[C] 消息队列机制 →→→→→进入此内容的聊天室

来自 , 2021-01-27, 写在 C, 查看 137 次.
URL http://www.code666.cn/view/1fb2a1c3
  1. /***************************************************************************************
  2. 建立头文件"msg.h"
  3. ****************************************************************************************/
  4. #ifndef __MSG_H
  5. #define __MSG_H
  6.  
  7. //////////////////////// 参数配置 ////////////////////////
  8. //结构体_msg的数据接收器msgData最大大小
  9. #define MSG_DATA_LEN        (20ul)
  10.  
  11. /* 消息 */
  12. #define MSG_DATA_NONE                      0x00 //空
  13.  
  14. #define MSG_TYPE_SYSMODE_SWITCH       0x00      //模式切换
  15.         #define MSG_DATA_SYSMODE_AUTO          0x00 //切换成自动模式
  16.         #define MSG_DATA_SYSMODE_TP            0x01 //切换成定时器模式
  17.         #define MSG_DATA_SYSMODE_HOLIDAY       0x02 //切换成度假模式
  18.         #define MSG_DATA_SYSMODE_MANUAL        0x03 //切换成 Manual ONOFF模式
  19.         #define MSG_DATA_SYSMODE_TEST          0x04 //切换成测试模式
  20.  
  21. #define MSG_TYPE_PASSWORD_RESET       0x01 //密码恢复
  22. #define MSG_TYPE_ENERGY_DATE_UPDATE   0x02 //能源管理日期更新
  23. #define MSG_TYPE_LAMP_LUX_UPDATE      0x03 //更新灯光亮度,并重新计算offlux
  24.  
  25. //////////////////////////////////////////////////////////
  26.  
  27.  
  28. //消息队列控制块
  29. typedef struct
  30. {
  31.   void **QStart;  /* Pointer to start of queue data                              */
  32.   void **QEnd;    /* Pointer to end   of queue data                              */
  33.   void **QIn;     /* Pointer to where next message will be inserted  in   the Q  */
  34.   void **QOut;    /* Pointer to where next message will be extracted from the Q  */
  35.   int  QSize;     /* Size of queue (maximum number of entries)                   */
  36.   int  QEntries;  /* Current number of entries in the queue                      */
  37. } _msg_q;
  38.  
  39. //消息
  40. typedef struct {
  41.   unsigned char msgType;                  /* Message type            */
  42.   unsigned char msgData[MSG_DATA_LEN];    /* Message data buffer     */
  43.   unsigned char dataSize;                 /* Length of message data  */
  44. } _msg;
  45.  
  46. #define MSG_Q_SUCCESS         ((unsigned char)0)  //成功
  47. #define MSG_Q_NONE            ((unsigned char)1)  //无消息,消息队列空
  48. #define MSG_Q_FULL            ((unsigned char)2)  //消息队列满
  49. #define MSG_Q_ERR             ((unsigned char)3)  //错误
  50. #define MSG_MALLOC_FAILED     ((unsigned char)4)  //内存分配失败
  51.  
  52. char MsgQCreate(_msg_q* pQ, void **start, int size);
  53. char MsgQPost(_msg_q* pQ, void* pmsg);
  54. void* MsgQPend(_msg_q* pQ, char* err);
  55. char MQPostMessage(_msg_q* pQ, _msg msg);
  56. char MQGetMessage(_msg_q* pQ, _msg* msg);
  57.  
  58. #endif /*__MSG_H*/
  59.  
  60.  
  61. /***************************************************************************************
  62. 建立源文件"msg.c"
  63. ****************************************************************************************/
  64. #include "msg.h"
  65. #include "stdlib.h"
  66.  
  67. //////////////////////// 消息队列 ////////////////////////
  68. //消息队列发送的是消息指针
  69.  
  70. /*
  71.  @FUNCTION  创建消息队列
  72.  @INPUT     pQ    消息队列控制块
  73.             start 消息队列首地址
  74.             size  消息队列大小
  75.  @OUTPUT    MSG_Q_ERR      创建消息队列失败,数据错误
  76.             MSG_Q_SUCCESS  创建消息队列成功
  77.  **/
  78. char MsgQCreate(_msg_q* pQ, void **start, int size)
  79. {
  80.         if(pQ == 0 || start == 0 || size == 0)
  81.         {
  82.                 return MSG_Q_ERR;
  83.         }
  84.         else
  85.         {
  86.                 pQ->QStart   = start;
  87.                 pQ->QEnd     = &start[size];
  88.                 pQ->QIn      = start;
  89.                 pQ->QOut     = start;
  90.                 pQ->QSize    = size;
  91.                 pQ->QEntries = 0u;
  92.                
  93.                 return MSG_Q_SUCCESS;
  94.         }
  95. }
  96.  
  97. /*
  98.  @Function : 发送消息指针
  99.  @Input     : pQ   消息队列控制块
  100.              pmsg 消息指针
  101.  @Output   : MSG_Q_SUCCESS  发送成功
  102.              MSG_Q_FULL     消息队列已满
  103.              MSG_Q_ERR      数据错误
  104.  **/
  105. char MsgQPost(_msg_q* pQ, void* pmsg)
  106. {
  107.         if(pQ == 0 || pmsg == 0)
  108.         {
  109.                 return MSG_Q_ERR;
  110.         }
  111.         if(pQ->QEntries >= pQ->QSize)
  112.         {
  113.                 return MSG_Q_FULL;
  114.         }
  115.         pQ->QEntries++;
  116.         *pQ->QIn++ = pmsg;
  117.         if(pQ->QIn == pQ->QEnd)
  118.         {
  119.                 pQ->QIn = pQ->QStart;
  120.         }
  121.  
  122.         return MSG_Q_SUCCESS;
  123. }
  124.  
  125. /*
  126.  @Function : 请求消息队列
  127.  @Input     : pQ   消息队列控制块
  128.              err  错误信息
  129.                       MSG_Q_SUCCESS  发送成功
  130.                       MSG_Q_NONE     消息队列空
  131.                       MSG_Q_ERR      数据错误
  132.  @Output   : 消息指针接收器
  133.  **/
  134. void* MsgQPend(_msg_q* pQ, char* err)
  135. {
  136.         void* pmsg = NULL;
  137.  
  138.         if(pQ == 0)
  139.         {
  140.                 *err = MSG_Q_ERR;
  141.         }
  142.         else if(pQ->QEntries <= 0)
  143.         {
  144.                 *err = MSG_Q_NONE;
  145.         }
  146.         else
  147.         {
  148.                 pmsg = *pQ->QOut++;
  149.                 pQ->QEntries--;
  150.                 if(pQ->QOut == pQ->QEnd)
  151.                 {
  152.                         pQ->QOut = pQ->QStart;
  153.                 }
  154.                 *err = MSG_Q_SUCCESS;
  155.         }
  156.         return pmsg;
  157. }
  158.  
  159. /*
  160.  @Function : 数据复制
  161.  @Input     : ptrdes
  162.              ptrsrc
  163.              len    复制的字节长度
  164.  @Output   : 目的地址
  165.  **/
  166. static void* mymemcpy(void* pdes, void* psrc, unsigned int len)
  167. {
  168.         char* ptrdes = (char*)pdes;
  169.         char* ptrsrc = (char*)psrc;
  170.  
  171.         if(pdes == 0 || psrc == 0)
  172.                 return pdes;
  173.         if(ptrdes>ptrsrc?(ptrdes-ptrsrc<len):(ptrsrc-ptrdes<len))//有重叠
  174.         {
  175.                 return pdes;
  176.         }      
  177.     while(len--)
  178.     {
  179.         *ptrdes++ = *ptrsrc++;
  180.     }
  181.         return pdes;
  182. }
  183.  
  184. //////////////////////// 消息的发送和接收 ////////////////////////
  185. //消息发送的是消息内容,消息以结构体_msg封装起来
  186. //将消息内容复制存放在一个新分配的内存空间中再将此空间指针进行传递,
  187. //MQGetMessage接收到指针后将该空间内容复制出来,而后再释放掉该空间。
  188.  
  189. /*
  190.  @Function : 发送消息
  191.  @Input     : pQ  消息队列控制块
  192.              msg 消息
  193.  @Output   : MSG_Q_SUCCESS      发送成功
  194.              MSG_MALLOC_FAILED  内存分配失败
  195.              其他
  196.  **/
  197. char MQPostMessage(_msg_q* pQ, _msg msg)
  198. {
  199.         unsigned char *buffer;
  200.         char res;
  201.  
  202.         buffer = (unsigned char *)malloc(2+msg.dataSize);
  203.         if(buffer == 0)
  204.         {
  205.                 buffer = (unsigned char *)malloc(2+msg.dataSize);
  206.                 if(buffer == 0)
  207.                 {
  208.                         return MSG_MALLOC_FAILED;
  209.                 }
  210.         }
  211.  
  212.         buffer[0] = msg.msgType;
  213.         buffer[1] = msg.dataSize;
  214.         mymemcpy(&buffer[2], msg.msgData, (unsigned int)msg.dataSize);
  215.        
  216.         res = MsgQPost(pQ, (void*)buffer);
  217.  
  218.         return res;
  219. }
  220.  
  221. /*
  222.  @Function : 接收消息
  223.  @Input     : pQ            消息队列控制块
  224.              msg           消息接收器
  225.  @Output   : MSG_Q_SUCCESS 接收成功
  226.              其他
  227.  **/
  228. char MQGetMessage(_msg_q* pQ, _msg* msg)
  229. {
  230.         unsigned char* buffer;
  231.         char res;
  232.        
  233.         buffer = (unsigned char*)MsgQPend(pQ, &res);
  234.         if(res == MSG_Q_SUCCESS)
  235.         {
  236.                 msg->msgType  = buffer[0];
  237.                 msg->dataSize = buffer[1];
  238.                 mymemcpy(msg->msgData, &buffer[2], (unsigned int)msg->dataSize);
  239.                 free(buffer);
  240.         }
  241.         return res;
  242. }
  243.  
  244.  
  245.  
  246.  

回复 "消息队列机制"

这儿你可以回复上面这条便签

captcha