以前在开发项目中,看到很多操作系统,都有自己的调度器,写起代码来比裸机方便多了,但别人的操作系统又比较大型,占用资源比较多,而且也比较复杂。
所以我自己也就写了一个小型的调度器,没有像操作uCos那样,进行任务的进出栈。我利用系统的定时器10ms唤醒一次,进行调度工作,如果精度要求不高,可以变成100ms唤醒1次,这样就会大大的降低了MCU功耗。
其实我写的这个调度器还是挺简单的,分享出代码给大家看看,已经在一个工控产品上进行了应用!
struct ke_timer usr_timer[USR_TIMER_MAX] = {{0,0}}; static unsigned char gTimerTickFlg = 0; static unsigned short gUsrUsingTimerCount = 0; /* 启动一个timer timer_id: timer_id 里面注册 delay:多久后运行当前Task,如果系统timer设置为10ms,那么delay=100,就是1S后运行 例子: ke_timer_set(USR_TIMER0,100); */ void ke_timer_set(unsigned short const timer_id, unsigned short const delay) { usr_timer[timer_id].flag = 1; usr_timer[timer_id].time = delay; } /* 关闭一个timer timer_id: timer_id 里面注册 例子: ke_timer_clear(USR_TIMER0); */ void ke_timer_clear(unsigned short const timer_id) { usr_timer[timer_id].flag = 0; } /* 内核进行timer的调度工作,这个函数需要在main函数里面的while循环调度*/ void ke_schedule(void) { unsigned short timer_id = 0,fun_id = 0; if(gTimerTickFlg) { gTimerTickFlg = 0; for(timer_id=0;timer_id<gUsrUsingTimerCount;timer_id++) { if(usr_timer[timer_id].flag) { if(usr_timer[timer_id].time > 0) usr_timer[timer_id].time--; } } } for(timer_id=0;timer_id<gUsrUsingTimerCount;timer_id++) { if(usr_timer[timer_id].flag) { if(usr_timer[timer_id].time == 0) { usr_timer[timer_id].flag = 0; for(fun_id=0;fun_id<gUsrUsingTimerCount;fun_id++) { if(usr_timer_state[fun_id].id == timer_id) { usr_timer_state[fun_id].func(timer_id); } } } } } } /* MCU timer如果注册为10ms,那么每次也调度一下这个函数 */ void timer_tick_set(void) { gTimerTickFlg = 1; } /* timer 初始化*/ void ke_timer_init(void) { gUsrUsingTimerCount = get_usr_using_timer_count(); }下面是任务注册的地方 /* 注册任务函数 */ void usr_test_timer(unsigned short const msgid) { QPRINTF("usr timer0\r\n"); } /* 注册 timer 对应的任务 */ const ke_msg_handler usr_timer_state[] = { {USR_TIMER0, (ke_msg_func_t) usr_test_timer}, }; /* 获取 系统有多少个任务,用来分配空间 */ unsigned short get_usr_using_timer_count(void) { return (unsigned short)(sizeof(usr_timer_state) / sizeof(ke_msg_handler)); } 其他更详细的代码在附件里面,其实上面的代码也很简单,大家看一下,有什么好的建议可以一起分享一下!!