rtos.c 6.8 KB

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