什么样是好的系统呢?笔者认为有2点,1是让微处理器在单位时间内处理更多的任务,2是程序易于维护。 在早期的程序设计中,就是一个简单的while(1),然后一直执行应用代码,这就是裸机系统。后来由于裸机系统的功能越来越复杂,代码的可维护性变得越来越差,任务的调度也变得不理想,于是人们就发明了操作系统。基于操作系统的程序设计相对比较简单,但其资源开销较大,CPU利用率较低。下面将分别介绍裸机系统于操作系统之间的区别:
操作系统:
操作系统的最明显的特征就是每个任务都有自己独立的堆栈空间,堆栈空间里保持着任务被挂起时的上下文环境,这样操作系统内核就能根据优先级调用最高优先级的任务了。
裸机系统:
裸机系统最明显的特征就是所有任务共享一个堆栈空间,任务之间不好进行同步,任务之间像是被杂糅在一起,随着功能的增加,其程序设计越加复杂且易造成系统的不稳定,但对于小型应用来说,裸机系统是比较好的选择,其执行效率高且不易出错。下面是笔者整理的常用裸机调度框架代码:
//常用宏定义
#define TRUE (1)
#define FALSE (0)
//定义TASK的数量
#define TASK_NUM (3)
//定义一个tick周期,定时器计数值累加多少
#define TICK_CNT (1000)
//定义定时器最大的计数值
#define MAX_TIMER_CNT (0xFFFFFFFF)
//用于计算tick时间
uint32_t startScheduleTime = 0;
uint32_t endScheduleTime = 0;
//用于task任务调度的索引
volatile int appTaskScheduleIndex = 0;
//Task 任务函数定义
void Task0(void)
{
//Task 0 任务处理
}
void Task1(void)
{
//Task 1 任务处理
}
void Task2(void)
{
//Task 2 任务处理
}
void Task3(void)
{
//Task 3 任务处理
}
//空闲任务,用于提高cpu利用率
void TaskIdle(void)
{
//空闲任务处理
}
//需要更据参考芯片手册,读取定时器的计数值
void GetSchduleTimerValue(uint32_t *value)
{
//TODO:得到调度定时器的值
}
//等待一个Tick的时间是否到期
int WaitScheduleTimerTick(uint32_t start,uint32_t end)
{
if(end >= start)
{
if((end - start) >= TICK_CNT)
{
return 1;
}
else
{
return 0;
}
}
else
{
if((MAX_TIMER_CNT - start + end) >= TICK_CNT)
{
return 1;
}
else
{
return 0;
}
}
}
void main(void)
{
TimerInit();//初始化定时器使其产生1ms中断
While(1)
{
GetSchduleTimerValue(&startScheduleTime);
switch(appTaskScheduleIndex)
{
case 0:
Task0();
break;
case 1:
Task1();
break;
case 2:
Task2();
break;
//添加其它任务处理case
//..
//..
default:
appTaskScheduleIndex = 0;
;
}
//等待中断的发生,驱动任务的调度
GetSchduleTimerValue(&endScheduleTime);
while(WaitScheduleTimerTick(startScheduleTime,endScheduleTime) == 0)
{
TaskIdle();
GetSchduleTimerValue(&endScheduleTime);
}
//任务索引的溢出处理
if(appTaskScheduleIndex >= TASK_NUM)
{
appTaskScheduleIndex = 0;
}
else
{
appTaskScheduleIndex++;
}
}
}