超简单的线程切换

背景

接手一个IoT工程,使用STM8L + NBIOT模块实现远程数传。源代码大体上已经构建完成,但是既没有使用ISR + Mainloop + FSM的设计方式,又没有使用RTOS做任务调度。所以如果花时间重新撸代码,时间和精力都不允许。实际上,我已经投入了大量时间来翻代码(填坑),增加了ISR,systicker,FSM,以及数据收发结构体......但是依然存在很多问题。

延时问题

阻塞型的代码设计,很多事情无法同时完成。尤其是阻塞型delay/wait会造成很多麻烦,比如Modem在通讯时需要较长时间等待和重试,而此时keyboard判断和处理几乎无法实现,而我并不希望在定时中断嵌入键盘处理。因为定时中断应该只提供ticker,而不应该和应用相关。

RTOS Thread.yield的做法是,在Modem等慢速设备通讯任务中,遇到延时,将控制权交还给RTOS,并调度到其他任务中。于是我参考了这一做法,利用回调函数和systicker来实现任务切换。

// setup callback functions of void cb(void)
void set_delay_cb(void (*cb)()){
  callback = cb;
}

void yield_ms(uint8_t t)
{
  assert_param(t<=250);
  u32 period = t;
  u32 start = systicker;
  while((systicker - start)

time.c

void hw_update(void){
  LED_update();
  key_update();
  MTR_update();
  PM_update();
}

void main {
  set_delay_cb(hw_update);  // set callback as background task
  yield(10);  // delay 10 seconds, which perform callback functions.
}

main.c

结构简单非常简单。但是放在hw_update()后台的函数与前台函数不能够有资源竞争,后台函数最好不要有while循环,也不要递归调用yield。

你可能感兴趣的:(超简单的线程切换)