当前位置:   article > 正文

RTX操作系统教程[02]_rtx教程

rtx教程

一、信号

RTX支持每个线程多达16个信号标志。这些信号存储在线程控制块中。可以暂停一个线程的执行,直到系统中另一个线程设置了特定的信号标志或一组信号标志。

osEvent osSignalWait ( int32_t signals,uint32_t millisec);

值为0xFFFF时,定义一个无限超时时间。

如果在调用osSignalWait时将signals变量设置为零,那么设置任何标志都会导致线程继续执行。你可以通过读取oseven .value.signals的返回值来查看设置了哪个标志。

任何线程都可以在任何其他线程上设置或清除信号。

  1. int32_t osSignalSet ( osThreadId thread_id, int32_t signals);
  2. int32_t osSignalClear ( osThreadId thread_id, int32_t signals);

线程同步例程main:

  1. /*----------------------------------------------------------------------------
  2. Designers Guide to the Cortex-M Family
  3. CMSIS RTOS Signal Example
  4. *----------------------------------------------------------------------------*/
  5. #include "stm32f10x.h"
  6. #include <cmsis_os.h>
  7. #include "Board_LED.h"
  8. void led_Thread1 (void const *argument);
  9. void led_Thread2 (void const *argument);
  10. osThreadDef(led_Thread1, osPriorityNormal, 1, 0);
  11. osThreadDef(led_Thread2, osPriorityNormal, 1, 0);
  12. osThreadId T_led_ID1;
  13. osThreadId T_led_ID2;
  14. void delay (void)
  15. {
  16. unsigned int index;
  17. const unsigned int count = 1000000;
  18. for(index =0;index<count;index++)
  19. {
  20. ;
  21. }
  22. }
  23. /*----------------------------------------------------------------------------
  24. Flash LED 1 when signaled by the led_Thread2
  25. *---------------------------------------------------------------------------*/
  26. void led_Thread1 (void const *argument)
  27. {
  28. for (;;)
  29. {
  30. osSignalWait (0x00,osWaitForever);
  31. LED_On(1);
  32. osSignalWait (0x00,osWaitForever);
  33. LED_Off(1);
  34. }
  35. }
  36. /*----------------------------------------------------------------------------
  37. Flash LED two and synchronise the flashing of LED 1 by setting a signal flag
  38. *---------------------------------------------------------------------------*/
  39. void led_Thread2 (void const *argument)
  40. {
  41. for (;;)
  42. {
  43. LED_On(2);
  44. osSignalSet (T_led_ID1,0x01);
  45. delay();
  46. LED_Off(2);
  47. osSignalSet (T_led_ID1,0x02);
  48. delay();
  49. }
  50. }
  51. /*----------------------------------------------------------------------------
  52. Start the threads
  53. *---------------------------------------------------------------------------*/
  54. int main (void)
  55. {
  56. osKernelInitialize (); // initialize CMSIS-RTOS
  57. LED_Initialize();
  58. T_led_ID2 = osThreadCreate(osThread(led_Thread2), NULL);
  59. T_led_ID1 = osThreadCreate(osThread(led_Thread1), NULL);
  60. osKernelStart (); // start thread execution
  61. }

中断

在RTOS应用程序中,最好将中断服务代码设计为RTOS中的一个线程,并为其分配一个高优先级。中断线程的第一行代码应该让它等待一个信号标志。当中断发生时,ISR简单地设置信号标志并终止。这将调度为中断服务的中断线程,然后返回等待下一个信号标志被设置。

例程:

  1. void Thread3 (void)
  2. {
  3. while(1)
  4. {
  5. osSignalWait ( isrSignal,waitForever); // Wait for the ISR to trigger an event
  6. ….. // Handle the interrupt
  7. } // Loop round and go back sleep
  8. }
  9. The actual interrupt source will contain a minimal amount of code.
  10. void IRQ_Handler (void)
  11. {
  12. osSignalSet (tsk3,isrSignal); // Signal Thread 3 with an event
  13. }

ADC中断例程:

  1. #include "stm32f10x.h"
  2. #include "cmsis_os.h"
  3. #include "Board_LED.h"
  4. void led_Thread1 (void const *argument);
  5. void led_Thread2 (void const *argument);
  6. void adc_Thread (void const *argument);
  7. void init_ADC (void);
  8. osThreadDef(led_Thread1, osPriorityNormal, 1, 0);
  9. osThreadDef(led_Thread2, osPriorityNormal, 1, 0);
  10. osThreadDef(adc_Thread, osPriorityAboveNormal, 1, 0);
  11. osThreadId T_led_ID1;
  12. osThreadId T_led_ID2;
  13. osThreadId T_adc_ID;
  14. /*----------------------------------------------------------------------------
  15. ADC interrupt handler. On Conversion set ADC thread signal
  16. *---------------------------------------------------------------------------*/
  17. void ADC1_2_IRQHandler (void)
  18. {
  19. osSignalSet(T_adc_ID,0x01);
  20. ADC1->SR &= ~(1 << 1);
  21. }
  22. void adc_Thread (void const *argument)
  23. {
  24. for (;;)
  25. {
  26. osSignalWait(0x01,osWaitForever);
  27. GPIOB->ODR = ADC1->DR;
  28. }
  29. }
  30. void led_Thread1 (void const *argument)
  31. {
  32. for (;;)
  33. {
  34. osSignalWait(0x01,osWaitForever);
  35. LED_On(1);
  36. osSignalWait(0x01,osWaitForever);
  37. LED_Off(1);
  38. }
  39. }
  40. void led_Thread2 (void const *argument)
  41. {
  42. for (;;)
  43. {
  44. LED_On(2);
  45. osSignalSet(T_led_ID1,0x01);
  46. osDelay(500);
  47. ADC1->CR2 |= (1UL << 22); //Start ADC conversion
  48. LED_Off(2);
  49. osSignalSet(T_led_ID1,0x01);
  50. osDelay(500);
  51. }
  52. }
  53. /*----------------------------------------------------------------------------
  54. Initilise the ADC and create the threads
  55. *---------------------------------------------------------------------------*/
  56. int main (void) {
  57. LED_Initialize();
  58. init_ADC();
  59. T_led_ID1 = osThreadCreate(osThread(led_Thread1), NULL);
  60. T_led_ID2 = osThreadCreate(osThread(led_Thread2), NULL);
  61. T_adc_ID = osThreadCreate(osThread(adc_Thread), NULL);
  62. for (;;);
  63. }
  64. /*----------------------------------------------------------------------------
  65. ADC initilisation code defined as a SVC function. Must be in priviliged mode to enable the NVIC interrupt
  66. *---------------------------------------------------------------------------*/
  67. void init_ADC(void){
  68. RCC->APB2ENR |= ( 1UL << 2); /* enable periperal clock for GPIOA */
  69. GPIOA->CRL &= ~0x000000F0; /* set PIN1 as analog input */
  70. /* Setup and initialize ADC converter */
  71. RCC->CFGR |= ( 3UL << 14); /* ADC clk = PCLK2 / 8 */
  72. RCC->APB2ENR |= ( 1UL << 9); /* enable periperal clock for ADC1 */
  73. ADC1->SQR1 = 0; /* Regular chn. Sequence length = 1 */
  74. ADC1->SQR2 = 0; /* Clear register */
  75. ADC1->SQR3 = (1UL << 0); /* 1. conversion = channel 1 */
  76. ADC1->SMPR2 = (5UL << 3); /* sample time channel 1 55,5 cyc. */
  77. ADC1->CR1 = (1UL << 8); /* Scan mode on */
  78. ADC1->CR2 = (7UL << 17)| /* select SWSTART */
  79. (1UL << 20) ; /* enable external Trigger */
  80. ADC1->CR1 |= (1UL << 5); /* enable for EOC Interrupt */
  81. NVIC->ISER[0] = (1UL << 18); /* To Access the NVIC we must be in priviliged mode */
  82. }

当我们添加了一个线程时,我们还需要增加并发运行线程的数量。

 

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/397952
推荐阅读
相关标签
  

闽ICP备14008679号