rtos.c 6.9 KB

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