Sfoglia il codice sorgente

RTX5: update osKernelResume handling (processing past sleep ticks)

Robert Rostohar 4 anni fa
parent
commit
81dd4f2d70
2 ha cambiato i file con 55 aggiunte e 47 eliminazioni
  1. 1 0
      CMSIS/DoxyGen/RTOS2/src/history.txt
  2. 54 47
      CMSIS/RTOS2/RTX/Source/rtx_kernel.c

+ 1 - 0
CMSIS/DoxyGen/RTOS2/src/history.txt

@@ -107,6 +107,7 @@
        - Fixed Round-Robin (timeout value is not reset when switching to higher priority threads).
        - Fixed osThreadJoin (when terminating thread which is waiting to be joined).
        - Enhanced stack overrun checking.
+       - Updated osKernelResume handling (processing past sleep ticks).
        - Updated configuration (Event Recorder).
        - Reorganized and optimized IRQ modules.
       </td>

+ 54 - 47
CMSIS/RTOS2/RTX/Source/rtx_kernel.c

@@ -62,6 +62,31 @@ static void KernelUnblock (void) {
   OS_Tick_Enable();
 }
 
+// Get Kernel sleep time
+static uint32_t GetKernelSleepTime (void) {
+  const os_thread_t *thread;
+  const os_timer_t  *timer;
+  uint32_t           delay;
+
+  delay = osWaitForever;
+
+  // Check Thread Delay list
+  thread = osRtxInfo.thread.delay_list;
+  if (thread != NULL) {
+    delay = thread->delay;
+  }
+
+  // Check Active Timer list
+  timer = osRtxInfo.timer.list;
+  if (timer != NULL) {
+    if (timer->tick < delay) {
+      delay = timer->tick;
+    }
+  }
+
+  return delay;
+}
+
 
 //  ==== Service Calls ====
 
@@ -346,9 +371,7 @@ static int32_t svcRtxKernelRestoreLock (int32_t lock) {
 /// Suspend the RTOS Kernel scheduler.
 /// \note API identical to osKernelSuspend
 static uint32_t svcRtxKernelSuspend (void) {
-  const os_thread_t *thread;
-  const os_timer_t  *timer;
-  uint32_t           delay;
+  uint32_t delay;
 
   if (osRtxInfo.kernel.state != osRtxKernelRunning) {
     EvrRtxKernelError(osRtxErrorKernelNotRunning);
@@ -358,24 +381,10 @@ static uint32_t svcRtxKernelSuspend (void) {
 
   KernelBlock();
 
-  delay = osWaitForever;
-
-  // Check Thread Delay list
-  thread = osRtxInfo.thread.delay_list;
-  if (thread != NULL) {
-    delay = thread->delay;
-  }
-
-  // Check Active Timer list
-  timer = osRtxInfo.timer.list;
-  if (timer != NULL) {
-    if (timer->tick < delay) {
-      delay = timer->tick;
-    }
-  }
-
   osRtxInfo.kernel.state = osRtxKernelSuspended;
 
+  delay = GetKernelSleepTime();
+
   EvrRtxKernelSuspended(delay);
 
   return delay;
@@ -387,7 +396,7 @@ static void svcRtxKernelResume (uint32_t sleep_ticks) {
   os_thread_t *thread;
   os_timer_t  *timer;
   uint32_t     delay;
-  uint32_t     ticks;
+  uint32_t     ticks, kernel_tick;
 
   if (osRtxInfo.kernel.state != osRtxKernelSuspended) {
     EvrRtxKernelResumed();
@@ -395,40 +404,38 @@ static void svcRtxKernelResume (uint32_t sleep_ticks) {
     return;
   }
 
-  osRtxInfo.kernel.tick += sleep_ticks;
+  delay = GetKernelSleepTime();
+  if (sleep_ticks >= delay) {
+    ticks = delay - 1U;
+  } else {
+    ticks = sleep_ticks;
+  }
 
-  // Process Thread Delay list
+  // Update Thread Delay sleep ticks
   thread = osRtxInfo.thread.delay_list;
   if (thread != NULL) {
-    delay = sleep_ticks;
-    do {
-      if (delay >= thread->delay) {
-        delay -= thread->delay;
-        thread->delay = 1U;
-        osRtxThreadDelayTick();
-        thread = osRtxInfo.thread.delay_list;
-      } else {
-        thread->delay -= delay;
-        delay = 0U;
-      }
-    } while ((thread != NULL) && (delay != 0U));
+    thread->delay -= ticks;
   }
 
-  // Process Active Timer list
+  // Update Timer sleep ticks
   timer = osRtxInfo.timer.list;
   if (timer != NULL) {
-    ticks = sleep_ticks;
-    do {
-      if (ticks >= timer->tick) {
-        ticks -= timer->tick;
-        timer->tick = 1U;
-        osRtxInfo.timer.tick();
-        timer = osRtxInfo.timer.list;
-      } else {
-        timer->tick -= ticks;
-        ticks = 0U;
-      }
-    } while ((timer != NULL) && (ticks != 0U));
+    timer->tick -= ticks;
+  }
+
+  kernel_tick = osRtxInfo.kernel.tick + sleep_ticks;
+  osRtxInfo.kernel.tick += ticks;
+
+  while (osRtxInfo.kernel.tick != kernel_tick) {
+    osRtxInfo.kernel.tick++;
+
+    // Process Thread Delays
+    osRtxThreadDelayTick();
+
+    // Process Timers
+    if (osRtxInfo.timer.tick != NULL) {
+      osRtxInfo.timer.tick();
+    }
   }
 
   osRtxInfo.kernel.state = osRtxKernelRunning;