Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
【2024-RSOC】RTT的线程同步、线程间的通信
发布于 2024-07-24 23:28:19 浏览:220
订阅该版
[tocm] # RT-Thread IPC ## ipc内容 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240724/59bdc1d318e6f694cbac3668e2c949b1.png.webp) 线程同步类似与裸机的flag 主要是要掌握临界区,阻塞、死锁、挂起 信号量:一种轻型的用于解决线程间同步问题的内核对象,一个或多个运行线程可 以获取或释放它,从而达到同步或互斥的目的。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240724/44d38d38ec5fcba817c92b889b660d3c.png) api: ```c //创建 rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag); //删除 rt_err_t rt_sem_delete(rt_sem_t sem); //初始化 rt_err_t rt_sem_init(rt_sem_t sem, const char *name, rt_uint32_t value, rt_uint8_t flag) //释放 rt_err_t rt_sem_release(rt_sem_t sem); ``` 互斥量 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240724/3e6adaef308e6971853a08f6f8fc3c9a.png) api: ```c rt_mutex_t rt_mutex_create (const char* name, rt_uint8_t flag); rt_err_t rt_mutex_delete (rt_mutex_t mutex); rt_err_t rt_mutex_init (rt_mutex_t mutex, const char* name, rt_uint8_t flag); rt_err_t rt_mutex_detach (rt_mutex_t mutex); rt_err_t rt_mutex_release(rt_mutex_t mutex); ``` 消息邮箱 控制块结构如下: ```c struct rt_mailbox { struct rt_ipc_object parent; rt_uint32_t* msg_pool; /* 邮箱缓冲区的开始地址 */ rt_uint16_t size; /* 邮箱缓冲区的大小 */ rt_uint16_t entry; /* 邮箱中邮件的数目 */ rt_uint16_t in_offset, out_offset; /* 邮箱缓冲的进出指针 */ rt_list_t suspend_sender_thread; /* 发送线程的挂起等待队列 */ }; typedef struct rt_mailbox* rt_mailbox_t; ``` 基础使用 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240724/60c7e5d90e60568ec32714834d8bae4f.png) 消息队列 控制块结构如下 ```c struct rt_messagequeue { struct rt_ipc_object parent; void* msg_pool; /* 指向存放消息的缓冲区的指针 */ rt_uint16_t msg_size; /* 每个消息的长度 */ rt_uint16_t max_msgs; /* 最大能够容纳的消息数 */ rt_uint16_t entry; /* 队列中已有的消息数 */ void* msg_queue_head; /* 消息链表头 */ void* msg_queue_tail; /* 消息链表尾 */ void* msg_queue_free; /* 空闲消息链表 */ rt_list_t suspend_sender_thread; /* 发送线程的挂起等待队列 */ }; typedef struct rt_messagequeue* rt_mq_t; ``` 基础使用 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240724/53e6b23ae70a7d2852d9b8a1b43442aa.png) 配置软件包 ```c menuconfig.exe pkgs --update ``` 学习了FinSH 控制台 ```c int usart_name(void) { rt_kprintf("hello word !!\n"); } MSH_CMD_EXPORT(usart_name, thread sample); ``` 消息队列小demo ```c /* * 程序清单:消息队列例程 * * 这个程序会创建2个动态线程,一个线程会从消息队列中收取消息;一个key线程按下给消 * 息队列发送 普通消息和紧急消息。 */ #include
#include
#include
#ifndef RT_USING_NANO #include
#endif /* RT_USING_NANO */ #define GPIO_LED_B GET_PIN(F, 11) #define GPIO_LED_R GET_PIN(F, 12) #define GPIO_BTN_UP GET_PIN(C, 5) #define GPIO_BTN_DOWN GET_PIN(C, 1) #define THREAD_PRIORITY 25 #define THREAD_TIMESLICE 5 /* 消息队列控制块 */ static struct rt_messagequeue mq; /* 消息队列中用到的放置消息的内存池 */ static rt_uint8_t msg_pool[2048]; #ifdef rt_align rt_align(RT_ALIGN_SIZE) #else ALIGN(RT_ALIGN_SIZE) #endif static char thread1_stack[1024]; static struct rt_thread thread1; /* 线程1入口函数 */ static void thread1_entry(void *parameter) { char buf = 0; rt_uint8_t cnt = 0; while (1) { /* 从消息队列中接收消息 */ #if (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 1)) if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) > 0) #else if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK) #endif { rt_kprintf("thread1: recv msg from msg queue, the content:%c\n", buf); } /* 延时50ms */ rt_thread_mdelay(50); } rt_kprintf("thread1: detach mq \n"); rt_mq_detach(&mq); } #ifdef rt_align rt_align(RT_ALIGN_SIZE) #else ALIGN(RT_ALIGN_SIZE) #endif static char thread2_stack[1024]; static struct rt_thread thread2; /* 线程2入口 */ static void thread2_entry(void *parameter) { int result; char buf = 'A'; static int key_val1,key_val2; //rt_uint8_t cnt = 0; while (1) { key_val1 = rt_pin_read(GPIO_BTN_UP); key_val2 = rt_pin_read(GPIO_BTN_DOWN); /* 按下发送紧急消息 */ if (key_val1 == PIN_LOW) { rt_thread_mdelay(200); if(key_val1 == PIN_LOW) { /* 发送紧急消息到消息队列中 */ result = rt_mq_urgent(&mq, &buf, 1); if (result != RT_EOK) { rt_kprintf("rt_mq_urgent ERR\n"); } else { rt_kprintf("thread2: send urgent message - %c\n", buf); } } } /* 按下发送消息 */ if (key_val2 == PIN_LOW) { rt_thread_mdelay(200); if(key_val2 == PIN_LOW) { /* 发送紧急消息到消息队列中 */ result = rt_mq_send(&mq, &buf, 1); if (result != RT_EOK) { rt_kprintf("rt_mq_send ERR\n"); } else { rt_kprintf("thread2: send message - %c\n", buf); } } } /* 延时5ms */ rt_thread_mdelay(5); } } /* 消息队列示例的初始化 */ int msgq_test_sample(void) { rt_pin_mode(GPIO_BTN_UP, PIN_MODE_INPUT_PULLUP); rt_pin_mode(GPIO_BTN_DOWN, PIN_MODE_INPUT_PULLUP); rt_err_t result; /* 初始化消息队列 */ result = rt_mq_init(&mq, "mqt", &msg_pool[0], /* 内存池指向msg_pool */ 1, /* 每个消息的大小是 1 字节 */ sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */ RT_IPC_FLAG_PRIO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */ if (result != RT_EOK) { rt_kprintf("init message queue failed.\n"); return -1; } rt_thread_init(&thread1, "thread1", thread1_entry, RT_NULL, &thread1_stack[0], sizeof(thread1_stack), THREAD_PRIORITY, THREAD_TIMESLICE); #ifdef RT_USING_SMP /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ rt_thread_control(&thread1, RT_THREAD_CTRL_BIND_CPU, (void*)0); #endif rt_thread_startup(&thread1); rt_thread_init(&thread2, "thread2", thread2_entry, RT_NULL, &thread2_stack[0], sizeof(thread2_stack), THREAD_PRIORITY, THREAD_TIMESLICE); #ifdef RT_USING_SMP /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ rt_thread_control(&thread2, RT_THREAD_CTRL_BIND_CPU, (void*)0); #endif rt_thread_startup(&thread2); return 0; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(msgq_test_sample, msgq_test_sample); ``` 运行结果如下 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240726/b07327e754d5bf4b6b3c64bb76b22f1e.png)
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
XLUR_8603
这家伙很懒,什么也没写!
文章
7
回答
0
被采纳
0
关注TA
发私信
相关文章
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
14
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部