Browse Source

Added sheduler files.

Vladimir N. Shilov 1 year ago
parent
commit
7e8d4a7153
2 changed files with 251 additions and 0 deletions
  1. 193 0
      lib/rtos.c
  2. 58 0
      lib/rtos.h

+ 193 - 0
lib/rtos.c

@@ -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--;         // èíà÷å óìåíüøàåì âðåìÿ
+      }
+   }
+
+}

+ 58 - 0
lib/rtos.h

@@ -0,0 +1,58 @@
+#pragma once
+#ifndef __RTOS_H
+#define __RTOS_H
+
+/******************************************************************************************
+ * За основу взят планировщик задач с сайта ChipEnable.ru                                 *
+ * http://chipenable.ru/index.php/programming-avr/item/110-planirovschik.html             *
+ *                                                                                        *
+ * Доработал Шибанов Владимир aka KontAr                                                  *
+ * Дата: 26.03.2014                                                                       *
+ *                                                                                        *
+ * Изменения:                                                                             *
+ * - добавлен однократный вызов задачи                                                    *
+ * - добавлено удаление задачи по имени                                                   *
+ * - при повторном добавлении задачи обновляются ее переменные                            *
+ * - добавлен указатель на "хвост" списка                                                 *
+ * - функции РТОС скорректированы с учетом "хвоста"                                       *
+ *                                                                                        *
+ * 18.05.2015, Shilov V.N. <shilow@ukr.net>                                               *
+ * - скрестил с timing_delay от ST                                                        *
+ * - перенёс сюда обработчик прерываний для уменьшения оверхеда                           *
+ *                                                                                        *
+ ******************************************************************************************/
+
+#include "stm8s.h"
+
+// Количество задач
+#define MAX_TASKS	9
+
+#define  ENABLE_INTERRUPT enableInterrupts()
+#define DISABLE_INTERRUPT disableInterrupts()
+
+/**
+ * Структура задачи
+ */
+typedef struct task
+{
+  void (*pFunc) (void); // указатель на функцию
+  uint16_t delay;       // задержка перед первым запуском задачи
+  uint16_t period;      // период запуска задачи
+  uint8_t run;          // флаг готовности задачи к запуску
+} task;
+
+/**
+ * Переменные
+ */
+
+/**
+ * Прототипы фукнций
+ */
+void RTOS_Init (void);
+void RTOS_SetTask (void (*taskFunc)(void), uint16_t taskDelay, uint16_t taskPeriod);
+void RTOS_DeleteTask (void (*taskFunc)(void));
+void RTOS_DispatchTask (void);
+
+void Delay(__IO uint16_t nTime);
+
+#endif /* __RTOS_H */