FreeRTOS thread support - mis-aligned errors reading the TCB

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • FreeRTOS thread support - mis-aligned errors reading the TCB

      Hello,

      We are having issues using the JLink with thread-aware FreeRTOS debugging. When stopping in the debugger with a newer SDK and FreeRTOS version (9.0.0 versus 8.0.2) are are getting misaligned reads and errors reading the TCB as follows:


      WARNING: Mis-aligned memory read: Address: 0x0000000B, NumBytes: 4, Alignment: 4 (Word-aligned)
      WARNING: Failed to read memory @ address 0x0917512C
      ERROR: Error reading thread name in FreeRTOS task control block.


      Looking through the differences in the GDBPlugin logs we see the following:

      On the earlier version it reads several areas until it gets to the ulTotalRunTime symbol, and then reads from <xTasksWaitingTermination+12> and all is well:


      Working Case: FreeRTOS 8.0.2


      02-00000000-00-00011004-00A2: TD8DE000 011:005 JLINK_ReadMemU32(0x001137B4, 0x0001 Items, ...) -- Read from C cache (4 bytes @ 0x001137B4) - Data: 44 80 1D 01 returns 1 (0000ms, 0376ms total)
      (gdb) p/x &ulTotalRunTime
      $1 = 0x1137b4
      02-00000000-00-00011004-00A2: TD8DE000 011:005 JLINK_ReadMemU32(0x001137C4, 0x0001 Items, ...) -- Read from C cache (4 bytes @ 0x001137C4) - Data: C0 37 11 00 returns 1 (0000ms, 0376ms total)
      (gdb) x/x 0x001137C4
      0x1137c4 <xTasksWaitingTermination+12>: 0x001137c0
      02-00000000-00-00011004-00A2: TD8DE000 011:005 JLINK_ReadMemU32(0x001137CC, 0x0001 Items, ...) -- Read from C cache (4 bytes @ 0x001137CC) - Data: F8 37 11 00 returns 1 (0000ms, 0376ms total)
      (gdb) x/x 0x001137CC
      0x1137cc <pxDelayedTaskList>: 0x001137f8
      02-00000000-00-00011006-0120: TD8DE000 011:005 JLINK_ReadMem (0x0011382C, 0x0020 Bytes, ...) -- CPU_ReadMem(128 bytes @ 0x00113800) -- Updating C cache (128 bytes @ 0x00113800) -- Read from C cache (32 bytes @ 0x0011382C) - Data: 0C 38 11 00 00 00 00 00 38 38 11 00 01 00 00 00 ... returns 0x00 (0002ms, 0378ms total)
      (gdb) x/x 0x0011382C
      0x11382c <pxOverflowDelayedTaskList>: 0x0011380c
      02-00000000-00-00011006-00A2: TD8DE000 011:007 JLINK_ReadMemU32(0x00113824, 0x0001 Items, ...) -- Read from C cache (4 bytes @ 0x00113824) - Data: 00 00 00 00 returns 1 (0000ms, 0378ms total)
      (gdb) x/x 0x00113824
      0x113824 <xYieldPending>: 0x00000000



      On the newer version it reads several areas until it gets to the ulTotalRunTime symbol, and then reads from <xTasksWaitingTermination+8> and dies:


      FreeRTOS 9.0.0


      02-00000000-00-00010766-00F4: T320D000 010:766 JLINK_ReadMemU32(0x00113104, 0x0001 Items, ...) -- CPU_ReadMem(64 bytes @ 0x00113100) -- Updating C cache (64 bytes @ 0x00113100) -- Read from C cache (4 bytes @ 0x00113104) - Data: 00 00 00 00 returns 1 (0001ms, 0391ms total)

      02-00000000-00-00010766-00A2: T320D000 010:767 JLINK_ReadMemU32(0x00113118, 0x0001 Items, ...) -- Read from C cache (4 bytes @ 0x00113118) - Data: EF AF D0 00 returns 1 (0000ms, 0391ms total)
      (gdb) p/x &ulTotalRunTime
      $1 = 0x113118

      02-00000000-00-00010766-00A2: T320D000 010:767 JLINK_ReadMemU32(0x00113128, 0x0001 Items, ...) -- Read from C cache (4 bytes @ 0x00113128) - Data: FF FF FF FF returns 1 (0000ms, 0391ms total)
      (gdb) x/x 0x00113128
      0x113128 <xTasksWaitingTermination+8>: 0xffffffff
      (gdb)
      0x11312c <xTasksWaitingTermination+12>: 0x00113128
      Now we die and stop reading further...

      03-00000000-00-00010766-0060: WARNING: Mis-aligned memory read: Address: 0x0000000B, NumBytes: 4, Alignment: 4 (Word-aligned)

      02-00000000-00-00010766-0096: T320D000 010:767 JLINK_ReadMemU32(0x0000000B, 0x0001 Items, ...)Mis-aligned memory read: Address: 0x0000000B, NumBytes: 4, Alignment: 4 (Word-aligned)
      02-00000000-00-00010767-00B9: ***** Mis-aligned memory read: Address: 0x0000000B, NumBytes: 4, Alignment: 4 (Word-aligned) -- CPU_ReadMem(4 bytes @ 0x0000000B) - Data: F8 50 17 09 returns 1 (0001ms, 0392ms total)
      02-00000000-00-00010768-00C5: T320D000 010:768 JLINK_ReadMem (0x0917512C, 0x0020 Bytes, ...) -- CPU_ReadMem(32 bytes @ 0x0917512C) - Data: AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ... returns 0x01 (0001ms, 0393ms total)
      03-00000000-00-00010768-0034: WARNING: Failed to read memory @ address 0x0917512C

      03-00000000-00-00010768-0041: ERROR: Error reading thread name in FreeRTOS task control block.



      I am at a loss for where to look, and debugging our multi-threaded system is impossible without the debugger support for viewing the state of all threads. Any idea where to start looking for why things may be different between FreeRTOS 8 and 9? I've done all the basics I can think of, looking at differences between structures of the 2 builds, and it all looks well aligned, but I cannot figure out why in the 8.0.2 case it reads from <xTasksWaitingTermination+12> and in the 9.0.0 case it decides to read from <xTasksWaitingTermination+8>
    • configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0.

      I have verified this by modifying tasks.c with bad C code which will fails to compile.

      When I add the bad line to inside the #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) area compiling FreeRTOS fails, when it is added inside the corresponding #else compiling will succeed.
    • OK - After some more googling and trying OpenOCD without success I believe I have found the cause. Breakpoints and showing all threads is working successfully now.

      I did have to make this change to a support function in: freertos/Source/FreeRTOS-openocd.c


      -const int USED uxTopUsedPriority = configMAX_PRIORITIES;
      +const int USED uxTopUsedPriority = configMAX_PRIORITIES - 1;

      Once this change was made everything is working as expected and I am seeing all 20 threads.

      Does this make sense?
    • Hello,

      yes it does. pxReadyTasksLists is an array of lists. The plug-in ran into a problem, because it tried to read beyond the end of the array.
      For the GDB server it is quite difficult to determine the size of the array (it can only query for the start address). uxTopUsedPriority is
      used for that purpose, if it is present. If not, uxTopReadyPriority is used - but this variable only reflects the number of relevant list
      entries, if port optimized task selection is not in use.


      Newer versions of FreeRTOS may provide a FreeRTOSDebugConfig structure. This is a helper for plug-ins to overcome such problems.


      Best regards
      Arne