在其他论坛上的一次问答,现摘录为贴。
/***************************************************************************/
问:
我们目前已知道:
1) 如何创建一个任务(暂且叫他任务吧, 它的形式上只是一个被消息触发来调用的函数):
如 msg_send(hello_world,0,NULL,1000,0,MSG_OPT_REPEAT); // hello_world函数 被1秒周期触发调用
-------------------------------------------------------------------------------------------------------------------------------------------
再深入一点儿(PS: 这段时间我还没仔细认真的去看源码)
这样说吧: 来举一个非常简单的例子
假设有两个任务: A.按键任务, B.打印输出(显示)任务
当按键K1按下时, 通过消息触发, 让打印输出 " K1 press!"
当按键K2按下时, 通过消息触发, 让打印输出 " K2 press!"
如何通这个系统架构来实现, 基于消息来触发, 即打印任务没有被消息触发时,处于等待状态的;
当消息来了, 立即输出相应信息。
即: 1) 如何等待消息, 2) 如何发出消息。
/***************************************************************************/
答:
这个问题好!
设有以下几个函数已知
int key_read(void);//单纯的读取键按键值,包括了消抖等处理
void printout(char *str);//显示函数,可能是串口打印也可能是屏幕显示,总之是显示一个字串
void init(void);//相关的所有初始化
如果是前后台框架会这么写
void main(void)
{
int key;
init();
while(1)//系统主循环
{
key=key_read();
if(key==K1)
{
printout("K1 press!");
}
else if(key==K2)
{
printout("K2 press!");
}
....
}
}
原理很简单,在死循环中不断检查按键值,按键值有效则直接调用输出函数。如果系统就这么简单用这种方式也还好,但如果再有其他功能,也是类似于这样在这同一个主循环中需要不断检查,一旦其中一个任务在执行时耗时较长都将影响整个系统的实时处理。
其他rtos处理方式
为了提高按键驱动效率,可以在软硬件定时器中对按键进行检查,按键有效时发送一个消息邮箱或消息队列,
专门有一个线程来等待接收这个消息,平时因没有消息而阻塞,
void key_irq(void)//设按键在定时中断中执行
{
int key;
key=key_read();//读取按键值
if(key)//按键值有效
{
msg_send(key);//发送消息,同事携带按键值
}
}
void task_key(void)//按键消息处理线程
{
int key;
while(1)//每个线程都是个死循环,
{
msg_wait(&key);//等待按键消息到来,无消息时线程会被阻塞在这个位置,儿释放CPU
if(key==K1)
{
printout("K1 press!");
}
else if(key==K2)
{
printout("K2 press!");
}
}
}
这样做运行效率和实时性都得到了提升
MsgOS处理方式
如果用MsgOS整体思路和其他rots接近,但不用为按键处理单独建立一个线程,编写好按键处理函数等待系统调用即可。
void key_irq(void)//设按键在定时中断中执行
{
int key;
key=key_read();//读取按键值
if(key)//按键值有效
{
msg_send(key_process,key,NULL,0,0,0);//发送消息,同事携带按键值
}
}
void key_process(uint32 key,void *ptr)//按键处理消息回调函数,不能是死循环
{
if(key==K1)
{
printout("K1 press!");
}
else if(key==K2)
{
printout("K2 press!");
}
}
代码写起来更简单高效,因为不用建立按键处理线程,会节省不少的ram空间,时间耗费及实时性和其他rtos基本一致。
|