rtos.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include "rtos.h"
  2. #include "stm8l15x_it.h"
  3. /* Private define ------------------------------------------------------------*/
  4. #define TIM4_PERIOD (uint8_t)124
  5. /******************************************************************************************
  6. * Ïåðåìåííûå ìîäóëÿ
  7. */
  8. static __IO task TaskArray[MAX_TASKS]; // î÷åðåäü çàäà÷
  9. static __IO uint8_t arrayTail; // "õâîñò" î÷åðåäè
  10. static __IO uint16_t TimingDelay;
  11. /******************************************************************************************
  12. * Èíèöèàëèçàöèÿ ÐÒÎÑ, âðåìÿ òèêà - 1 ìñ
  13. */
  14. inline void RTOS_Config()
  15. {
  16. /*
  17. TIM4 configuration:
  18. - TIM4CLK is set to 16 MHz, the TIM4 Prescaler is equal to 128 so the TIM1 counter
  19. clock used is 16 MHz / 128 = 125 000 Hz
  20. - With 125 000 Hz we can generate time base:
  21. max time base is 2.048 ms if TIM4_PERIOD = 255 --> (255 + 1) / 125000 = 2.048 ms
  22. min time base is 0.016 ms if TIM4_PERIOD = 1 --> ( 1 + 1) / 125000 = 0.016 ms
  23. - In this example we need to generate a time base equal to 1 ms
  24. so TIM4_PERIOD = (0.001 * 125000 - 1) = 124
  25. */
  26. /* Enable TIM4 CLK */
  27. CLK_PeripheralClockConfig(CLK_Peripheral_TIM4, ENABLE);
  28. /* Time base configuration */
  29. TIM4_TimeBaseInit(TIM4_Prescaler_128, TIM4_PERIOD);
  30. /* Clear TIM4 update flag */
  31. TIM4_ClearFlag(TIM4_FLAG_Update);
  32. /* Enable update interrupt */
  33. TIM4_ITConfig(TIM4_IT_Update, ENABLE);
  34. /* enable interrupts */
  35. enableInterrupts();
  36. /* Enable TIM4 */
  37. TIM4_Cmd(ENABLE);
  38. /* "õâîñò" â 0 */
  39. arrayTail = 0;
  40. }
  41. /******************************************************************************************
  42. * Äîáàâëåíèå çàäà÷è â ñïèñîê
  43. */
  44. void RTOS_SetTask (void (*taskFunc)(void), uint16_t taskDelay, uint16_t taskPeriod)
  45. {
  46. uint8_t i;
  47. if(!taskFunc) return;
  48. for(i = 0; i < arrayTail; i++) // ïîèñê çàäà÷è â òåêóùåì ñïèñêå
  49. {
  50. if(TaskArray[i].pFunc == taskFunc) // åñëè íàøëè, òî îáíîâëÿåì ïåðåìåííûå
  51. {
  52. DISABLE_INTERRUPT;
  53. TaskArray[i].delay = taskDelay;
  54. TaskArray[i].period = taskPeriod;
  55. TaskArray[i].run = 0;
  56. // RESTORE_INTERRUPT;
  57. ENABLE_INTERRUPT;
  58. return; // îáíîâèâ, âûõîäèì
  59. }
  60. }
  61. if (arrayTail < MAX_TASKS) // åñëè òàêîé çàäà÷è â ñïèñêå íåò
  62. { // è åñòü ìåñòî,òî äîáàâëÿåì
  63. DISABLE_INTERRUPT;
  64. TaskArray[arrayTail].pFunc = taskFunc;
  65. TaskArray[arrayTail].delay = taskDelay;
  66. TaskArray[arrayTail].period = taskPeriod;
  67. TaskArray[arrayTail].run = 0;
  68. arrayTail++; // óâåëè÷èâàåì "õâîñò"
  69. // RESTORE_INTERRUPT;
  70. ENABLE_INTERRUPT;
  71. }
  72. }
  73. /******************************************************************************************
  74. * Óäàëåíèå çàäà÷è èç ñïèñêà
  75. */
  76. void RTOS_DeleteTask (void (*taskFunc)(void))
  77. {
  78. uint8_t i;
  79. for (i=0; i<arrayTail; i++) // ïðîõîäèì ïî ñïèñêó çàäà÷
  80. {
  81. if(TaskArray[i].pFunc == taskFunc) // åñëè çàäà÷à â ñïèñêå íàéäåíà
  82. {
  83. DISABLE_INTERRUPT;
  84. if(i != (arrayTail - 1)) // ïåðåíîñèì ïîñëåäíþþ çàäà÷ó
  85. { // íà ìåñòî óäàëÿåìîé
  86. TaskArray[i] = TaskArray[arrayTail - 1];
  87. }
  88. arrayTail--; // óìåíüøàåì óêàçàòåëü "õâîñòà"
  89. // RESTORE_INTERRUPT;
  90. ENABLE_INTERRUPT;
  91. return;
  92. }
  93. }
  94. }
  95. /******************************************************************************************
  96. * Äèñïåò÷åð ÐÒÎÑ, âûçûâàåòñÿ â main
  97. */
  98. void RTOS_DispatchTask(void)
  99. {
  100. uint8_t i;
  101. void (*function) (void);
  102. for (i=0; i<arrayTail; i++) // ïðîõîäèì ïî ñïèñêó çàäà÷
  103. {
  104. if (TaskArray[i].run == 1) // åñëè ôëàã íà âûïîëíåíèå âçâåäåí,
  105. { // çàïîìèíàåì çàäà÷ó, ò.ê. âî
  106. function = TaskArray[i].pFunc; // âðåìÿ âûïîëíåíèÿ ìîæåò
  107. // èçìåíèòüñÿ èíäåêñ
  108. if(TaskArray[i].period == 0)
  109. { // åñëè ïåðèîä ðàâåí 0
  110. RTOS_DeleteTask(TaskArray[i].pFunc); // óäàëÿåì çàäà÷ó èç ñïèñêà,
  111. } else {
  112. TaskArray[i].run = 0; // èíà÷å ñíèìàåì ôëàã çàïóñêà
  113. if(!TaskArray[i].delay) // åñëè çàäà÷à íå èçìåíèëà çàäåðæêó
  114. { // çàäàåì åå
  115. TaskArray[i].delay = TaskArray[i].period-1;
  116. } // çàäà÷à äëÿ ñåáÿ ìîæåò ñäåëàòü ïàóçó
  117. }
  118. (*function)(); // âûïîëíÿåì çàäà÷ó
  119. }
  120. }
  121. }
  122. /******************************************************************************************
  123. * Òàéìåðíàÿ ñëóæáà ÐÒÎÑ (ïðåðûâàíèå àïïàðàòíîãî òàéìåðà)
  124. */
  125. /*
  126. static void RTOS_Timer(void)
  127. {
  128. uint8_t i;
  129. for (i=0; i<arrayTail; i++) // ïðîõîäèì ïî ñïèñêó çàäà÷
  130. {
  131. if (TaskArray[i].delay == 0) { // åñëè âðåìÿ äî âûïîëíåíèÿ èñòåêëî
  132. TaskArray[i].run = 1; // âçâîäèì ôëàã çàïóñêà,
  133. } else {
  134. TaskArray[i].delay--; // èíà÷å óìåíüøàåì âðåìÿ
  135. }
  136. }
  137. }
  138. */
  139. /**
  140. * @brief Inserts a delay time.
  141. * @param nTime: specifies the delay time length, in milliseconds.
  142. * @retval None
  143. */
  144. void Delay(__IO uint16_t nTime)
  145. {
  146. TimingDelay = nTime;
  147. while (TimingDelay != 0) {
  148. // çäåñü ìîæíî ñïàòü è æäàòü ïðåðûâàíèå
  149. }
  150. }
  151. /**
  152. * @brief Decrements the TimingDelay variable.
  153. * @note This function should be called in the
  154. * TIM2_UPD_OVF_TRG_BRK_USART2_TX_IRQHandler in the stm8l15x_it.c file.
  155. *
  156. * // INTERRUPT_HANDLER(TIM2_UPD_OVF_TRG_BRK_USART2_TX_IRQHandler, 19)
  157. * // {
  158. * // TimingDelay_Decrement();
  159. * // TIM2_ClearITPendingBit(TIM2_IT_Update);
  160. *
  161. * // }
  162. * @param None
  163. * @retval None
  164. */
  165. /*
  166. static void TimingDelay_Decrement(void)
  167. {
  168. if (TimingDelay != 0x00)
  169. {
  170. TimingDelay--;
  171. }
  172. }
  173. */
  174. /**
  175. * @brief TIM4 Update/Overflow/Trigger Interrupt routine.
  176. * @param None
  177. * @retval None
  178. */
  179. INTERRUPT_HANDLER(TIM4_UPD_OVF_TRG_IRQHandler,25)
  180. {
  181. /* In order to detect unexpected events during development,
  182. it is recommended to set a breakpoint on the following instruction.
  183. */
  184. /* Cleat Interrupt Pending bit */
  185. TIM4->SR1 = (uint8_t)(~(uint8_t)TIM4_IT_Update);
  186. /* TimingDelay_Decrement() */
  187. if (TimingDelay > 0) {
  188. TimingDelay --;
  189. }
  190. /* RTOS_Timer() */
  191. uint8_t i;
  192. for (i=0; i<arrayTail; i++) { // ïðîõîäèì ïî ñïèñêó çàäà÷
  193. if (TaskArray[i].delay == 0) { // åñëè âðåìÿ äî âûïîëíåíèÿ èñòåêëî
  194. TaskArray[i].run = 1; // âçâîäèì ôëàã çàïóñêà,
  195. } else {
  196. TaskArray[i].delay--; // èíà÷å óìåíüøàåì âðåìÿ
  197. }
  198. }
  199. }