18815|5

155

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

关于CMSIS_OS对FreeRTOS创建队列API接口封装的问题。 [复制链接]

本帖最后由 liutogo 于 2015-7-15 22:16 编辑

感觉CMSIS_OS用的地方也并不多,不过STM32官方的RTOS历程,包括CUBE生成的FreeRTOS历程都是用CMSIS_OS做为应用的接口,顺便就了解一下这个。

问题来了:

下面是CMSIS_OS对FreeRTOS创建消息队列函数的封装,
  1. //CMSIS_OS创建队列API--------------------------------------------
  2. osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id)
  3. {
  4.   (void) thread_id;
  5.   
  6.   return xQueueCreate(queue_def->queue_sz, (uint32_t) sizeof(queue_def->item_sz));
  7. }
  8. //FreeRTOS创建队列API--------------------------------------------
  9. xQueueHandle xQueueCreate (
  10. unsigned portBASE_TYPE uxQueueLength, 队列中包含最大项目数量
  11. unsigned portBASE_TYPE uxItemSize 队列中每个项目所需的字节数
  12. );
复制代码
  1. typedef const struct os_messageQ_def  {

  2.   uint32_t                queue_sz;    /*  number of elements in the queue 队列中包含项目数量 */

  3.   uint32_t                 item_sz;    /*  size of an item 队列中每个项目所需的字节数 */

  4.   //void                       *pool;    /*  memory array for messages */

  5. } osMessageQDef_t;
复制代码

queue_def是以上结构体的一个实例,sizeof(queue_def->item_sz)即 sizeof(int32_t)=4
也就是说 使用CMSIS的接口 最终调用FreeRTOS的API,在FreeRTOS的API第二个实参这里都会传递的是4 ,岂不是就丧失了FreeRTOS接口的多样性。??


最新回复

osMessageQDef(MsgBox, 16, T_MEAS);               // Define message queue osMessageQId  MsgBox; 我觉得例程里面MsgBox定义有错吧,既然是个指针,应该定义为32位的大小,T_MEAS大小明显大于32位,这样会导致未知地址的拷贝,可能造成很严重的错误。  详情 回复 发表于 2017-10-12 11:13
点赞 关注

回复
举报

7815

帖子

56

TA的资源

裸片初长成(中级)

沙发
 
也许,它的目的就是为了侦察提供这个item_sz的定义者,给它定义的字长(port时,看样子是要求移植者提供这个定义好或者修改好的新的item_sz)
 
 

回复

155

帖子

1

TA的资源

一粒金砂(中级)

板凳
 
又想了想,觉得有些头绪了。
之前问题纠结到了,使用CMSIS_OS API创建消息队列,消息队列单元的大小仅仅是4字节。而直接使用FreeRTOS的API创建消息队列,可以将消息队列的单元大小设置成任意,也就是说,消息队列中可以直接传递一些复杂些的结构体、数组什么的。本以为CMSIS_OS会限制FreeRTOS消息队列传递复杂的数据结构。现在想想,并不用担心这样的问题。
CMSIS-RTOS的说明文档中这样描述:
Message Queue Management functions allow to control, send, receive, or wait for messages. A message can be an integer or pointer value that is send to a thread or interrupt service routine.

意思就是,CMSIS_OS下消息队列传递的是整型或是指针量(它们在ARM下都是占用4字节空间),所以CMSIS_OS下的消息队列单元的字节长度就是4。

这样做,可以通过传递复杂数据结构的指针,来实现任务间通信。(不过这些数据结构应该是动态分配的,不是任务中的局部变量,也就是说它们的指针并不指向任务栈空间)



附:osMessageCreate 说明文档:

osMessageQId osMessageCreate
(const osMessageQDef_t * queue_def,
osThreadId thread_id
)

Parameters
[in]queue_defqueue definition referenced with osMessageQ.
[in]thread_idthread ID (obtained by osThreadCreate or osThreadGetId) or NULL.
Returnsmessage queue ID for reference by other functions or NULL in case of error.NoteMUST REMAIN UNCHANGED: osMessageCreate shall be consistent in every CMSIS-RTOS.
Create and initialize a message queue.
Example
#include "cmsis_os.h"

osThreadId tid_thread1;                          // ID for thread 1
osThreadId tid_thread2;                          // for thread 2

typedef struct {                                 // Message object structure
  float    voltage;                              // AD result of measured voltage
  float    current;                              // AD result of measured current
  int      counter;                              // A counter value
} T_MEAS;

osPoolDef(mpool, 16, T_MEAS);                    // Define memory pool
osPoolId  mpool;
osMessageQDef(MsgBox, 16, T_MEAS);               // Define message queue
osMessageQId  MsgBox;

void send_thread (void const *argument);         // forward reference
void recv_thread (void const *argument);         // forward reference
                                                 // Thread definitions
osThreadDef(send_thread, osPriorityNormal, 1, 0);
osThreadDef(recv_thread, osPriorityNormal, 1, 2000);

/*
    Thread 1: Send thread
*/
void send_thread (void const *argument) {
  T_MEAS    *mptr;

  mptr = osPoolAlloc(mpool);                     // Allocate memory for the message
  mptr->voltage = 223.72;                        // Set the message content
  mptr->current = 17.54;
  mptr->counter = 120786;
  osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever);  // Send Message
  osDelay(100);

  mptr = osPoolAlloc(mpool);                     // Allocate memory for the message
  mptr->voltage = 227.23;                        // Prepare a 2nd message
  mptr->current = 12.41;
  mptr->counter = 170823;
  osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever);  // Send Message
  osThreadYield();                               // Cooperative multitasking
                                                 // We are done here, exit this thread
}

/*
    Thread 2: Receive thread
*/
void recv_thread (void const *argument) {
  T_MEAS  *rptr;
  osEvent  evt;

  for (;;) {
    evt = osMessageGet(MsgBox, osWaitForever);  // wait for message
    if (evt.status == osEventMessage) {
      rptr = evt.value.p;
      printf ("\nVoltage: %.2f V\n", rptr->voltage);
      printf ("Current: %.2f A\n", rptr->current);
      printf ("Number of cycles: %d\n", rptr->counter);
      osPoolFree(mpool, rptr);                  // free memory allocated for message
    }
  }
}

void StartApplication (void) {
  mpool = osPoolCreate(osPool(mpool));                 // create memory pool
  MsgBox = osMessageCreate(osMessageQ(MsgBox), NULL);  // create msg queue

  tid_thread1 = osThreadCreate(osThread(send_thread), NULL);
  tid_thread2 = osThreadCreate(osThread(recv_thread), NULL);
  :
}




 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

4
 
我也遇到这个问题了。看来经过封装后,是没有办法想FREERTOS那样生成队列了。只能传递指针了。
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

5
 
lb342 发表于 2017-4-5 15:47
我也遇到这个问题了。看来经过封装后,是没有办法想FREERTOS那样生成队列了。只能传递指针了。

其实单单传递指针方式很好,直接传递和传递指针来说,传递指针更高效,而且什么功能都能实现了,封装的很好
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

6
 
osMessageQDef(MsgBox, 16, T_MEAS);               // Define message queue
osMessageQId  MsgBox;
我觉得例程里面MsgBox定义有错吧,既然是个指针,应该定义为32位的大小,T_MEAS大小明显大于32位,这样会导致未知地址的拷贝,可能造成很严重的错误。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表