嵌入式开发交流网论坛

标题: 自制消息响应处理 [打印本页]

作者: 崩死菊花虫    时间: 2018-11-29 20:42
标题: 自制消息响应处理
[attach]18801[/attach]

昨天讲了UCOS的任务控制,每个任务都是可能嵌套运行,那它们的变量只能在临界区才能互传,今天要讲下自己写的一种消息响应处理模式的操作系统,喜欢它的原因是不管是使用上或查看修改上都非常简单。
  大家先一起看看程序



  void main(void)
{
/*......*/

MsgECB.handler = msg_handle;

/*......*/

}
/*消息处理程序*/

void msg_handle(MessageId id,Message msg)

{
switch(id)

{
case keyup:

keyup_handler(msg);

break;

case keydown:

keydown_handler(msg);
break;

case openeven:

  OpenEvenStruct *structopen=(OpenEvenStruct *)msg;
openeven_handler(structopen);
break;

case changememmory:

uchar changedata = (uchar *)msg;

savedata(changedata);
break;

default:break;

}

}



void ButtonTask()/*按键任务*/

{
for(;;)

{
if(upkeyIO==1)

{
/* ......消抖程序略 */

sendMessage(keyup,0);  /*发送消息*/
}

OSDelayTick(50); /* 每20ms扫描一次键盘 */
}

}



看起来简单易懂,别人在维护你的代码时看着也非常舒服,因为每个任务都是独立的,每个消息事件处理也都是独立的,修改其功能能保证不会影响其它事件或任务的运行。

下面开始讲解框架



创建 os_msg.c os_msg.h 在os_msg.h中添加结构体


typedef const void *Message;
typedef INT8U MessageId;
typedef struct messageData

{
        MessageId id;                        /* 消息ID                                 */
        Message *msg;                /* 消息内容      */
        INT16U delay;/* 发送消息延迟时间*/
}MessageData;


typedef struct os_mcb
{
        INT8U         msgRdyTbl;        /* 消息就绪列表 最高支持8个消息                        */
        INT16U         msgHoldTbl;        /* 消息等待列表 最高支持16个等待                        */
        void (*handler)(MessageId, Message) REENTRANT;       
}OS_MECB;


MSGEXT OS_MECB   MsgECB; /* 消息事件控制块 */


MSGEXT MessageData                msgRdyData[8];        /* 就绪消息内容                */
MSGEXT MessageData                msgHoldData[16];        /* 等待消息内容                */


我建了两个列表,一个是就绪列表,按先送先处理原则,最高支持8个消息等待处理(如果8个还会丢失消息,那可能你得换个更高的时钟晶振,或是直接换芯片吧。)。另一个是等待列表,在任务运行时如果你希望你要发送的消息过个几秒钟后再去处理比较好,那它就会进入等待列表,等待列表这里只设置了16个,觉得不够用可以自行进行扩大,自已扩大的话,在状态修改代码中也需要进行相应的修改。

[attach]18802[/attach]

[attach]18803[/attach]

消息发送,修改对应的消息列表


接着新建个任务 作为消息处理任务,该任务优先级为最低,退空闲任务高一级就可以了。因为数据处理一般是占用CPU时间最长的,这样可以在其它任务都空闲下来时进行数据处理,其它任务需要时就中断数据处理,保证其他任务的实时性。
[attach]18804[/attach]

[attach]18805[/attach]

[attach]18806[/attach]

任务中分两部分,一部分是等待消息计时,到时时加入就绪消息列队。另一个是消息列队消息处理。并保证每个滴答中运行一次。



然后呢? 就好了! 就是这么简单的东西,添加后 代码量增加1K 占用xram 200左右。

这一想法其实是先前阅读过 CSR蓝牙的官方demo 得来的,它的底层被封装了,能看到的就是一个非常大的消息处理函数,用来处理蓝牙的所有动作,优点是消息独立,缺点也是消息独立,不能像ucos的邮箱一样进行任务间的通讯。

明天讲下ucos的邮箱系统。就这么定了




欢迎光临 嵌入式开发交流网论坛 (http://www.dianzixuexi.com/bbs/) Powered by Discuz! X3.2