您的位置:首页 > 其它

CMSIS-RTOS 线程间通信 Inter-Thread Communication

2016-11-20 16:31 1906 查看

线程间通信 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);


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

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

int32_t osSinalSet(osThreadId thread_id, int32_t signals);
int32_t osSignalClear(osThreadId thread_id, int32_t signals);


练习:信号

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

打开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);
}
}


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

void led_Thread1(void const *argument){
for(;;){
osSignalWait(0x01, osWaitFover);//无超时机制
LED_On(1);
osSignalWait(0x01, osWaitFover);
LED_Off(1);
}
}


编译工程,请启动debugger环境

打开GPIOB窗口,并全速运行代码



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

这个例子虽然简单,却揭示了线程间同步的核心概念,而这又是RTOS最基本的应用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: