keil提供了RTX模板,先看一下最简单的RTX_Blinky 模板。文末附Blinky.c代码。
打开工程一堆文件,最主要关心Blinky.c文件,先用osThreadId定义各个线程的标示符 , 在此要使用信号signal,在每个线程可以使用16个信号标志(Signal Flags)。
在主程序中使用osThreadCreate()创建了phaseA,B,C,D以及时钟线程,之后使用 osSignalSet(thread_id,signals )给第一个线程发送信号,然后osDelay(osWaitForever);即主程序被永久挂起,而在第一个线程中有osSignalWait(signals,osWaitForever)函数一直在等待这个信号的到来,当信号到来时就开始运行第一个线程内的程序开灯A, 然后调用signal_func(tid_phaseB)函数运行了时钟线程,开启关闭LED_CLK2次,给phaseB线程发signal,运行phaseB线程.500ms后关闭灯A,phaseB,C,D线程的运行和phaseA线程一模一样,而且就这样无限循环一次执行下去。
信号和信号量的区别:转自http://www.cnblogs.com/viviwind/archive/2012/12/19/2824524.html
信号量(Semaphore),有时被称为信号灯,是在多环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量
1.信号:(signal)是一种处理异步事件的方式。信号时比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程外,还可以发送信号给进程本身。linux除了支持unix早期的信号语义函数,还支持语义符合posix.1标准的信号函数sigaction。
2.信号量:(Semaphore)进程间通信处理同步互斥的机制。是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
/*----------------------------------------------------------------------------
* RL-ARM - RTX
*----------------------------------------------------------------------------
* Name: BLinky.c
* Purpose: RTX example program
*----------------------------------------------------------------------------
* This code is part of the RealView Run-Time Library.
* Copyright (c) 2004-2014 KEIL - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include "cmsis_os.h"
#include "LPC17xx.h"
#include "Board_LED.h"
osThreadId tid_phaseA; /* Thread id of task: phase_a */
osThreadId tid_phaseB; /* Thread id of task: phase_b */
osThreadId tid_phaseC; /* Thread id of task: phase_c */
osThreadId tid_phaseD; /* Thread id of task: phase_d */
osThreadId tid_clock; /* Thread id of task: clock */
#define LED_A 0
#define LED_B 1
#define LED_C 2
#define LED_D 3
#define LED_CLK 7
/*----------------------------------------------------------------------------
* Switch LED on
*---------------------------------------------------------------------------*/
void Switch_On (unsigned char led) {
LED_On(led);
}
/*----------------------------------------------------------------------------
* Switch LED off
*---------------------------------------------------------------------------*/
void Switch_Off (unsigned char led) {
LED_Off(led);
}
/*----------------------------------------------------------------------------
* Function 'signal_func' called from multiple threads
*---------------------------------------------------------------------------*/
void signal_func (osThreadId tid) {
osSignalSet(tid_clock, 0x0100); /* set signal to clock thread */
osDelay(500); /* delay 500ms */
osSignalSet(tid_clock, 0x0100); /* set signal to clock thread */
osDelay(500); /* delay 500ms */
osSignalSet(tid, 0x0001); /* set signal to thread 'thread' */
osDelay(500); /* delay 500ms */
}
/*----------------------------------------------------------------------------
* Thread 1 'phaseA': Phase A output
*---------------------------------------------------------------------------*/
void phaseA (void const *argument) {
for (;;) {
osSignalWait(0x0001, osWaitForever); /* wait for an event flag 0x0001 */
Switch_On (LED_A);
signal_func(tid_phaseB); /* call common signal function */
Switch_Off(LED_A);
}
}
/*----------------------------------------------------------------------------
* Thread 2 'phaseB': Phase B output
*---------------------------------------------------------------------------*/
void phaseB (void const *argument) {
for (;;) {
osSignalWait(0x0001, osWaitForever); /* wait for an event flag 0x0001 */
Switch_On (LED_B);
signal_func(tid_phaseC); /* call common signal function */
Switch_Off(LED_B);
}
}
/*----------------------------------------------------------------------------
* Thread 3 'phaseC': Phase C output
*---------------------------------------------------------------------------*/
void phaseC (void const *argument) {
for (;;) {
osSignalWait(0x0001, osWaitForever); /* wait for an event flag 0x0001 */
Switch_On (LED_C);
signal_func(tid_phaseD); /* call common signal function */
Switch_Off(LED_C);
}
}
/*----------------------------------------------------------------------------
* Thread 4 'phaseD': Phase D output
*---------------------------------------------------------------------------*/
void phaseD (void const *argument) {
for (;;) {
osSignalWait(0x0001, osWaitForever); /* wait for an event flag 0x0001 */
Switch_On (LED_D);
signal_func(tid_phaseA); /* call common signal function */
Switch_Off(LED_D);
}
}
/*----------------------------------------------------------------------------
* Thread 5 'clock': Signal Clock
*---------------------------------------------------------------------------*/
void clock (void const *argument) {
for (;;) {
osSignalWait(0x0100, osWaitForever); /* wait for an event flag 0x0100 */
Switch_On (LED_CLK);
osDelay(80); /* delay 80ms */
Switch_Off(LED_CLK);
}
}
osThreadDef(phaseA, osPriorityNormal, 1, 0);
osThreadDef(phaseB, osPriorityNormal, 1, 0);
osThreadDef(phaseC, osPriorityNormal, 1, 0);
osThreadDef(phaseD, osPriorityNormal, 1, 0);
osThreadDef(clock, osPriorityNormal, 1, 0);
/*----------------------------------------------------------------------------
* Main: Initialize and start RTX Kernel
*---------------------------------------------------------------------------*/
int main (void) {
LED_Initialize(); /* Initialize the LEDs */
tid_phaseA = osThreadCreate(osThread(phaseA), NULL);
tid_phaseB = osThreadCreate(osThread(phaseB), NULL);
tid_phaseC = osThreadCreate(osThread(phaseC), NULL);
tid_phaseD = osThreadCreate(osThread(phaseD), NULL);
tid_clock = osThreadCreate(osThread(clock), NULL);
osSignalSet(tid_phaseA, 0x0001); /* set signal to phaseA thread */
osDelay(osWaitForever);
while(1);
}