RT_Thread 调试笔记:信号量,互斥量,事件集 的创建和使用流程
2024-01-07 21:01:09
说明:记录日常使用?RT_Thread 开发时做的笔记。
持续更新中,欢迎收藏。
1. 信号量
1. 使用流程
/* 信号量的定义和使用流程 */
/*step1: 定义用于接收消息的信号量*/
static struct rt_semaphore rx_sem; 或者 static rt_sem_t rx_sem;
/*step2: 初始化信号量 */
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/*step3:获取信号量函数,阻塞等待接收信号量,等到信号量后再次读取数据,RT_WAITING_FOREVER参数,永远阻塞,直到获得资源 */
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
/*step4:释放信号量可以唤醒挂起在该信号量上的线程。释放信号量使用下面的函数。可以在中断或线程内使用*/
rt_sem_release(&rx_sem);
//示例:rt_sem_release(&rx_sem_adc_dma);//释放信号量
2.rt_sem_control()
rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg)
????????rt_sem_release释放信号量后会将挂起在sem_ack上的线程唤醒并重新调度,rt_sem_control是有可能等下次该线程运行时才会被执行的。在rt_sem_release后使用rt_sem_control的目的是因为在某些应用中必须rt_sem_take和rt_sem_release依次出现,而不允许rt_sem_release被连续多次调用,一旦出现这种情况会被认为是出现了异常,通过调用rt_sem_control接口来重新初始化sem_ack,恢复异常。
2. 互斥量
/* 互斥量的使用:
* 1:当线程完成互斥资源的访问后,应尽快释放它占据的互斥量,使得其他线程能及时获取该互斥量。
* 2:互斥量的 flag 标志设置为 RT_IPC_FLAG_PRIO,表示在多个线程等待资源时,将由优先级高的线程优先获得资源。
* 3:互斥量的 flag 标志设置为 RT_IPC_FLAG_FIFO,表示在多个线程等待资源时,将按照先来先得的顺序获得资源。
* 4:当不再使用互斥量时,通过删除互斥量以释放系统资源,适用于动态创建的互斥量。
* .删除互斥量使用下面的函数接口:rt_err_t rt_mutex_delete (rt_mutex_t mutex);
* */
/*step1: 定义指向互斥量的指针*/
static rt_mutex_t dynamic_mutex = RT_NULL;
/*step2: 创建一个动态互斥量 */
dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_FIFO);
/*step3: 获取互斥量: rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time);time 可以是等待具体时间也可以是永远等待*/
rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
/*step4: 释放互斥量:*/
rt_mutex_release(dynamic_mutex);
3. 事件集
1. 事件集使用流程及案例:看门狗 事件 控制线程?
/* 看门狗 事件 控制线程 */
#define EVENT_FLAG3 (1 << 3)
#define EVENT_FLAG4 (1 << 4)
#define EVENT_FLAG5 (1 << 5)
#define EVENT_FLAG6 (1 << 5)
#define WDT_EVENT (EVENT_FLAG3 | EVENT_FLAG4 |EVENT_FLAG5 | EVENT_FLAG6) /* 开启的事件打包 */
/* 事件集的管理方式 */
/* step1: 创建事件控制块 */
/* step2: 初始化事件对象 */
/* step3: 发送事件 */
/* step4: 接收事件 */
/* step5: 删除,脱离事件 */
/* step1: 创建事件控制块 */
static struct rt_event wdt_event;
/* 事件应用 线程 入口函数 */
static void thread_recv_event(void *param)
{
rt_uint32_t e; /* 接收事件的变量 */
rt_err_t result;
/* step2: 初始化事件对象 */
result = rt_event_init(&wdt_event, "wdt_event", RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
rt_kprintf("init event failed.\n");
return -1;
}
while(1)
{
/* step4:接收事件,事件 WD_ENENT 打包的事件全部收集后 ....,接收完后清除事件标志 */
if (rt_event_recv(&wdt_event, /* 事件集对象的句柄 */
WDT_EVENT, /* 接收线程感兴趣的事件 */
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, /* 接收选项 ,事件逻辑与,接收后清除事件标志 */
RT_WAITING_FOREVER, /* 指定超时时间 */
&e) /* 指向接收到的事件 */
== RT_EOK)
{
rt_kprintf("thread1: AND recv event 0x%x\n", e);
}
/* 收到事件后要执行的代码 */
}
/* step3: 发送事件 */
/* 发送事件函数使用实例 (此处仅做使用方法记录,本行代码并非使用在此处)*/
rt_event_send(&wdt_event, EVENT_FLAG5); /* 发送事件函数,事件控制块,事件标志位 */
}
/* 接以上 */
文章来源:https://blog.csdn.net/yutian0606/article/details/135436000
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!