硬汉嵌入式论坛

 找回密码
 立即注册
查看: 854|回复: 51
收起左侧

[μCOS-III] 分享一下自己捣鼓的 cmsis-ucos3-os2 封装层,势力有线不太完善,但初步可用

  [复制链接]

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
发表于 2025-12-9 09:24:25 | 显示全部楼层 |阅读模式
本帖最后由 hpdell 于 2025-12-9 15:52 编辑

分享一下自己捣鼓的 cmsis-ucos3-os2 封装层,实力有线不太完善,但初步可用

ucos3 v3.08.02


已知还没有实现功能的函数如下:

osThreadGetId
osThreadGetState     估计不太完善
osThreadSetPriority         设置任务优先级 不知道是否正常 ?
osThreadYield
osThreadExit
osThreadDetach   有待 后续测试 ...
osThreadJoin
osThreadGetCount
osThreadEnumerate
osMessageQueueGetCapacity
osMessageQueueGetSpace


----------------------------------------------------------------------------------------------------------------------------------
使用说明:

00. 消息邮箱使用双指针
    osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void **msg_ptr, uint8_t *msg_prio, uint32_t timeout);  // cmsis-ucos3-os2 封装层  ok

01. cmsis-ucos3-os2 兼容层定时器回调函数定义:
     typedef void (*osTimerFunc_t) (void *p_tmr, void *p_arg);                // ucos

02.
用户只需包含 #include "cmsis_os.h" 头文件即可

03.  兼容层调用示例:
       cmsis-ucos3-os2-01.png

       cmsis-ucos3-os2-02.png


04. 代码:
      cmsis-ucos3-os2.7z (31.11 KB, 下载次数: 9)


05. 如下内存管理用户替换成自己的内存管理即可:

extern int rt_memheap_init_cmsis_os2(
                         void              *start_addr,
                         uint32_t         size);

extern void *rt_memheap_alloc_cmsis_os2(
                         uint32_t         size);

extern void rt_memheap_free_cmsis_os2( void *ptr);



06. 哪位大佬看看能否加以完善一下下哈,在此先感谢感谢了


07. 初步实现功能如下:

/**
  * @brief  The function osMessageQueueGetMsgSize returns the maximum message
  *         size in bytes for the message queue object specified by parameter
  *         mq_id or 0 in case of an error.
  *         Note : This function may be called from Interrupt Service
  *         Routines.
  * @param  [in] mq_id  message queue ID obtained by osMessageQueueNew.
  * @retval maximum message size in bytes.
  *         函数功能初步实现了
  */
uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id)
{
  /* For OS_Q the control block pointer is the queue identifier */
  OS_Q *queue_ptr = (OS_Q *)mq_id;
  /* The specific maximum message size in bytes */
  uint32_t max_messages_size;

  /* Check if the mq_id is NULL or queue_ptr->tx_queue_id != TX_QUEUE_ID */
  if (queue_ptr == NULL)
  {
    /* Return 0 in case of error */
    max_messages_size = 0U;
  }
  else
  {
    /* Return the message size that was specified in queue creation */
    max_messages_size = queue_ptr->MsgQ.NbrEntriesSize;
  }

  return (max_messages_size);
}

/**
  * @brief  The function osMessageQueueGetCount returns the number of queued
  *         messages in the message queue object specified by parameter mq_id or
  *         0 in case of an error.
  *         Note : This function may be called from Interrupt Service
  *         Routines.
  * @param  [in] mq_id  message queue ID obtained by osMessageQueueNew.
  * @retval number of queued messages.
  *         函数功能初步实现了
  */
uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id)
{
  /* For OS_Q the control block pointer is the queue identifier */
  OS_Q *queue_ptr = (OS_Q *)mq_id;
  /* The specific number of queued messages */
  uint32_t queued_messages_number = 0U;

  /* Check if the mq_id is NULL or queue_ptr->tx_queue_id != TX_QUEUE_ID */
  if (queue_ptr == NULL)
  {
    /* Return 0 in case of error */
    queued_messages_number = 0U;
  }
  else
  {
    /* Call the tx_queue_info_get to get the number of queued messages */
      queued_messages_number = queue_ptr->MsgQ.NbrEntriesSize;
  }

  return (queued_messages_number);
}









评分

参与人数 1金币 +100 收起 理由
eric2013 + 100 很给力!

查看全部评分

回复

使用道具 举报

22

主题

109

回帖

175

积分

初级会员

积分
175
发表于 2025-12-9 09:43:15 | 显示全部楼层
大佬是纯手写代码,没有使用 STM32CubeMX 配置模板吗?
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-9 09:47:06 | 显示全部楼层
刘心武 发表于 2025-12-9 09:43
大佬是纯手写代码,没有使用 STM32CubeMX 配置模板吗?

暂时这个没有
回复

使用道具 举报

22

主题

109

回帖

175

积分

初级会员

积分
175
发表于 2025-12-9 09:59:34 | 显示全部楼层

那你是用 CubeMX 生成的代码挪到你当前截图的工程中吗,并没有直接使用 CubeMX 生成的工程吗?
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
120427
QQ
发表于 2025-12-9 11:26:56 | 显示全部楼层


回复

使用道具 举报

7

主题

40

回帖

61

积分

初级会员

积分
61
发表于 2025-12-9 13:34:47 | 显示全部楼层
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-9 14:04:41 | 显示全部楼层
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-9 14:05:08 | 显示全部楼层
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-9 15:39:00 | 显示全部楼层
刘心武 发表于 2025-12-9 09:59
那你是用 CubeMX 生成的代码挪到你当前截图的工程中吗,并没有直接使用 CubeMX 生成的工程吗?

我这个 cmsis-ucos3-os2  是在 cmsis-threadx-os2 的基础上修改而来的

回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-9 15:41:41 | 显示全部楼层
其实完全可以吧ucos3 和 cmsis_os2 源码直接给AI,没什么太大问题
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-9 19:19:04 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-9 15:41
其实完全可以吧ucos3 和 cmsis_os2 源码直接给AI,没什么太大问题

ai 目前不太会雅,  你看能否帮忙转换一下下 雅 ?
回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-10 16:53:09 | 显示全部楼层
hpdell 发表于 2025-12-9 19:19
ai 目前不太会雅,  你看能否帮忙转换一下下 雅 ?

https://github.com/cyq97/CMSIS-uCOS.git

CMSIS-uCOS-main-a6645830.zip (44.56 KB, 下载次数: 4)

你测试一下吧,很大可能会有问题。我不怎么用 ucos。你你可以直接在这个基础上继续引导 AI 工作。

看着 AI 艰难赛博打工的样子,我都觉得我充钱充少了

回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-11 09:06:34 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-10 16:53
https://github.com/cyq97/CMSIS-uCOS.git




你好, 刚刚下载我大概看了一下,貌似有些复杂,

有些功能也不支持,

我 结合你提供的这个驱动与我分享发布的驱动再整合一下看看能否完美解决哈  
回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-11 09:16:19 | 显示全部楼层
hpdell 发表于 2025-12-11 09:06
你好, 刚刚下载我大概看了一下,貌似有些复杂,

有些功能也不支持,

可以先看一下里面的文档。

AI根据 FreeRTOS 兼容层来做的
https://github.com/ARM-software/CMSIS-FreeRTOS

起先 AI 花了大部分工作在动态创建内核原语上,后来我指示暂时不涉及内存方面的内容,尽量套壳做,没有的特性就不强行适配。
最后做了中断中调用相关原语的适配,也是参照 CMSIS-FreeRTOS 来的

ScreenShot_2025-12-11_091346_026.png
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-11 10:25:26 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-11 09:16
可以先看一下里面的文档。

AI根据 FreeRTOS 兼容层来做的

我吧 attr_t 中的静态控制块改成 动态试试看
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2025-12-11 10:51:36 | 显示全部楼层
感谢楼主的分享精神。这个封装层SiliconLabs已经给了:
https://github.com/SiliconLabs/s ... /source/cmsis_os2.c
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2025-12-11 10:53:12 | 显示全部楼层
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
120427
QQ
发表于 2025-12-11 11:11:36 | 显示全部楼层
hylnew 发表于 2025-12-11 10:51
感谢楼主的分享精神。这个封装层SiliconLabs已经给了:
https://github.com/SiliconLabs/simplicity_sdk/b ...



谢谢分享
回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-11 11:23:10 | 显示全部楼层
hylnew 发表于 2025-12-11 10:53
SiliconLabs官方的:
https://github.com/SiliconLabs/simplicity_sdk/blob/sisdk-2025.6/platform/micriu ...

还是原厂来做这些工作比较合适

不知道动态创建内核对象的时候使用的malloc和free也没有重定向
xxxxxxxxxxxxxxxxxxx.png
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2025-12-11 12:04:40 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-11 11:23
还是原厂来做这些工作比较合适

不知道动态创建内核对象的时候使用的malloc和free也没有重定 ...

应该是没有重定向,代码包含了:#include <stdlib.h>
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-11 14:35:02 | 显示全部楼层
本帖最后由 hpdell 于 2025-12-11 21:50 编辑
hylnew 发表于 2025-12-11 10:51
感谢楼主的分享精神。这个封装层SiliconLabs已经给了:
https://github.com/SiliconLabs/simplicity_sdk/b ...

大牛呀,

貌似他这个里面的写的只是针对他们类型的单片机,如果要想移植到其他类型的单片机上估计还得费一番功夫才行哟

那个 ai 写的相对来说移植要简单一些


回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-12 09:19:10 | 显示全部楼层

大佬,请教下,捣鼓的 cmsis-ucos3-os2 封装层, 使用消息邮箱功能, 貌似有时收不到消息 是怎么回事呀 ?

如果使用 ucos 提供的源封装层就没有这个问题发生

回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-12 11:32:47 | 显示全部楼层
hpdell 发表于 2025-12-12 09:19
大佬,请教下,捣鼓的 cmsis-ucos3-os2 封装层, 使用消息邮箱功能, 貌似有时收不到消息 是怎么回事呀  ...

ucos原生的貌似只能传指针大小的数据
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-12 17:24:24 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-12 11:32
ucos原生的貌似只能传指针大小的数据

重新封装的 cmsis-usoc3-os2 貌似也是穿指针的形式,


回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-12 17:25:21 | 显示全部楼层
hylnew 发表于 2025-12-11 10:53
SiliconLabs官方的:
https://github.com/SiliconLabs/simplicity_sdk/blob/sisdk-2025.6/platform/micriu ...

貌似这个里面的 消息邮箱功能使用的是 信号量来实现的,

消息邮箱被魔改了,牛劈
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-12 20:31:01 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-12 11:32
ucos原生的貌似只能传指针大小的数据

那个 ai 提供的 cmsis-ucos3-os2 封装层, 使用 静态的 mem 工作貌似非常稳定, 使用的 消息邮箱 也没有出现 接收不到消息的情况, 看来还是 ai 牛逼呀 ,

貌似使用动态的 mem 消息邮箱工作就会出现异常但其他组件工作倒是没有什么问题

不知道 ai 提供的那个封装层是基于 ucos3  的哪个版本, 里面有少数函数不支持,

我目前使用的 ucos3 v3.8.2 版本
回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-12 21:02:49 | 显示全部楼层
hpdell 发表于 2025-12-12 20:31
那个 ai 提供的 cmsis-ucos3-os2 封装层, 使用 静态的 mem 工作貌似非常稳定, 使用的 消息邮箱 也没有 ...

3.8.2

PixPin_2025-12-12_20-45-04.png

目前 AI 实现的接口都不支持使用动态内存来创建内核对象。因为我不熟悉 ucos 的内存管理,所以就没让AI做。

其实除了 cmsis_os2 封装的 RTX5,像使用 FreeRTOS、ThreadX是这些的时候习惯上我都不怎么用动态内存的方式来创建 RTOS 内核对象。

如果当前 MessageQueue 的消息大小限制为 sizeof(void *) 用起来不太方便,明天我再生成一个使用静态方式创建任意大小的消息的 MessageQueue 的接口
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-12 21:51:00 | 显示全部楼层
本帖最后由 hpdell 于 2025-12-12 21:55 编辑




取消 queue 大小限制好啊, 期待大神作品呀,

我目前使用的也是 ucos3 v3.8.2 版本的, 里面有几个函数实际中在 源码里面貌似没有找到

如:

OSTaskYield   在 ucos3 里面可以替代的函数:OSSchedRoundRobinYield  我目前是使用这个函数来替代的

OSSemCntGet 这个函数貌似源码里面也是没有的,    目前使用 sem->Ctr; 这个来替代

OSTmrSet  这个函数在源码里只有 6 个参数, 但 ai 生成的却有 7个参数

OSFlagQuery 这个函数源码里面貌似也是没有找到, 我目前使用 ef->grp.Flags;   这个来替代

目前已知的大概就这么多吧 ,  



我要不把动态 mem 的发给你看看 需要不 ?


回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-13 10:35:05 | 显示全部楼层
hpdell 发表于 2025-12-12 21:51
取消 queue 大小限制好啊, 期待大神作品呀,

我目前使用的也是 ucos3 v3.8.2 版本的, 里面有 ...

工作失误了,版本确实存在问题。应该是当时让 AI 查看 ucos3 代码的时候它直接从网上拉的,没有从我给子模块的对应版本中获取信息。

刚刚让 AI 检查了一下存在不一致的问题,"开发记录"目录下有报告。对此进行了修复。

并且将 messagequeue 传递的消息大小升级为任意大小,不过还是只支持静态创建,请参见示例程序

测试就交给你了
主要是我一开始接触的是 FreeRTOS,现在工作上维护的是 RTX5 cmsis_os2 的工程,基本上没用过 ucos。

cyq97/CMSIS-uCOS
CMSIS-uCOS-main-5268130.zip (56.7 KB, 下载次数: 5)
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-13 17:17:27 | 显示全部楼层
本帖最后由 hpdell 于 2025-12-13 17:18 编辑
狠狠滴摸鱼冲浪 发表于 2025-12-13 10:35
工作失误了,版本确实存在问题。应该是当时让 AI 查看 ucos3 代码的时候它直接从网上拉的,没有从我 ...

好的, 我现下载来测试看看
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-13 20:59:48 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-13 10:35
工作失误了,版本确实存在问题。应该是当时让 AI 查看 ucos3 代码的时候它直接从网上拉的,没有从我 ...





刚刚测试了一下, 这个新版本的 消息邮箱有时会出现 收不到的情况, mem 使用的都是 静态定义的缓存,


回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-13 23:54:02 | 显示全部楼层
hpdell 发表于 2025-12-13 20:59
刚刚测试了一下, 这个新版本的 消息邮箱有时会出现 收不到的情况, mem 使用的都是 静态定义的 ...

明天我自己移植再测试一下
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-14 16:01:36 | 显示全部楼层
本帖最后由 hpdell 于 2025-12-14 18:06 编辑
狠狠滴摸鱼冲浪 发表于 2025-12-13 23:54
明天我自己移植再测试一下

好啊,欢迎欢迎啊,

我使用 了 2套消息邮箱

我目前的应用大概说一下:

void music_player_common(int type, char *name);

void music_player_01();
void music_player_02();
void music_player_03();
void music_player_04();


static void AppTaskMusic(void *argument)  {

        status_t  xResult;
        static MusicMsg_T  *pMsg = 0;
        
        while(true)  {

                /* 接受数据,播放MP3文件或者WAV文件 */
                xResult = osMessageQueueGet(xQueue,    /* 消息队列句柄 */
                                                                                        (void *)&pMsg,    /* 这里获取的是结构体的地址 */
                                                                                        0,
                                                                                        osWaitForever);   /* 设置阻塞时间 */                                                               
                if( xResult == osOK )  {
                        music_player_common(pMsg->ucType, (const char *)pMsg->ucName);
                }
               
        }
}



void music_player_common(int type, char *name){
    music_player_01();
}


void music_player_01()  {
   music_player_02();   // 这个函数里面接收到 停止信号后会退出
}


#define MUSIC_STOP   0x25

void music_player_02()  {

   int  cmd_type  = 0;

Music_Message  *pmess = 0;
   .....

   while(1)  {

             status = osMessageQueueGet(Music_Message_Queue_ID, (void *)pmess,0,osWaitForever);

             if(status  == osOK)  {
             cmd_type   = pmess->type;
              switch(cmd_type)  {

                 ...
        
                     case MUSIC_STOP  :   // 收到停止信号后就退出
                        ....
                     return;
             }
        }
    }




第一次等待 xQueue 这个消息邮箱信息可以, 但是第二次等待 xQueue  这个消息时 就不知道跑到哪里去了 ??

xQueue 这个消息邮箱 msg_count  大小 设置 4 /8/16 都没有什么改善

Music_Message_Queue_ID  这个消息邮箱的  msg_count  大小 设置 4 /8/16 都没有什么改善







回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-14 20:02:22 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-13 23:54
明天我自己移植再测试一下





貌似 V2 版本里面 把 发送    稍微修改一下就可以了

//  memcpy(message, msg_ptr, mq->msg_size);
  message = *(void * const *)msg_ptr;       



接收里面也修改一下下

//  memcpy(msg_ptr, message, mq->msg_size);
  *(void **)msg_ptr = message;





回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-14 23:31:16 | 显示全部楼层
本帖最后由 狠狠滴摸鱼冲浪 于 2025-12-14 23:44 编辑
hpdell 发表于 2025-12-14 20:02
貌似 V2 版本里面 把 发送    稍微修改一下就可以了

//  memcpy(message, msg_ptr, mq->msg_s ...

我试了一下 MessageQueue,应该是没有问题,估计是你定义 消息队列控制块 的时候有问题。

https://github.com/cyq97/stm32f429_ucos3.git
如果你github仓库拉不下来,就拿下面这个测试文件看一下吧

[C] 纯文本查看 复制代码
#include "main.h"

#ifdef TEST_MESSAGEQUEUE
#include <string.h>
#include "cmsis_os2.h"
#include "ucos3_os2.h"

/* 线程控制块与栈 */
static uint8_t producer_cb[sizeof(os_ucos3_thread_t)];
static uint8_t consumer_cb[sizeof(os_ucos3_thread_t)];
static CPU_STK producer_stack[512 / sizeof(CPU_STK)];
static CPU_STK consumer_stack[512 / sizeof(CPU_STK)];

/* 消息队列 */
/* 消息的结构 */
typedef struct {
  uint8_t value;    // 改成 uint8_t, uint16_t, uint32_t 进行测试(已通过)
  char    info[14]; // 更改为任意大小进行测试(已通过)
} msg_t;            // (当value类型为 uint16_t 时, 工程使用时尽量保证 sizeof(msg_t) 2字节对齐,测试阶段任意指定
                    // (当value类型为 uint32_t 时, 工程使用时尽量保证 sizeof(msg_t) 4字节对齐,测试阶段任意指定
                    
/* 消息队列的容量 */
#define MESSAGE_QUEUE_CAPACITY    8
#define MESSAGE_SIZE  sizeof(msg_t)
/* 这里需要额外定义一个 (sizeof(void*) * MESSAGE_QUEUE_CAPACITY) 大小的空间:
   因为ucOS3的邮箱传递的是指针, 这个空间就是指针邮箱的静态存储空间 */
__align(8)
static  uint8_t mq_cb[sizeof(os_ucos3_message_queue_t) + (sizeof(void*) * MESSAGE_QUEUE_CAPACITY)];
/* 存储消息的静态空间 */
//__align(8)  // 找个办法测试不对齐
static  uint8_t mq_mem[MESSAGE_SIZE * MESSAGE_QUEUE_CAPACITY];



/* CMSIS 对象句柄 */
static osThreadId_t producer_id;
static osThreadId_t consumer_id;
static osMessageQueueId_t mq_id;


static void producer_thread(void *argument) {
  (void)argument;
  osStatus_t state;
  msg_t msg_write;
  memset(&msg_write, 0, sizeof(msg_write));
  
  for (;;) {
    msg_write.value += 1000;
    state = osMessageQueuePut(mq_id, &msg_write, 0, osWaitForever);
    
    if (state == osOK) {
      osDelay(50);
    }
    /* 消息发送失败, 错误指示灯闪烁 */
    else {
      osThreadSuspend(consumer_id);
      for (;;) {
        LED_1(0);
        osDelay(50);
        LED_1(1);
        osDelay(200);
      }
    }
  }
}

static void consumer_thread(void *argument) {
  (void)argument;
  int led_state;
  osStatus_t state;
  msg_t msg_read;
  msg_t msg_should_read;
  
  memset(&msg_read, 0, sizeof(msg_read));
  memset(&msg_should_read, 0, sizeof(msg_should_read));
  
  for (;;) {
    state = osMessageQueueGet(mq_id, &msg_read, NULL, osWaitForever);
    
    /* 注意以下的比较判断不能直接使用: msg_read.value == msg_should_read.value + 1000
     * 因为比如当 value 类型为 uint8_t 时,右边的表达式是会超过 255 的,
     * 至少应该写 msg_read.value == (msg_should_read.value + 1000) & 0xFF。
     * 但是当 value 类型为 uint8_t 时,又要改成 & 0xFFFF 了。
     * 因此直接用下面的通用比较方式
     */
    msg_should_read.value += 1000;
    if (state == osOK && msg_read.value == msg_should_read.value) {
      LED_0(led_state);
      led_state = !led_state;
    }
    /* 消息接收失败, 错误指示灯闪烁 */
    else {
      osThreadSuspend(producer_id);
      for (;;) {
        LED_1(0);
        osDelay(50);
        LED_1(1);
        osDelay(50);
      }
    }
  }
}


void app_main(void) {
  osKernelInitialize();

  /* 消息队列 (静态消息存储) */
  const osMessageQueueAttr_t mq_attr = {
    .name = "queue",
    .cb_mem = mq_cb,
    .cb_size = sizeof(mq_cb),
    .mq_mem = mq_mem,
    .mq_size = sizeof(mq_mem),
  };
  mq_id = osMessageQueueNew(MESSAGE_QUEUE_CAPACITY, MESSAGE_SIZE, &mq_attr);

  /* 线程 */
  const osThreadAttr_t producer_attr = {
    .name = "producer",
    .cb_mem = producer_cb,
    .cb_size = sizeof(producer_cb),
    .stack_mem = producer_stack,
    .stack_size = sizeof(producer_stack),
    .priority = osPriorityNormal,
  };
  const osThreadAttr_t consumer_attr = {
    .name = "consumer",
    .cb_mem = consumer_cb,
    .cb_size = sizeof(consumer_cb),
    .stack_mem = consumer_stack,
    .stack_size = sizeof(consumer_stack),
    .priority = osPriorityAboveNormal,
  };

  producer_id = osThreadNew(producer_thread, NULL, &producer_attr);
  consumer_id = osThreadNew(consumer_thread, NULL, &consumer_attr);
  (void)producer_id;
  (void)consumer_id;

  osKernelStart();
}

#endif /* #ifdef TEST_MESSAGEQUEUE */


回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-15 14:40:55 | 显示全部楼层
狠狠滴摸鱼冲浪 发表于 2025-12-14 23:31
我试了一下 MessageQueue,应该是没有问题,估计是你定义 消息队列控制块 的时候有问题。

https://git ...





  msg_t msg_read;
   
  memset(&msg_read, 0, sizeof(msg_read));
    state = osMessageQueueGet(mq_id, &msg_read, NULL, osWaitForever);


貌似这个应用就跟 cmsis-os2 源封装层有点差异了,

------------------------------------------------------------------------------------------------------------
cmsis-os2 的 封装层应用貌似是这样的
msg_t  *msg_read;
state = osMessageQueueGet(mq_id, &msg_read, NULL, osWaitForever);
回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-15 14:47:30 | 显示全部楼层
hpdell 发表于 2025-12-15 14:40
msg_t msg_read;
   
  memset(&msg_read, 0, sizeof(msg_read));

ScreenShot_2025-12-15_144714_232.png
回复

使用道具 举报

719

主题

3771

回帖

5953

积分

论坛元老

积分
5953
 楼主| 发表于 2025-12-15 21:09:27 | 显示全部楼层
本帖最后由 hpdell 于 2025-12-15 21:24 编辑



我修改了我的上层 应用 来匹配这个驱动是可以了, 只是有点与我之前的应用驱动有些不太兼容, 你目前的这个最新版本使用是完全没有问题的,

另外有个疑问请教下, 在 消息邮箱创建里面多个了一个信号量的定义:

  OS_SEM            space_sem;
  bool              space_sem_created;


我把这个定义的信号量的相关代码屏蔽后貌似也能够正常工作, 想请问下这个信号量的加入有什么深意吗 ?  
回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-16 09:05:16 | 显示全部楼层
hpdell 发表于 2025-12-15 21:09
我修改了我的上层 应用 来匹配这个驱动是可以了, 只是有点与我之前的应用驱动有些不太兼容, 你目前 ...

uC-OS3的OS_Q的写入没有超时机制,cmsis_os2的MessageQueue的写入有超时参数
回复

使用道具 举报

4

主题

55

回帖

67

积分

初级会员

积分
67
发表于 2025-12-16 09:10:17 | 显示全部楼层
hpdell 发表于 2025-12-14 16:01
好啊,欢迎欢迎啊,

我使用 了 2套消息邮箱

而且你给的代码不完整,看的晕,我不知道你想传的是数据块的指针还是直接通过指针操作MessageQueue中的数据块。
还有就是这样用,要配合锁等机制来保护这些数据和指向他们的指针是同步的被操作的。

回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-1-9 16:56 , Processed in 0.084801 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表