嵌入式系统电子课件-4.3 嵌入式C程序架构.pptx
嵌入式C程序架构
软件架构屏幕操作键盘操作内存操入式C编程综述05性能优化★★★★
软件架构模块划分1任务模式中断服务程序硬件驱动C的面向对象化
模块划分的“划”是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分,合作完成系统的需求。软件架构C语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能。
模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明;模块划分的方法某模块提供给其它模块调用的外部函数及数据需在.h文件中冠以extern关键字声明;仅在模块内部使用的函数和全局变量需在.c文件开头冠以static关键字声明;永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作。
一个不好的例子/*module1.h*/inta=5;/*在模块1的.h文件中定义inta*//*module1.c*/#includemodule1.h/*在模块1中包含模块1的.h文件*//*module2.c*/#includemodule1.h/*在模块2中包含模块1的.h文件*//*module3.c*/#includemodule1.h/*在模块3中包含模块1的.h文件*/结果。。。在多个模块中共享变量
一个好的例子/*module1.h*/externinta;/*在模块1的.h文件中声明inta*//*module1.c*/inta=5;/*在模块1的.c文件中定义inta*//*module2.c*/#includemodule1.h/*在模块2中包含模块1的.h文件*//*module3.c*/#includemodule1.h/*在模块3中包含模块1的.h文件*/
一个嵌入式系统通常包括两类模块:硬件驱动模块,一种特定硬件对应一个模块;软件功能模块,其模块的划分应满足低耦合、高内聚的要求。两种类型模块
单任务、多任务单任务:微观串行、宏观串行多任务:微观串行、宏观并行任务模式
从CPU复位时的指定地址开始执行单任务程序典型架构跳转至汇编代码startup处执行;跳转至用户主程序main执行,在main中完成:初始化部分硬件设备;初始化各软件模块;进入死循环(无限循环),调用各模块的处理函数
无限循环的两种方案while(1)
{
}01好:一目了然for(;;)
{
}02不好:含义不明确
中断是嵌入式系统中重要的组成部分,但是在标准C中不包含中断。许多编译开发商在标准C上增加了对中断的支持,提供新的关键字用于标识中断服务程序(ISR),类似于__interrupt中断服务程序当一个函数被定义为ISR的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码。
中断服务程序需要满足如下要求:不能返回值;不能向ISR传递参数;ISR应该尽可能的短小精悍;printf(char*lpFormatString,…)函数会带来性能问题,不能在ISR中采用。中断服务程序的特点
在项目的开发中,设计一个队列,在中断服务程序中,只是将中断类型添加入该队列中,在主程序的无限循环中不断扫描中断队列是否有中断,有则取出队列中的第一个中断类型,进行相应处理。中断服务程序模型
中断服务程序模型typedefstructtagIntQueue /*存放中断的队列*/{ intintType; /*中断类型*/ structtagIntQueue*next;}IntQueue;IntQueue*lpIntQueueHead;__interruptISRexample(){ intintType; intType=GetSystemType(); /*得到中断类型*/ QueueAddTail(lpIntQueueHead,intType); /*在队列尾加入新的中断*/}
主程序模型While(1){ if(!IsIntQueueEmpty())
{ intType=GetFirstInt();
switch(intType) { casexxx: /*中断处理部分代码*/
…
break; casexxx:
…
break;
… } }}
一个硬件驱动模块通常应包括如下函数:中断服务程序ISR硬件初始化 修改寄存器,设置硬件参数(如UART应设置其波特率,AD/DA设备应设置其采样速率等); 将中断服务程序入口地址写入中断向量表;硬件驱动模块
一个硬件驱动模块通常