ARM底层如何实现Message(消息模式)
2014-05-26 17:02
148 查看
先定义消息ID
typedef enum
{
//system message
MSG_KEYSCAN_PROCESSED = (UINT32)0x00,
MSG_KEY_VOL_STATE,
....//中间好多Msg_ID
MSG_USB_CONNECTED,
MSG_USB_HOST_CONNECTED,
MSG_SDCARD_EJECT, //SD card insert status
MSG_SDCARD_UPDATE, //SD card poll out
//End
MSG_ID_MAX //max message number
}MSG_ID;
这个enum有300多个ID!很占空间!
最后的那一个MSG_ID_MAX是最重要的,因为enum中的数据是根据第一个数据(UINT32)0x00开始递增的,所以最后一个数据MSG_ID_MAX就是该enum包括的ID数量。利用这个值,可以设计一个数组,用来保存ID。这里比较巧妙的办法就是,不直接使用enum。而是使用一个数组取代。数组的设计是这样的:
所有的ID,按每32位为一组,刚好可以放满一个UINT32(unsigned long int)数据的各个位。这样,假设枚举类MSG_ID有330个ID,只需要(MSG_ID_MAX/32+1)个UINT32空间就可以存储,节省了大概32倍的内存空间。
UINT32 Msg[(MSG_ID_MAX / 32) + 1]; //定义全局数组(各个需要调用msg机制的c文件,都需要include 包含该数据的.h,该数组可以在Msg.h里声明)
SendMsg其实就是设置上面的Msg数组的某个位,先拿到MsgID,然后算出属于数组的哪个UINT32数据:Msg[MsgID/32]。 然后用“位或”的方式,把相应的位数置位,偏移量为MsgID除以32的余数,代码实现:Msg[MsgID/32] |= 1<<(MsgID%32)。
根据上面的介绍,参考代码如下:
BOOL GetMsg(MSG_ID MsgId)
{
// UINT16 imask_tmp;
if (Msg[MsgId / 32] & (1 << (MsgId % 32)))
{
// GLOBAL_INTERRUPT_DISABLE;
IntMasterDisable();
Msg[MsgId / 32] &= ~(1 << (MsgId % 32));
IntMasterEnable();
// GLOBAL_INTERRUPT_ENABLE;
return(TRUE);
}
return(FALSE);
}
void SendMsg(MSG_ID MsgId)
{
// UINT16 imask_tmp;
// GLOBAL_INTERRUPT_DISABLE;
IntMasterDisable();
Msg[MsgId / 32] |= 1 << (MsgId % 32);
IntMasterEnable();
// GLOBAL_INTERRUPT_ENABLE;
}
typedef enum
{
//system message
MSG_KEYSCAN_PROCESSED = (UINT32)0x00,
MSG_KEY_VOL_STATE,
....//中间好多Msg_ID
MSG_USB_CONNECTED,
MSG_USB_HOST_CONNECTED,
MSG_SDCARD_EJECT, //SD card insert status
MSG_SDCARD_UPDATE, //SD card poll out
//End
MSG_ID_MAX //max message number
}MSG_ID;
这个enum有300多个ID!很占空间!
最后的那一个MSG_ID_MAX是最重要的,因为enum中的数据是根据第一个数据(UINT32)0x00开始递增的,所以最后一个数据MSG_ID_MAX就是该enum包括的ID数量。利用这个值,可以设计一个数组,用来保存ID。这里比较巧妙的办法就是,不直接使用enum。而是使用一个数组取代。数组的设计是这样的:
所有的ID,按每32位为一组,刚好可以放满一个UINT32(unsigned long int)数据的各个位。这样,假设枚举类MSG_ID有330个ID,只需要(MSG_ID_MAX/32+1)个UINT32空间就可以存储,节省了大概32倍的内存空间。
UINT32 Msg[(MSG_ID_MAX / 32) + 1]; //定义全局数组(各个需要调用msg机制的c文件,都需要include 包含该数据的.h,该数组可以在Msg.h里声明)
SendMsg其实就是设置上面的Msg数组的某个位,先拿到MsgID,然后算出属于数组的哪个UINT32数据:Msg[MsgID/32]。 然后用“位或”的方式,把相应的位数置位,偏移量为MsgID除以32的余数,代码实现:Msg[MsgID/32] |= 1<<(MsgID%32)。
根据上面的介绍,参考代码如下:
BOOL GetMsg(MSG_ID MsgId)
{
// UINT16 imask_tmp;
if (Msg[MsgId / 32] & (1 << (MsgId % 32)))
{
// GLOBAL_INTERRUPT_DISABLE;
IntMasterDisable();
Msg[MsgId / 32] &= ~(1 << (MsgId % 32));
IntMasterEnable();
// GLOBAL_INTERRUPT_ENABLE;
return(TRUE);
}
return(FALSE);
}
void SendMsg(MSG_ID MsgId)
{
// UINT16 imask_tmp;
// GLOBAL_INTERRUPT_DISABLE;
IntMasterDisable();
Msg[MsgId / 32] |= 1 << (MsgId % 32);
IntMasterEnable();
// GLOBAL_INTERRUPT_ENABLE;
}
相关文章推荐
- WCF如何克服HTTP传输协议的局限提供对不同消息传输模式的实现
- [置顶] 观察者模式及如何通过消息机制(观察者模式)实现模块间解耦
- UNIX环境下如何应用消息队列实现进程间通信
- 如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- 如何实现Web Service设计与整合模式--前言?
- 使用Biztalk Server实现基于消息的状态机设计模式
- 如何调用NetMessageBufferSend发送消息?(改编)
- 如何利用jgroups实现分布式环境下消息的接受和发送
- 如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- VC中如何实现自定义消息
- 如何实现qq的那种有消息过来,窗口就在任务栏闪的效果?
- 实战演习-如何用wse实现soap消息路由一
- 如何利用jgroups实现分布式环境下消息的接受和发送
- 如何获取错误消息说明使用 FormatMessage API
- 如何自定义一个Remoting中Sink对象实现特定协议上的消息转发
- 如何在VC中实现用户自定义消息
- 如何在C#中实现全屏模式
- 如何利用FDD模式实现项目的精确、快速开发
- 如何用设计模式变相实现类的多继承?
- Liferay研究之廿四:如何实现配置模式