当前位置:   article > 正文

CMSIS-RTOS 线程间通信 Inter-Thread Communication_cmsis rtos event flag

cmsis rtos event flag

线程间通信 Inter-Thread Communication

前面我们已经学习了如何把你的应用代码设计成独立的线程,以及如何访问RTOS的时间服务函数。在实际的工程应用中,线程间的通信是必不可少的,任何一个RTOS都会支持几种通信方式来连接各种不同的线程。CMSIS-RTOS API支持的通信方式有:信号(signals),信号量(semaphores),互斥锁(mutexes),邮箱(mailboxes)和消息队列(message queues)。所有这些首要的核心概念就是并发性。在这一章,将集中讨论多任务间的同步问题。

信号 Signals

CMSIS RTOS RTX支持单线程16种信号标志,这些信号存储在线程控制块里,一个线程会暂停执行,直到一个或一组信号标志被其他线程置位。

这里写图片描述

每个线程有16个信号标志,一个线程可能被置于等待状态,直到一种模式的信号被其他线程置位。然后此线程就会返回等待状态,并等待调度器调度到运行状态。

调用信号等待后,系统会挂起正在运行的线程,并把它置于等待事件(wait_event)状态,直到所有的信号标志被置位,线程才会恢复运行。当然也可以加入超时机制,以便让线程可以顺利返回等待状态。默认初始化超时值是0xFFFF。

osEvent osSignalWait(int32_t signals, uint32_t millisec);
  • 1

调用osSignalWait之后会把信号复位,如果后面还有信号被置位,线程就可以继续执行,你可以读osEvent.value.signals的值来获取哪个标志被置位。

任何一个线程都可以置位或清除另外一个线程的信号:

int32_t osSinalSet(osThreadId thread_id, int32_t signals);
int32_t osSignalClear(osThreadId thread_id, int32_t signals);
  • 1
  • 2

练习:信号

在这个练习里,我们将学会如何在两个线程之间使用信号触发线程执行。

打开Pack Installer,并选择”Ex 8 Signals,然后install到你的自定义路径

从代码中可以看到,两个线程都是执行的LED闪烁程序,其中一个通过调用osDelay()暂停执行,同时置位一个信号来唤醒另外一个LED线程:

void led_Thread2(void const *argument){
    f(;;){
        LED_On(2);
        osSignalSet(T_led_ID1, 0x01);
        osDelay(500);
        LED_Off(2);
        osSignalSet(T_led_ID1, 0x01);
        osDelay(500);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

第二个线程等待信号被置位,然后才会执行LED闪烁程序:

void led_Thread1(void const *argument){
    for(;;){
        osSignalWait(0x01, osWaitFover);//无超时机制
        LED_On(1);
        osSignalWait(0x01, osWaitFover);
        LED_Off(1);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

编译工程,请启动debugger环境

打开GPIOB窗口,并全速运行代码
这里写图片描述

从窗口中可以看到两个管脚亮灭是同步的,给人的错觉就是两个LED线程是并行运行的。

这个例子虽然简单,却揭示了线程间同步的核心概念,而这又是RTOS最基本的应用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/397991
推荐阅读
相关标签
  

闽ICP备14008679号