嵌入式实时操作系统在DATU中的应用
发布时间:2009/2/18 0:00:00 访问次数:1304
配电自动化远方终端(datu)是配电自动化系统(das)的基础设备,是配电变压器远方终端(ttu)、馈线远方终端(ftu)和中压监控单元等几种设备的统称。这几种设备除少数高端功能不同以外,其余功能均大致相似,主要包括数据采集与处理、监控、保护和远方通信等功能。datu是一种实时性很强的嵌入式系统,正常情况下它负责采集相应设备的运行情况,如电压、电流的数值以及开关的分合状态等,并将上述信息通过通信网络传向远方的配电自动化主站,同时还可以根据主站下发的命令进行远方操作[1]。在配电网发生故障时,datu还要完成故障检测、记录故障参数和微机保护等功能。
在传统的嵌入式系统中,应用程序一般是由一个主程序和几个中断服务子程序(isr)组成。主程序一般是一个无限的循环,在循环中调用相应的函数完成相应的数据处理,isr负责处理时间相关性很强的关键操作。因为isr提供的信息一直要等到主程序循环到负责处理这个信息的那段程序的时候才能得到处理,所以传统系统的实时性比较差,最坏情况下的实时响应时间可能是整个循环的执行时间[2]。如果采用嵌入式实时操作系统µc/os-ii,则可以大大缩短实时响应时间,接近理论上能达到的最好水平;此外,在嵌入式应用中使用µc/os-ii,通过将应用程序分解为多个任务,可以简化应用软件的设计;同时良好的多任务设计,有助于提高系统的稳定性与可靠性[2]。
1 µc/os-ii的移植
所谓移植就是使µc/os-ii能在某个cpu中运行。虽然大部分的µc/os-ii代码是用c语言写的,但仍需要开发者用汇编语言写一些与cpu相关的代码,这是因为µc/os-ii在访问cpu寄存器时只能通过汇编语言来实现。µc/os-ii与cpu相关的代码包含在三个文件中:os_cpu.h,os_cpu_c.c,os_cpu_a.asm。
1.1 移植的前提条件
我们的datu所采用的cpu是美国德州仪器公司(ti)生产的一种高性能16位定点dsp——tms320lf2407a(以下简称为f2407)。其定点运算速度最高可达每秒40兆条指令,片内除具有2.5k字的ram和32k字的flash存储器外,还有a/d、spi、can等多种外设资源[3]。
µc/os-ii能否移植至某种cpu中,这种cpu必须满足以下要求:该cpu的c编译器支持内嵌汇编语句;能由硬件产生定时中断;支持软件堆栈;有将堆栈指针(sp)和其它寄存器存储到内存中的指令[2]。通过查看f2407的手册可以得知它完全满足以上条件,所以将µc/os-ii移植到f2407中是完全可行的。
1.2 os_cpu.h
os_cpu.h包括一系列用#define定义的与处理器相关的数据类型、宏和常量,如关中断、开中断、任务切换和堆栈增长方式等。需要注意的是,由于intm不受加载状态寄存器指令lst的影响,也就是说,即便可以将st0保存至堆栈或内存中,也无法使用lst指令从堆栈或内存中恢复intm的值,故而只能使用直接关中断的方式(方式一)来保护临界区代码[2]。
1.3 os_cpu_c.c
os_cpu_c.c中包括一系列c语言函数:ostaskstkinit()和若干个hook函数。其中唯一必要的是ostaskstkinit(),其它几个函数可以不包含任何代码[2]。ostickisr()是时钟节拍中断的isr,因为code composor支持用c语言编写isr,而且也支持内嵌汇编语句,所以我们把用c语言编写的ostickisr()也放在os_cpu_c.c中。
1.3.1 ostaskstkinit()
ostaskstkinit()在创建任务时被ostaskcreate()或ostaskcreateext()调用来初始化任务的堆栈结构。图1显示了在f2407中需要放到任务堆栈中的寄存器及其顺序。
图1 任务的堆栈结构
ostaskstkinit()的代码如下,其四个参数中,task是任务的起始地址,pdata是传给任务的数据指针,ptos是最初的sp,opt没有用到。函数返回的是全部入栈操作完成后的新的sp。
os_stk *ostaskstkinit(void (*task),
void *pdata, os_stk *ptos, int16u opt)
{
*ptos++ = (os_stk)pdata;/*任务参数*/
*ptos++ = (os_stk)0;/*空闲 */
*ptos++ = (os_stk)0x27fc;/*st1*/
*ptos++ = (os_stk)0x2600;/*st0*/
*ptos++ = (os_stk)0;/*acch*/
*ptos++ = (os_stk)0;/*accl*/
*ptos++ = (os_stk)0;/*ph*/
*ptos++ = (os_stk)0;/*pl*/
*ptos++ = (os_stk)0;/*临时寄存器*/
*ptos++ = (os_stk)0;/*辅助寄存器0*/
……………/*辅助寄存器ar2-ar7*/
*ptos++ = (os_stk)task;/*硬件堆栈2*/
……………/*硬件堆栈3-8*/
return ptos;
}
1.3.2 ostickisr()
配电自动化远方终端(datu)是配电自动化系统(das)的基础设备,是配电变压器远方终端(ttu)、馈线远方终端(ftu)和中压监控单元等几种设备的统称。这几种设备除少数高端功能不同以外,其余功能均大致相似,主要包括数据采集与处理、监控、保护和远方通信等功能。datu是一种实时性很强的嵌入式系统,正常情况下它负责采集相应设备的运行情况,如电压、电流的数值以及开关的分合状态等,并将上述信息通过通信网络传向远方的配电自动化主站,同时还可以根据主站下发的命令进行远方操作[1]。在配电网发生故障时,datu还要完成故障检测、记录故障参数和微机保护等功能。
在传统的嵌入式系统中,应用程序一般是由一个主程序和几个中断服务子程序(isr)组成。主程序一般是一个无限的循环,在循环中调用相应的函数完成相应的数据处理,isr负责处理时间相关性很强的关键操作。因为isr提供的信息一直要等到主程序循环到负责处理这个信息的那段程序的时候才能得到处理,所以传统系统的实时性比较差,最坏情况下的实时响应时间可能是整个循环的执行时间[2]。如果采用嵌入式实时操作系统µc/os-ii,则可以大大缩短实时响应时间,接近理论上能达到的最好水平;此外,在嵌入式应用中使用µc/os-ii,通过将应用程序分解为多个任务,可以简化应用软件的设计;同时良好的多任务设计,有助于提高系统的稳定性与可靠性[2]。
1 µc/os-ii的移植
所谓移植就是使µc/os-ii能在某个cpu中运行。虽然大部分的µc/os-ii代码是用c语言写的,但仍需要开发者用汇编语言写一些与cpu相关的代码,这是因为µc/os-ii在访问cpu寄存器时只能通过汇编语言来实现。µc/os-ii与cpu相关的代码包含在三个文件中:os_cpu.h,os_cpu_c.c,os_cpu_a.asm。
1.1 移植的前提条件
我们的datu所采用的cpu是美国德州仪器公司(ti)生产的一种高性能16位定点dsp——tms320lf2407a(以下简称为f2407)。其定点运算速度最高可达每秒40兆条指令,片内除具有2.5k字的ram和32k字的flash存储器外,还有a/d、spi、can等多种外设资源[3]。
µc/os-ii能否移植至某种cpu中,这种cpu必须满足以下要求:该cpu的c编译器支持内嵌汇编语句;能由硬件产生定时中断;支持软件堆栈;有将堆栈指针(sp)和其它寄存器存储到内存中的指令[2]。通过查看f2407的手册可以得知它完全满足以上条件,所以将µc/os-ii移植到f2407中是完全可行的。
1.2 os_cpu.h
os_cpu.h包括一系列用#define定义的与处理器相关的数据类型、宏和常量,如关中断、开中断、任务切换和堆栈增长方式等。需要注意的是,由于intm不受加载状态寄存器指令lst的影响,也就是说,即便可以将st0保存至堆栈或内存中,也无法使用lst指令从堆栈或内存中恢复intm的值,故而只能使用直接关中断的方式(方式一)来保护临界区代码[2]。
1.3 os_cpu_c.c
os_cpu_c.c中包括一系列c语言函数:ostaskstkinit()和若干个hook函数。其中唯一必要的是ostaskstkinit(),其它几个函数可以不包含任何代码[2]。ostickisr()是时钟节拍中断的isr,因为code composor支持用c语言编写isr,而且也支持内嵌汇编语句,所以我们把用c语言编写的ostickisr()也放在os_cpu_c.c中。
1.3.1 ostaskstkinit()
ostaskstkinit()在创建任务时被ostaskcreate()或ostaskcreateext()调用来初始化任务的堆栈结构。图1显示了在f2407中需要放到任务堆栈中的寄存器及其顺序。
图1 任务的堆栈结构
ostaskstkinit()的代码如下,其四个参数中,task是任务的起始地址,pdata是传给任务的数据指针,ptos是最初的sp,opt没有用到。函数返回的是全部入栈操作完成后的新的sp。
os_stk *ostaskstkinit(void (*task),
void *pdata, os_stk *ptos, int16u opt)
{
*ptos++ = (os_stk)pdata;/*任务参数*/
*ptos++ = (os_stk)0;/*空闲 */
*ptos++ = (os_stk)0x27fc;/*st1*/
*ptos++ = (os_stk)0x2600;/*st0*/
*ptos++ = (os_stk)0;/*acch*/
*ptos++ = (os_stk)0;/*accl*/
*ptos++ = (os_stk)0;/*ph*/
*ptos++ = (os_stk)0;/*pl*/
*ptos++ = (os_stk)0;/*临时寄存器*/
*ptos++ = (os_stk)0;/*辅助寄存器0*/
……………/*辅助寄存器ar2-ar7*/
*ptos++ = (os_stk)task;/*硬件堆栈2*/
……………/*硬件堆栈3-8*/
return ptos;
}
1.3.2 ostickisr()
热门点击
- Linux设备驱动程序的函数跳转表
- PIE中断向量的映射方式
- Linux系统调用例程system_call
- PIE模块级中断
- 什么是Linux内核模块
- Linux系统调用接口、系统调用例程和内核服
- ARM复位原理
- Linux系统调用接口、系统调用例程和内核服
- Linux字符设备驱动程序的注册
- Linux外部设备的基本概念
推荐技术资料
- DFRobot—玩的就是
- 如果说新车间的特点是“灵动”,FQPF12N60C那么... [详细]