FreeRTOS maximum used priority is unreasonably big, not proceeding

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FreeRTOS maximum used priority is unreasonably big, not proceeding

3,396 Views
Keith4DSmith
Contributor V

The problem is the Segger debug session reports "FreeRTOS maximum used priority is unreasonably big, not proceeding" and the debug session stops.
When the debug session stops, the debugger is configured to let the application run.
When I 'attach' to the application it has run properly. The application is not hung.
This appears to be a problem with the debug session.

This is a report of a problem that seems to have persisted for a couple of years.

Below are links to prior reports of this issue.

https://community.nxp.com/thread/457049 - Aug 2017

https://forum.segger.com/index.php/Thread/4704-ABANDONED-FreeRTOS-plugin-under-Eclipse-crash/ - Dec 2017

https://github.com/espressif/openocd-esp32/issues/7  - Mar 2017

I have been able to solve this problem using the information at this link, https://community.nxp.com/thread/440321

My environment is:

Segger J-Link Pro, Version 6.44
MCUXpresso 10.3.1
Target MCU: MK22FN1M0Axxx12
RTOS: Amazon FreeRTOS 10.0.1
Microsoft Windows 7

The default setting for configUSE_PORT_OPTIMISED_TASK_SELECTION is 1, thus FreeRTOS uses the 'ported' code to select the next task.

Using RTOS Plugin: GDBServer/RTOSPlugin_FreeRTOS


The error message is found in this version of OpenOCD code.
http://openocd.org/doc-release/doxygen/FreeRTOS_8c_source.html

In the OpenOCD code, the FreeRTOS OpenOCD variable uxTopUsedPriority is part of the test that generates the error.

From the Segger J-Link debug console is the following:

Loading RTOS plugin: GDBServer/RTOSPlugin_FreeRTOS...
RTOS plugin (API v1.0) loaded successfully
RTOS plugin initialized successfully.
Received symbol: pxCurrentTCB (0x20007FA0)
Received symbol: pxReadyTasksLists (0x20007FA4)
Received symbol: xDelayedTaskList1 (0x200080E4)
Received symbol: xDelayedTaskList2 (0x200080F8)
Received symbol: pxDelayedTaskList (0x2000810C)
Received symbol: pxOverflowDelayedTaskList (0x20008110)
Received symbol: xPendingReadyList (0x20008114)
Received symbol: xTasksWaitingTermination (0x20008128)
Received symbol: xSuspendedTaskList (0x20008140)
Received symbol: uxCurrentNumberOfTasks (0x20008154)
Received symbol: uxTopUsedPriority (0x00000000)
Received symbol: uxTopReadyPriority (0x2000815C)
Received symbol: vPortEnableVFP (0x000500D8)
Received symbol: FreeRTOSDebugConfig (0x00000000)
All mandatory symbols successfully loaded.

Notice that uxTopUsedPriority is zero.
    Also FreeRTOSDebugConfig is zero, but don't know if it relates to any issue.

The list of symbols above is used in the OpenOCD code referenced above.
[I don't know if Segger is using OpenOCD, but the correlation with OpenOCD is interesting.]

The solution shown above (/thread/440321) states that one should add the following code, along with updates to FreeRTOS_Config.h.

   int uxTopUsedPriority=configMAX_PRIORITIES; // Probably should be added to tasks.c

The error occurs in the macro prvAddTaskToReadyList() in tasks.c of FreeRTOS.
The instruction that generates the error message is:

   STR R3, [R2,#0]   R3 = 0x85,  R2 = 0x2000815c = &uxTopReadyPriority

The value of (R3 + 1) is the value reported with the error message.

/*-----------------------------------------------------------*/
/*
 * Place the task represented by pxTCB into the appropriate ready list for
 * the task.  It is inserted at the end of the list.
 */
#define prvAddTaskToReadyList( pxTCB )                \
 traceMOVED_TASK_TO_READY_STATE( pxTCB );              \
 taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );            \
 vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
 tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
/*-----------------------------------------------------------*/

This macro has successively created the first and second threads in my application. Tmr Svc and Idle task are also created.

I'm not sure who is responsible for fixing this problem, FreeRTOS, Segger, or NXP.

I'll start with NXP as they consolidate FreeRTOS and Segger.

Hope you find this useful.

Tags (2)
0 Kudos
6 Replies

2,717 Views
BlackNight
NXP Employee
NXP Employee

Hi Keith (and Richard),

there are multiple problems here in my view:

a) it is possible that newer compilers can optimize variables, thus breaking ability to debug with Kernel Awareness. -Lto (Link Time Optimizer) is just such a thing

b) Received symbol: uxTopUsedPriority (0x00000000)

  indiacates that this variable has been optimized out by the linker (dead-stripping), so probably the SEGGER Plugin should check that case.

I have solved this (and other similar problems) with dedicated code preventing the linker to optimize things if they are needed for debugging. For example in the following way:

void vPortStartFirstTask(void) {
#if configUSE_TOP_USED_PRIORITY || configLTO_HELPER
  /* only needed for openOCD or Segger FreeRTOS thread awareness. It needs the symbol uxTopUsedPriority present after linking */
  {
    extern volatile const int uxTopUsedPriority;
    __attribute__((__unused__)) volatile uint8_t dummy_value_for_openocd;
    dummy_value_for_openocd = uxTopUsedPriority;
  }
#endif

You can search for configUSE_TOP_USED_PRIORITY or configLTO_HELPER the FreeRTOS port available on McuOnEclipseLibrary/lib/FreeRTOS at master · ErichStyger/McuOnEclipseLibrary · GitHub  to get an idea. The good news is that I saw recent commits in the FreeRTOS kernel to deal with compiler and linker optimization for post 10.2.0 release. Until then, the above workarounds should do it.

I hope this helps,

Erich

2,717 Views
Keith4DSmith
Contributor V

Thank you Erich.

Ah. The variable uxTopUsedPriority and FreeRTOSDebugConfig do not exist in FreeRTOS 10.0.1, thus the problem.

I will look at your 10.2.0 of FreeRTOS and keep alert for a post 10.2.0 version from NXP.

It looks like FreeRTOS should expose a version number variable in the list of mandatory variables so the debugging tools can either warn 'version not supported' or adapt to the discovered version.

Keith Smith

0 Kudos

2,717 Views
BlackNight
NXP Employee
NXP Employee

Hi Keith,

FreeRTOS includes version number information in task.h:

#define tskKERNEL_VERSION_NUMBER "V10.1.1"
#define tskKERNEL_VERSION_MAJOR 10
#define tskKERNEL_VERSION_MINOR 1
#define tskKERNEL_VERSION_BUILD 1

But these are defines and usually do not end up in the binary, so the debugger has no chance to read that information.

That's why you will find the freertos_tasks_c_addition.h present in the FreeRTOS FreeRTOS:

McuOnEclipseLibrary/freertos_tasks_c_additions.h at master · ErichStyger/McuOnEclipseLibrary · GitHu... 

It contains a struct with all the information needed, including the kernel version. The NXP LPC-Link2/LinkServer does in fact read that information, but the SEGGER J-Link stub does not (at least not from what I can tell, so it would be able to have all the information). The FreeRTOS kernel provides all the mechanisms to provide that information to the debuggers, but it seems only the NXP port (MCUXpresso SDK) takes advantage of that.

I hope this helps,

Erich

0 Kudos

2,717 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Thank you for your report, we'll consult SEGGER.

Regards,

MCUXpresso IDE Support

0 Kudos

2,717 Views
FreeRTOS_org
Contributor IV

I assume this is because you have configUSE_PORT_OPTIMISED_TASK_SELECTION set to 1.  As you call that out I guess you had that thought too.  When configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 the variable being read by the debugger is actually used as a bitmap so it is not interpreted correctly by the debugger - the optimization being that the highest priority ready task can be obtained using a single count leading zeros assembly instruction.  If you set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 then the single asm instruction is replaced by a sequence of C code, so less efficient, but it should enable the debugger to interpret the variable properly as it is now a value rather than a bitmap.

0 Kudos

2,717 Views
Keith4DSmith
Contributor V

Yes, configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 as this is how FreeRTOS is shipped with the NXP SDK.

Setting configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 corrects the problem, but I consider this a workaround, not the solution.

Having set configUSE_PORT_OPTIMISED_TASK_SELECTION to 1 works much of the time, but now I have to change to 0 in order to debug this particular application. I am not the only developer who has encountered this problem.

Also, the code worked correctly to create the first two threads of my application.

Yes, the CLZ instruction is used when configUSE_PORT_OPTIMISED_TASK_SELECTION=1, but the instruction that is being executed when the debugger fails is not CLZ, but STR.

The priority bit list is 0x46, well within the 32-bit limit when setting configUSE_PORT_OPTIMISED_TASK_SELECTION=1.

The error message is output in the Segger debug console, not by FreeRTOS (The error string appears in OpenOCD code). Thus the debugger is raising the error, not FreeRTOS.

[Back in 2015, the lack of uxTopUsedPriority in FreeRTOS required an update to OpenOCD.

https://sourceforge.net/p/openocd/mailman/message/33274231/  ]

Short of paring down my application to a tiny reproducible test case, is there any additional steps I can take to solve this problem?

0 Kudos