3

I'm new to RTOS and having some troubles understanding a strange behavior:

I have a STM32 microcontroller running FreeRTOS and an RTC interrupt running, too. The RTC interrupt just updates a volatile uint32_t variable named SystemTime:

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
  UNUSED(hrtc);
  SystemTime++;
}

Additionally, I have another task that runs every 100 mS. It just prints the SystemTime value if it has changed.

static void ToggleLEDThread(void const *argument) {
  (void) argument;
  static uint32_t ost;
  uint32_t tst;

  for (;;) {
#if 0
    tst = SystemTime;
    if (ost != tst) {
      xprintf("<%d>\n", tst);
      ost = tst;
    }
#else
    if (ost != SystemTime) {
      xprintf("<%d>\n", SystemTime);
      ost = SystemTime;
    }
#endif
    vTaskDelay(100);
  }
}

It works as expected if #if 1 (using a temporary variable), but when #if 0, the code runs ok for some time before it stops printing and after a few seconds starts to print again.

There is another task that prints some other values once a second.

Output when it's working:

V:1139  O:1091
<35>
V:1139  O:1123
<36>
V:1140  O:1154
<37>
V:1140  O:1186
<38>
V:1139  O:1218
<39>
V:1139  O:1249
<40>
V:1139  O:1281
<41>
V:1139  O:1313
<42>
V:1139  O:1344
<43>
V:1139  O:1376
<44>
V:1139  O:1408
<45>
V:1139  O:1439
<46>
V:1140  O:1471
<47>
V:1139  O:1503
<48>
V:1139  O:1535
<49>
V:1139  O:1566
<50>
V:1140  O:1598
<51>
V:1139  O:1630
<52>
V:1139  O:1661

Output when the problem happens:

V:1139  O:1091
<35>
V:1139  O:1123
<36>
V:1140  O:1154
<37>
V:1140  O:1186
<38>
V:1139  O:1218
<39>
V:1139  O:1249
<40>
V:1139  O:1281
<41>
V:1139  O:1313
<42>
V:1139  O:1344
V:1139  O:1376
V:1139  O:1408
V:1139  O:1439
V:1140  O:1471
V:1139  O:1503
V:1139  O:1535
V:1139  O:1566
<50>
V:1140  O:1598
<51>
V:1139  O:1630
<52>
V:1139  O:1661

Any ideas?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Mscaff
  • 31
  • 2
  • The code in both instances looks ok to me from a quick look. Maybe add another line of debug to print the system time every time the task runs. Maybe the problem lies elsewhere and the task is getting blocked and not running every 100ms as you think? – Realtime Rik Jan 26 '17 at 09:42

3 Answers3

1

Use vTaskDelayUntil instead. This will take into account the time wasted sending over UART. SystemTime is a critical section care with that.

jabella
  • 55
  • 6
1
if (ost != SystemTime) {
    xprintf("<%d>\n", SystemTime);
    ost = SystemTime;
}

Here. While you are printing your SystemTimeValue, interrupt occur and your value is incremented. After that you equate a variable ost to modified variable SystemTime. Thats why next round is missing and code does not printing new time value.

Just a guess

HelpingHand
  • 1,294
  • 11
  • 27
Elisey
  • 11
  • 2
-1

Try giving the task that prints SystemTime higher priority than your other task. The #if 0 case I think is the correct implementation because in the other case SystemTime may be modified between checking it and storing it.

stathisv
  • 489
  • 2
  • 7
  • I think it is just the other way around: If setting `#if 0`, the lower code variant will run, which accesses `SystemTime` several times without protection, which may just miss those increments that happen in between. – HelpingHand May 30 '20 at 14:28