赞
踩
一、信号
RTX支持每个线程多达16个信号标志。这些信号存储在线程控制块中。可以暂停一个线程的执行,直到系统中另一个线程设置了特定的信号标志或一组信号标志。
osEvent osSignalWait ( int32_t signals,uint32_t millisec);
值为0xFFFF时,定义一个无限超时时间。
如果在调用osSignalWait时将signals变量设置为零,那么设置任何标志都会导致线程继续执行。你可以通过读取oseven .value.signals的返回值来查看设置了哪个标志。
任何线程都可以在任何其他线程上设置或清除信号。
- int32_t osSignalSet ( osThreadId thread_id, int32_t signals);
- int32_t osSignalClear ( osThreadId thread_id, int32_t signals);
线程同步例程main:
- /*----------------------------------------------------------------------------
-
- Designers Guide to the Cortex-M Family
- CMSIS RTOS Signal Example
-
- *----------------------------------------------------------------------------*/
- #include "stm32f10x.h"
- #include <cmsis_os.h>
- #include "Board_LED.h"
-
- void led_Thread1 (void const *argument);
- void led_Thread2 (void const *argument);
-
- osThreadDef(led_Thread1, osPriorityNormal, 1, 0);
- osThreadDef(led_Thread2, osPriorityNormal, 1, 0);
-
- osThreadId T_led_ID1;
- osThreadId T_led_ID2;
-
- void delay (void)
- {
- unsigned int index;
- const unsigned int count = 1000000;
- for(index =0;index<count;index++)
- {
- ;
- }
- }
- /*----------------------------------------------------------------------------
- Flash LED 1 when signaled by the led_Thread2
- *---------------------------------------------------------------------------*/
- void led_Thread1 (void const *argument)
- {
- for (;;)
- {
- osSignalWait (0x00,osWaitForever);
- LED_On(1);
- osSignalWait (0x00,osWaitForever);
- LED_Off(1);
- }
- }
- /*----------------------------------------------------------------------------
- Flash LED two and synchronise the flashing of LED 1 by setting a signal flag
- *---------------------------------------------------------------------------*/
- void led_Thread2 (void const *argument)
- {
- for (;;)
- {
- LED_On(2);
- osSignalSet (T_led_ID1,0x01);
- delay();
- LED_Off(2);
- osSignalSet (T_led_ID1,0x02);
- delay();
- }
- }
-
-
-
-
- /*----------------------------------------------------------------------------
- Start the threads
- *---------------------------------------------------------------------------*/
- int main (void)
- {
- osKernelInitialize (); // initialize CMSIS-RTOS
-
- LED_Initialize();
- T_led_ID2 = osThreadCreate(osThread(led_Thread2), NULL);
- T_led_ID1 = osThreadCreate(osThread(led_Thread1), NULL);
-
- osKernelStart (); // start thread execution
- }
中断
在RTOS应用程序中,最好将中断服务代码设计为RTOS中的一个线程,并为其分配一个高优先级。中断线程的第一行代码应该让它等待一个信号标志。当中断发生时,ISR简单地设置信号标志并终止。这将调度为中断服务的中断线程,然后返回等待下一个信号标志被设置。
例程:
- void Thread3 (void)
- {
- while(1)
- {
- osSignalWait ( isrSignal,waitForever); // Wait for the ISR to trigger an event
- ….. // Handle the interrupt
- } // Loop round and go back sleep
- }
- The actual interrupt source will contain a minimal amount of code.
- void IRQ_Handler (void)
- {
- osSignalSet (tsk3,isrSignal); // Signal Thread 3 with an event
- }
ADC中断例程:
- #include "stm32f10x.h"
- #include "cmsis_os.h"
-
- #include "Board_LED.h"
-
- void led_Thread1 (void const *argument);
- void led_Thread2 (void const *argument);
- void adc_Thread (void const *argument);
- void init_ADC (void);
-
- osThreadDef(led_Thread1, osPriorityNormal, 1, 0);
- osThreadDef(led_Thread2, osPriorityNormal, 1, 0);
- osThreadDef(adc_Thread, osPriorityAboveNormal, 1, 0);
-
- osThreadId T_led_ID1;
- osThreadId T_led_ID2;
- osThreadId T_adc_ID;
-
-
- /*----------------------------------------------------------------------------
- ADC interrupt handler. On Conversion set ADC thread signal
- *---------------------------------------------------------------------------*/
- void ADC1_2_IRQHandler (void)
- {
- osSignalSet(T_adc_ID,0x01);
- ADC1->SR &= ~(1 << 1);
- }
-
- void adc_Thread (void const *argument)
- {
- for (;;)
- {
- osSignalWait(0x01,osWaitForever);
- GPIOB->ODR = ADC1->DR;
- }
- }
-
- void led_Thread1 (void const *argument)
- {
- for (;;)
- {
- osSignalWait(0x01,osWaitForever);
- LED_On(1);
- osSignalWait(0x01,osWaitForever);
- LED_Off(1);
- }
- }
-
- void led_Thread2 (void const *argument)
- {
- for (;;)
- {
- LED_On(2);
- osSignalSet(T_led_ID1,0x01);
- osDelay(500);
- ADC1->CR2 |= (1UL << 22); //Start ADC conversion
- LED_Off(2);
- osSignalSet(T_led_ID1,0x01);
- osDelay(500);
- }
- }
-
- /*----------------------------------------------------------------------------
- Initilise the ADC and create the threads
- *---------------------------------------------------------------------------*/
- int main (void) {
- LED_Initialize();
- init_ADC();
- T_led_ID1 = osThreadCreate(osThread(led_Thread1), NULL);
- T_led_ID2 = osThreadCreate(osThread(led_Thread2), NULL);
- T_adc_ID = osThreadCreate(osThread(adc_Thread), NULL);
-
- for (;;);
- }
-
- /*----------------------------------------------------------------------------
- ADC initilisation code defined as a SVC function. Must be in priviliged mode to enable the NVIC interrupt
- *---------------------------------------------------------------------------*/
- void init_ADC(void){
- RCC->APB2ENR |= ( 1UL << 2); /* enable periperal clock for GPIOA */
- GPIOA->CRL &= ~0x000000F0; /* set PIN1 as analog input */
-
-
- /* Setup and initialize ADC converter */
- RCC->CFGR |= ( 3UL << 14); /* ADC clk = PCLK2 / 8 */
-
- RCC->APB2ENR |= ( 1UL << 9); /* enable periperal clock for ADC1 */
-
- ADC1->SQR1 = 0; /* Regular chn. Sequence length = 1 */
- ADC1->SQR2 = 0; /* Clear register */
- ADC1->SQR3 = (1UL << 0); /* 1. conversion = channel 1 */
- ADC1->SMPR2 = (5UL << 3); /* sample time channel 1 55,5 cyc. */
- ADC1->CR1 = (1UL << 8); /* Scan mode on */
- ADC1->CR2 = (7UL << 17)| /* select SWSTART */
- (1UL << 20) ; /* enable external Trigger */
- ADC1->CR1 |= (1UL << 5); /* enable for EOC Interrupt */
- NVIC->ISER[0] = (1UL << 18); /* To Access the NVIC we must be in priviliged mode */
-
- }
当我们添加了一个线程时,我们还需要增加并发运行线程的数量。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。