许多程序员被裸机上实现实时多任务所困扰,以前我的程序是这样……自从用了这种框架,现在成了这样式……
这年头还有用裸机实现多任务的设计?如果你像我一样不幸,作为过来人,给你提供一种思路,实现尽量的实时性。
裸机上编程,有个麻烦就是大任务无法打断,一旦执行,如果不在函数中穿插判断退出的情况,就必须等他执行完才能干别的,啥时实性啊,全耽误了。
当然,最实时的办法就是利用中断,但中断也不是随心所欲地用,中断程序不能写得太大,负责要么中断嵌套会溢出,要么丢掉一些中断,所以大任务还是要放到主循环里做……
下面的伪代码是裸机实现带优先级的多任务程序架构,自己阅读,理解理解,如果发现不妥之处请不吝赐教。
#define PRIOR1 20 //ms优先级1每过这个时间执行一次
#define PRIOR2 40
#define PRIOR3 80
#define PRIOR_CRUCIAL 10
#define IDLE_PRIOR 20
int pr1_last_time=0;
int pr2_last_time=0;
int pr3_last_time=0;
int send_last_time=0;
int whole_last_time=0;
void priority_init()
{
timer1.reset();
pr1_last_time=0;
pr2_last_time=0;
pr3_last_time=0;
crucial_last_time=0;
whole_last_time=0;
timer1.start();
}
void func1()
{
static int last_DSP_require;
bool crucial_handled=crucial_handle();//处理紧急事件
if(crucial_require && timer1.read()-crucial_last_time<PRIOR_CRUCIAL)
//距上次处理完还不到10ms就又要处理,说明现在情况紧急
{
maskable=true;//长时间的工作别干了
}
else
maskable=false;
if(crucial_handled) //
{
crucial_last_time=timer1.read(); //记录本次时间
}
}
void big_loop()
{
int jitters;
priority_init();
while(1)
{
if(func1_condition)
{
func1(); //最重要的任务,每次都要执行
}
jitters=timer1.read();
if(jitters-pr1_last_time>PRIOR1) //距离上次执行时间已经过去容忍限
{
if(func2_condition)
{
func2(); //次级任务,必须执行,但不用最频繁
}
pr1_last_time=timer1.read(); //记录上次执行时间
}
jitters=timer1.read();
if(jitters-pr2_last_time>PRIOR2) //距离上次执行时间已经过去容忍限
{
if(func3_condition)
{
func3(); //三级任务,可以不执行,但用时较短
}
pr2_last_time=timer1.read(); //记录上次执行时间
}
jitters=timer1.read();
if(jitters-pr3_last_time>PRIOR3 && !maskable) //距离上次执行时间已经过去容忍限
{
if(func4_condition)
{
func4(); //四级任务,可以不执行,用时较长
}
pr3_last_time=timer1.read(); //记录上次执行时间
}
jitters=timer1.read();
if(jitters-whole_last_time<IDLE_PRIOR && !maskable) //实在闲得没事干
{
if(func5_condition)
{
func5(); //无实时要求的任务,可以不执行,用时较长
}
if(time_is_fitting)
//合适的时候初始化一下时间,避免长时间运行导致溢出
{
priority_init();
}
}
if(ESC)
break;
whole_last_time=timer1.read(); //记录本轮起始时间
}
}