嵌入式软件底层开发的框架陈述

在底层代码编写中,初始的框架设计总会面临选择,针对实际的硬件使用环境,大家对于使用的软件框架有很多选择,今天我简单描述一些比较常用的架构,让大家能够理解并选择合适的架构。
总述
1. 简单的顺序执行程序:这类写法是大多数人使用的方法,不需用思考程序的具体架构,直接按照执行顺序编写应用程序即可。
2.前后台执行程序:在顺序执行的情况上增添中断前台处理机制,配置顺序执行的后台大循环程序,组合成可以实时响应的程序。
3. 时间片轮循法:在前后台的执行架构上,通过计数器进一步规划程序,定时执行特定的片段。
4. 实时操作系统:实时操作系统又叫rtos,实时性,rtos的内核负责管理所有的任务,内核决定了运行哪个任务,何时停止当前任务切换到其 他任务,这个是内核的多任务管理能力。多任务 管理给人的感觉就好像芯片有多个cpu,多任务管理实现了cpu资源的最大化利用,多任务管理有助于实现程序的模块化开发,能够实现复杂的实时应用。
除了实时性,还有可剥夺内核,顾名思义就是可以剥夺其他任务的cpu使用权,它总是运行就绪任务中的优先级最高的那个任务。
1.简单的顺序执行程序
这种应用程序比较简单,一般作为初阶简单使用,实时性以及要求不太高的情况下,可以使用。程序的设计比较简单,思路比较清晰。但是主循环的逻辑比较复杂的时候,如果没有完整的流程图指导,其他人很难看懂程序运行逻辑。
下面写一个顺序执行的程序模型
int main(void) { uint8 taskvalue; initsys(); // 初始化 while (1) { taskvalue= gettaskvalue(); switch (taskvalue) { case x: taskdispstatus(); break; 。。. default: break; } } }
2.前后台执行程序
这种程序特点是,后台大循环中一直执行默认的程序,中断服务程序(isr)产生相应中断标记,主程序运行与中断标记相关联的任务程序。一般实现有如下思路:
通过设置标志变量,然后在前台响应中断的时候进行对标志变量的置位或者复位,实现事件的信号获取,再在后台主循环进行中断所对应事物或者数据的处理,将程序流程转移到主程序。
前后台执行的程序
void irqhandler(void){ if(getitstatus == 1) { sysflag = 1; getitstatus = 0; }}int main(void) { uint8 taskvalue; initsys(); // 初始化 while (1) { taskvalue= gettaskvalue(); switch (taskvalue) { case x: if(sysflag == 1) { taskdispstatus(); sysflag == 0; } break; 。。. default: break; } } }
3.时间片轮循架构
时间片轮循法,大家看到它的时候,一般会将它与操作系统进行比较。不是说操作系统包含这种方法,而是在前后台程序中配合时间管理形成时间片轮循架构。
这种架构已经最大限度接近rtos,时间管理,中断管理,任务管理,已经都有了,只不过rtos会对内核进行更深入的修改,有针对delay延时的线程切换,抢占式任务切换这些更为复杂一些的功能等。
时间片轮循程序
时间片管理主要是通过对定时多处复用,在定时器计数,定时进行标志位的变化,继而主程序对标志真假的判断,实现不同时间不同任务状态执行。
因为此架构代码比较好,我适当进行详细描述。
step
1:初始化相应的定时器:注意设置定时器的间隔频率,可以按照芯片的性能设置。例如,设置定时中断为1ms,也可以设置为10ms,轮循架构中的定时器部分与操作系统的定时器部分具有一样的功能,中断过于频繁,影响主程的序执行效率;中断间隔过长,实时响应效果差。
2:针对定时器运行的任务设置一个函数结构体标志,用来在定时程序进行时间计数以及标志操作。
#define tasktab_num 6 //任务数量__packed typedef struct{ u8 flag; //定时标志 u32 numcount;//按照定时中断进行计数 u32 target; //设置的定时目标数值 int(*fun)(void);//设置定时执行的目标任务函数}tasktimtypedef
step
3:建立一个任务表,通过结构体表的设置,确定任务执行的时间表。
在定义变量时,我们已经初始化了值,这些值的初始化,非常重要,跟具体的执行时间优先级等都有关系,这个需要自己掌握。
/*mdmsendtimtab任务函数默认周期,单位5ms,tim7*/static tasktimtypedef tasktimtab[tasktab_num] ={ {1, 0, 30000, *task00}, //task00 3000数值是设置的定时目标值,如果觉得反应过慢,可以将此值设置小 {1, 0, 3000, *task01}, //task01 {1, 0, 300, *task02}, //task02 {1, 0, 30, *task03}, //task03 {1, 0, 3, *task04}, //task04 {1, 0, 0xffffffff, *task05}, //task05 //可以按照tasktab_num数量添加任务};int task00(void)//按照结构体的函数模板(int(*fun)(void);)写任务函数{。。.}//假设执行按键操作int task01(void){。。.}//假设执行usart发送任务int task02(void){。。.}//假设执行can通讯int task03(void){。。.}//假设执行继电器控制int task04(void){。。.}//假设执行网络解析int task06(void){。。.}//假设执行空
step
4:定时中断服务函数,按照我们需要的时间以及标志操作进行计时。
//定时中断服务函数 void timerinterrupt(void) { for(char i=0; i《tasktab_num; i++) { if(tasktimtab[i].flag == 1) { (tasktimtab[i].numcount《 tasktimtab[i].target)//比较目前定时计数与目标时间 ?(tasktimtab[i].numcount++):(tasktimtab[i].flag = 0); } } }
step
5:主函数进行任务函数执行。
int main(void) { initsys(); // 初始化 while (1) { for(char i=0; i《tasktab_num; i++)//// 任务处理 { if(tasktimtab[i].flag == 0) { if(tasktimtab.flag == 0) { tasktimtab[i].flag = 1; tasktimtab[i].numcount= 0; tasktimtab[i].fun(); } } } }
4.操作系统rtos
嵌入式操作系统是更加优化的执行框架,针对多任务,功能复杂,扩展性要求强项目的代码有非常好的使用。rtos是针对不同处理器优化设计的高效率实时多任务内核,rtos可以面对几十个系列的嵌入式处理器mpu、mcu、dsp、soc等提供类同的api接口,这是rtos基于设备独立的应用程序开发基础。因此,基于rtos的c语言程序具有极大的可移植性。目前针对微嵌入式或者单片机的操作系统有vxworks、ucos、free rtos、国产的rtt,这些操作系统大同小异,基本的功能都类似:任务管理、任务间同步和通信、内存管理、实时时钟服务、中断管理服务。
(图片来源博客)
rtos在时间轮循的架构上继续增加了任务挂起以及恢复,阻塞切换线程等,属于功能累加,进一步的优化。由于本次不是对rtos的讲解,本人学习应用有ucos、rtt、free rtos几个操作系统,因为篇幅有限,时间有限,我抽时间再进行详细的rtos系统架构学习等的介绍。
目前rtos系统有很多,很多项目都倾向于使用rtos,但是通过几种架构的分析明白不同的项目需要不同的架构,并不是所有项目都需要,也都适合使用rtos,例如项目中各个任务耦合性过大,如果用rtos需要很多的任务同步,甚至都无法进行线程的规划。这样就完全失去rtos意义,此时用某些裸机的架构反而更合适。


焊接问题还是SI问题,如何去判断
红米K20系列价格公布 售价1999元起
汽车安全与防御系统的设计
板式热交换器的作用_板式热交换器的优缺点
特斯拉Autopilot2.0:已走向“第五级”的水平
嵌入式软件底层开发的框架陈述
移相键控(PSK)实验
三星s8最新消息:三星s8摆脱note7阴影?三星表示s8/s8+电池绝对安全?
ESD如何去静电,ESD保护器件使用有哪些注意事项
Google实验部门Area 120有一个名为Tables的新项目
按下不同按键,发出不同频率声音应用设计
苹果iOS5或将支持语音输入
东航江苏公司引进了第6架B306E飞机
中国联通与IBM签署联合创新项目合作协议
液晶监视器故障原因分析及问题解决
无线充电器品牌排行,无线充电器品牌对比
LED背光技术可能会成为行业的改变者
极海APM32F103RCT7通过AEC-Q100车规认证
全球移动内存营收排名 三星半导体稳居龙头
傻瓜175功放电路图