rtos.c 7.1 KB

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