色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          "); //-->

          博客專欄

          EEPW首頁 > 博客 > 【RT-Thread 筆記】----使用消息隊列發(fā)送不定長數(shù)據(jù)

          【RT-Thread 筆記】----使用消息隊列發(fā)送不定長數(shù)據(jù)

          發(fā)布人:電子禪石 時間:2019-02-13 來源:工程師 發(fā)布文章

          簡介:

          本文簡要介紹如何使用RT-Thread 的消息隊列 發(fā)送不定長數(shù)據(jù)的使用。數(shù)據(jù)比較經(jīng)典的用法,可以在很多數(shù)據(jù)傳輸?shù)膱龊蠎?yīng)用。

          知識點:

          1.參考內(nèi)容:

          https://www.rt-thread.org/document/site/programming-manual/ipc2/ipc2/#_2

          2.要點摘錄:通過定義結(jié)構(gòu)體:數(shù)據(jù)塊首地址和數(shù)據(jù)塊大小 來進行數(shù)據(jù)的傳遞。非常通用。

          消息隊列的使用場合

          消息隊列可以應(yīng)用于發(fā)送不定長消息的場合,包括線程與線程間的消息交換,以及中斷服務(wù)例程中給線程發(fā)送消息(中斷服務(wù)例程不能接收消息)。下面分發(fā)送消息和同步消息兩部分來介紹消息隊列的使用。

          發(fā)送消息

          消息隊列和郵箱的明顯不同是消息的長度并不限定在 4 個字節(jié)以內(nèi);另外,消息隊列也包括了一個發(fā)送緊急消息的函數(shù)接口。但是當創(chuàng)建的是一個所有消息的最大長度是 4 字節(jié)的消息隊列時,消息隊列對象將蛻化成郵箱。這個不限定長度的消息,也及時的反應(yīng)到了代碼編寫的場合上,同樣是類似郵箱的代碼:

          struct msg{
              rt_uint8_t *data_ptr;    /* 數(shù)據(jù)塊首地址 */
              rt_uint32_t data_size;   /* 數(shù)據(jù)塊大小   */};

          和郵箱例子相同的消息結(jié)構(gòu)定義,假設(shè)依然需要發(fā)送這樣一個消息給接收線程。在郵箱例子中,這個結(jié)構(gòu)只能夠發(fā)送指向這個結(jié)構(gòu)的指針(在函數(shù)指針被發(fā)送過去后,接收線程能夠正確的訪問指向這個地址的內(nèi)容,通常這塊數(shù)據(jù)需要留給接收線程來釋放)。而使用消息隊列的方式則大不相同:

          void send_op(void *data, rt_size_t length){    struct msg msg_ptr;
          
              msg_ptr.data_ptr = data;  /* 指向相應(yīng)的數(shù)據(jù)塊地址 */
              msg_ptr.data_size = length; /* 數(shù)據(jù)塊的長度 */
          
              /* 發(fā)送這個消息指針給 mq 消息隊列 */
              rt_mq_send(mq, (void*)&msg_ptr, sizeof(struct msg));
          }

          注意,上面的代碼中,是把一個局部變量的數(shù)據(jù)內(nèi)容發(fā)送到了消息隊列中。在接收線程中,同樣也采用局部變量進行消息接收的結(jié)構(gòu)體:

          void message_handler(){    struct msg msg_ptr; /* 用于放置消息的局部變量 */
          
              /* 從消息隊列中接收消息到 msg_ptr 中 */
              if (rt_mq_recv(mq, (void*)&msg_ptr, sizeof(struct msg)) == RT_EOK)
              {        /* 成功接收到消息,進行相應(yīng)的數(shù)據(jù)處理 */
              }
          }

          因為消息隊列是直接的數(shù)據(jù)內(nèi)容復(fù)制,所以在上面的例子中,都采用了局部變量的方式保存消息結(jié)構(gòu)體,這樣也就免去動態(tài)內(nèi)存分配的煩惱了(也就不用擔心,接收線程在接收到消息時,消息內(nèi)存空間已經(jīng)被釋放)。

          例子說明:

          下面例子是通過onenet 平臺發(fā)送不定長命令,在開發(fā)板的命令響應(yīng)回掉函數(shù)中 將數(shù)據(jù)發(fā)送到打印線程:

          /* onenet mqtt command response callback function */
          static void onenet_cmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size)
          {
              char res_buf[] = { "cmd is received!\n" };
          
              log_d("recv data is %.*s\n", recv_size, recv_data);
              rs485_transport(recv_data,recv_size);
              /* user have to malloc memory for response data */
              *resp_data = (uint8_t *) ONENET_MALLOC(strlen(res_buf));
          
              strncpy(*resp_data, res_buf, strlen(res_buf));
          
              *resp_size = strlen(res_buf);
                  
          }
          static rt_uint8_t temp_data[20];
          void rs485_transport(uint8_t *recv_data, size_t recv_size)
          {
                    int result;
                          struct msg msg_ptr;
                       //增加一句 先  把數(shù)據(jù)復(fù)制到靜態(tài)變量中。
                         strncpy(temp_data, recv_data, recv_size);
                          msg_ptr.data_ptr = temp_data;//recv_data;
                          msg_ptr.data_size = recv_size;
              rt_pin_write(RS485_RE_DE_Pin, PIN_HIGH);
          /* 發(fā)送消息到消息隊列中 */
                      result = rt_mq_send(&mq,(void*)&msg_ptr,sizeof(struct msg));
                      if (result != RT_EOK)
                      {
                          rt_kprintf("rt_mq_send ERR\n");
                      }
          
                      rt_kprintf("thread onenet: send message - %s\n", msg_ptr.data_ptr);
              //rt_pin_write(RS485_RE_DE_Pin, PIN_LOW);
          }
          
          接收處理:
          static void serial_thread_entry(void *parameter)
          {
              char buf;
              rt_uint8_t k;
                  struct msg msg_prt;
              while (1)
              {
          
                                /* 從消息隊列中接收消息 */
          
                          if (rt_mq_recv(&mq, (void*)&msg_prt, sizeof(struct msg), RT_WAITING_FOREVER) == RT_EOK)
                  {
                  
                                  rt_device_write(serial, 0, (void*)msg_prt.data_ptr, msg_prt.data_size);
                  }
              
              }
          }

          *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



          關(guān)鍵詞:

          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉