|
@@ -0,0 +1,193 @@
|
|
|
+#include "rtos.h"
|
|
|
+#include "stm8s_it.h"
|
|
|
+
|
|
|
+/* Private define ------------------------------------------------------------*/
|
|
|
+#define TIM4_PERIOD (uint8_t)124
|
|
|
+
|
|
|
+/******************************************************************************************
|
|
|
+ * Ïåðåìåííûå ìîäóëÿ
|
|
|
+ */
|
|
|
+static __IO task TaskArray[MAX_TASKS]; // î÷åðåäü çàäà÷
|
|
|
+static __IO uint8_t arrayTail; // "õâîñò" î÷åðåäè
|
|
|
+static __IO uint16_t TimingDelay;
|
|
|
+__IO uint8_t I2C_timeout;
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************
|
|
|
+ * Èíèöèàëèçàöèÿ ÐÒÎÑ, âðåìÿ òèêà - 1 ìñ
|
|
|
+ */
|
|
|
+inline void RTOS_Init()
|
|
|
+{
|
|
|
+ /*
|
|
|
+ TIM4 configuration:
|
|
|
+ - TIM4CLK is set to 16 MHz, the TIM4 Prescaler is equal to 128 so the TIM1 counter
|
|
|
+ clock used is 16 MHz / 128 = 125 000 Hz
|
|
|
+ - With 125 000 Hz we can generate time base:
|
|
|
+ max time base is 2.048 ms if TIM4_PERIOD = 255 --> (255 + 1) / 125000 = 2.048 ms
|
|
|
+ min time base is 0.016 ms if TIM4_PERIOD = 1 --> ( 1 + 1) / 125000 = 0.016 ms
|
|
|
+ - In this example we need to generate a time base equal to 1 ms
|
|
|
+ so TIM4_PERIOD = (0.001 * 125000 - 1) = 124
|
|
|
+ */
|
|
|
+
|
|
|
+ /* Time base configuration. Set the Prescaler value */
|
|
|
+ TIM4->PSCR = (uint8_t)(TIM4_PRESCALER_128);
|
|
|
+ /* Set the Autoreload value */
|
|
|
+ TIM4->ARR = (uint8_t)(TIM4_PERIOD);
|
|
|
+ /* Clear TIM4 update flag */
|
|
|
+ TIM4->SR1 = (uint8_t)(~TIM4_FLAG_UPDATE);
|
|
|
+ /* Enable update interrupt */
|
|
|
+ TIM4->IER |= (uint8_t)TIM4_IT_UPDATE;
|
|
|
+
|
|
|
+ /* enable interrupts */
|
|
|
+ enableInterrupts();
|
|
|
+
|
|
|
+ /* Enable TIM4 */
|
|
|
+ TIM4->CR1 |= (uint8_t)TIM4_CR1_CEN;
|
|
|
+
|
|
|
+ /* "õâîñò" â 0 */
|
|
|
+ arrayTail = 0;
|
|
|
+}
|
|
|
+
|
|
|
+/******************************************************************************************
|
|
|
+ * Äîáàâëåíèå çàäà÷è â ñïèñîê
|
|
|
+ */
|
|
|
+void RTOS_SetTask (void (*taskFunc)(void), uint16_t taskDelay, uint16_t taskPeriod)
|
|
|
+{
|
|
|
+ uint8_t i;
|
|
|
+
|
|
|
+ if(!taskFunc) return;
|
|
|
+
|
|
|
+ for(i = 0; i < arrayTail; i++) // ïîèñê çàäà÷è â òåêóùåì ñïèñêå
|
|
|
+ {
|
|
|
+ if(TaskArray[i].pFunc == taskFunc) // åñëè íàøëè, òî îáíîâëÿåì ïåðåìåííûå
|
|
|
+ {
|
|
|
+ DISABLE_INTERRUPT;
|
|
|
+
|
|
|
+ TaskArray[i].delay = taskDelay;
|
|
|
+ TaskArray[i].period = taskPeriod;
|
|
|
+ TaskArray[i].run = 0;
|
|
|
+
|
|
|
+// RESTORE_INTERRUPT;
|
|
|
+ ENABLE_INTERRUPT;
|
|
|
+ return; // îáíîâèâ, âûõîäèì
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (arrayTail < MAX_TASKS) // åñëè òàêîé çàäà÷è â ñïèñêå íåò
|
|
|
+ { // è åñòü ìåñòî,òî äîáàâëÿåì
|
|
|
+ DISABLE_INTERRUPT;
|
|
|
+
|
|
|
+ TaskArray[arrayTail].pFunc = taskFunc;
|
|
|
+ TaskArray[arrayTail].delay = taskDelay;
|
|
|
+ TaskArray[arrayTail].period = taskPeriod;
|
|
|
+ TaskArray[arrayTail].run = 0;
|
|
|
+
|
|
|
+ arrayTail++; // óâåëè÷èâàåì "õâîñò"
|
|
|
+
|
|
|
+ ENABLE_INTERRUPT;
|
|
|
+ /* ñèãíàëèçàöèÿ ïåðåïîëíåíèÿ áóôåðà çàäà÷ */
|
|
|
+ } else {
|
|
|
+ while(1);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/******************************************************************************************
|
|
|
+ * Óäàëåíèå çàäà÷è èç ñïèñêà
|
|
|
+ */
|
|
|
+void RTOS_DeleteTask (void (*taskFunc)(void))
|
|
|
+{
|
|
|
+ uint8_t i;
|
|
|
+
|
|
|
+ for (i=0; i<arrayTail; i++) // ïðîõîäèì ïî ñïèñêó çàäà÷
|
|
|
+ {
|
|
|
+ if(TaskArray[i].pFunc == taskFunc) // åñëè çàäà÷à â ñïèñêå íàéäåíà
|
|
|
+ {
|
|
|
+
|
|
|
+ DISABLE_INTERRUPT;
|
|
|
+ if(i != (arrayTail - 1)) // ïåðåíîñèì ïîñëåäíþþ çàäà÷ó
|
|
|
+ { // íà ìåñòî óäàëÿåìîé
|
|
|
+ TaskArray[i] = TaskArray[arrayTail - 1];
|
|
|
+ }
|
|
|
+ arrayTail--; // óìåíüøàåì óêàçàòåëü "õâîñòà"
|
|
|
+// RESTORE_INTERRUPT;
|
|
|
+ ENABLE_INTERRUPT;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/******************************************************************************************
|
|
|
+ * Äèñïåò÷åð ÐÒÎÑ, âûçûâàåòñÿ â main
|
|
|
+ */
|
|
|
+
|
|
|
+void RTOS_DispatchTask(void)
|
|
|
+{
|
|
|
+ uint8_t i;
|
|
|
+ void (*function) (void);
|
|
|
+
|
|
|
+ for (i=0; i<arrayTail; i++) // ïðîõîäèì ïî ñïèñêó çàäà÷
|
|
|
+ {
|
|
|
+ if (TaskArray[i].run == 1) // åñëè ôëàã íà âûïîëíåíèå âçâåäåí,
|
|
|
+ { // çàïîìèíàåì çàäà÷ó, ò.ê. âî
|
|
|
+ function = TaskArray[i].pFunc; // âðåìÿ âûïîëíåíèÿ ìîæåò
|
|
|
+ // èçìåíèòüñÿ èíäåêñ
|
|
|
+ if(TaskArray[i].period == 0)
|
|
|
+ { // åñëè ïåðèîä ðàâåí 0
|
|
|
+ RTOS_DeleteTask(TaskArray[i].pFunc); // óäàëÿåì çàäà÷ó èç ñïèñêà,
|
|
|
+ } else {
|
|
|
+ TaskArray[i].run = 0; // èíà÷å ñíèìàåì ôëàã çàïóñêà
|
|
|
+ if(!TaskArray[i].delay) // åñëè çàäà÷à íå èçìåíèëà çàäåðæêó
|
|
|
+ { // çàäàåì åå
|
|
|
+ TaskArray[i].delay = TaskArray[i].period-1;
|
|
|
+ } // çàäà÷à äëÿ ñåáÿ ìîæåò ñäåëàòü ïàóçó
|
|
|
+ }
|
|
|
+ (*function)(); // âûïîëíÿåì çàäà÷ó
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Inserts a delay time.
|
|
|
+ * @param nTime: specifies the delay time length, in milliseconds.
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+void Delay(__IO uint16_t nTime)
|
|
|
+{
|
|
|
+ TimingDelay = nTime;
|
|
|
+ while (TimingDelay != 0) {
|
|
|
+ // çäåñü ìîæíî ñïàòü è æäàòü ïðåðûâàíèå
|
|
|
+ wfi();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief TIM4 Update/Overflow/Trigger Interrupt routine.
|
|
|
+ * @param None
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler,23)
|
|
|
+{
|
|
|
+ /* Cleat Interrupt Pending bit */
|
|
|
+ TIM4->SR1 = (uint8_t)(~(uint8_t)TIM4_IT_UPDATE);
|
|
|
+
|
|
|
+ /* I2C timeout */
|
|
|
+ if (I2C_timeout > 0) {
|
|
|
+ I2C_timeout --;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Decrements the TimingDelay variable */
|
|
|
+ if (TimingDelay > 0) {
|
|
|
+ TimingDelay --;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Òàéìåðíàÿ ñëóæáà ÐÒÎÑ */
|
|
|
+ uint8_t i;
|
|
|
+ for (i=0; i<arrayTail; i++) { // ïðîõîäèì ïî ñïèñêó çàäà÷
|
|
|
+ if (TaskArray[i].delay == 0) { // åñëè âðåìÿ äî âûïîëíåíèÿ èñòåêëî
|
|
|
+ TaskArray[i].run = 1; // âçâîäèì ôëàã çàïóñêà,
|
|
|
+ } else {
|
|
|
+ TaskArray[i].delay--; // èíà÷å óìåíüøàåì âðåìÿ
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|