根据任务调度的方式不同分为两类 :
1)由程序自己完成任务调度
运行效率高,对硬件中断响应快;
程序运行稳定,适合于任务较为单一。
实时性较强的应用
2)由嵌入式操作系统完成任务调度
利用处理器同时完成多个任务;
简化了应用系统软件设计;
良好的多任务设计有助于提高系统的稳定性和可靠性 、
自我调度程序组成:
1)中断程序部分
通过设置判断标志来影响主循环部分的运行
2)初始化部分
DSP软、硬件的初始化设置
启动系统硬件
使能DSP中断
启动DMA传送等
3)主循环部分
数据输入、处理和输出等
中断程序1
……
中断程序m;
Main( )
{
DSP_INT( ){……}; //DSP初始化
for(;;) //主循环
{
if(条件1) //判断条件1
{
处理模块1; //条件满足运行处理模块1
};
……
if(条件n) //判断条件n
{
处理模块n; //条件满足运行处理模块n
};
}
}
2、应用嵌入式操作系统
硬实时方式:
按照固定时钟节拍切换任务;
不仅要执行无误,而且要准时 。
软实时方式:
由软件来进行任务的切换;
使各个任务尽快运行,而不要求限定某个任务在多长时间内完成。
嵌入式操作系统的核心是操作系统内核:
优先级的内核可以分成两种类型:
1)不可剥夺型内核—合作型多任务
要求每个任务主动放弃CPU使用权 ;
每个任务相互合作,共享一个CPU ;
异步事件由中断服务来处理;
允许任务使用不可重入函数;
优点是响应中断快 。
2)可剥夺型内核
具有最高优先级的任务就绪,得到CPU的使用权;
不应直接使用不可重入函数;
主要工作是完成任务(进程)的调度。
任务状态转换 :
信号量:
两种类型:
二进制型—看做一个只有一位的计数器型信号量
计数器型
两个任务之间利用信号量来取得同步
单向同步:
任务用一个信号量触发另一个任务 :
双向同步:
C语言程序开发及优化 :
对I/O空间进行寻址:
关键字ioport;
ioport类型只能用来声明全局或静态变量;
在本地变量中使用ioport类型,则变量必须用指针声明。
指针声明ioport类型举例:
void foo (void)
{
ioport int i; /* 无效的声明 */
ioport int *j; /* 有效声明 */
}
注意:声明ioport类型的指针只有16位。
在printf()中引用ioport指针的举例:
ioport int *p;
printf(”%p\n”, (void*)p);
注意:则必须进行强制类型转换“void *”
在本地变量中使用ioport类型的举例:
int * ioport ioport_pointer; /* ioport 指针 */
int i;
int j;
void foo (void)
{
ioport_pointer = &i;
j = *ioport_pointer;
}
指向I/O空间数据指针的举例:
/* 指向ioport数据: */
ioport int * ptr_to_ioport;
ioport int i;
void foo (void)
{
int j;
i = 10;
ptr_to_ioport = &i;
j = *ptr_to_ioport;
}
编译结果:
_foo:
MOV #_i,*abs16(#_ptr_to_ioport) ; 存储_i的地址
MOV *abs16(#_ptr_to_ioport),AR3
AADD #–1, SP
MOV #10,port(#_i) ; 向_i中存入10
MOV *AR3,AR1
MOV AR1,*SP(#0)
AADD #1,SP
return
利用ioport指针指向I/O空间的数据的举例:
/* 指向ioport数据的ioport指针: */
ioport int * ioport iop_ptr_to_ioport;
ioport int i;
ioport int j;
void foo (void)
{
i = 10;
iop_ptr_to_ioport = &i;
j = *iop_ptr_to_ioport;
}
编译结果如下:
_foo:
MOV #10,port(#_i) ; 将10存在_i中
MOV #_i,port(#_iop_ptr_to_ioport) ; 存储_i的地址
MOV port(#_iop_ptr_to_ioport),AR3 ; 载入_i的地址
MOV *AR3, AR1 ; 载入_i
MOV AR1,port(#_j) ; 将10存到_j中
return
interrupt关键字 :
定义中断函数
中断函数必须返回空并且没有参数传递
中断函数可以定义本地变量并且使用堆栈
定义中断函数举例:
interrupt void int_handler()
{
unsigned int flags;
...
}
onchip关键字:
告诉编译器由该关键字定义的指针所指向的数据可以作为一个双乘法指令中的操作数
用onchip定义数组和指针的举例:
onchip int x[100]; /* array declaration */
onchip int *p; /* pointer declaration */
C语言的优化:
作用是对循环进行化简,重新组织表达式和声明,将变量直接分配到寄存器中;
提高程序运行效率,缩小程序编码数量。
3、C语言与汇编语言的混合编程
在C语言中直接嵌套汇编语句:
需在嵌入的汇编语句前面加上asm标识符,左右加上一个双引号和一个小括号。
通用目标文件格式 :
汇编器和链接器产生的可执行文件所采用的格式;
段—编译器产生的可以重新定位的代码和数据块。
初始化段:
代码段(.text段)
常数段(.const段)
未初始化段 :
堆栈和系统堆栈段(.stack和.sysstack)
存储全局和静态变量的.bss段
为分配动态存储器保留的.sysmem段