When defining portREMOVE_STATIC_QUALIFIER to allow debugger access to RTOS variables, it allows uninitialised variables to be used, which in our case, caused a DABORT. The problem is that when portREMOVE_STATIC_QUALIFIER is defined, it removes that static keyword to the variables at the top of croutine.c and tasks.c. The static keyword forces these variables to be initialised to zero, removing this allows the variables to be left uninitialised, although the code relies on them being zero at start-up. Obvious fix is to add = 0 to each of the variables when portREMOVE_STATIC_QUALIFIER is defined. I’ve tested this using Rowley Crossworks 1.7, up to date freeRTOS, and LPC2388.
The only port layers that define portREMOVE_STATIC_QUALIFIER, and have therefore been tested with portREMOVE_STATIC_QUALIFIER, are the three that use MPLAB (PIC18, PIC24/dsPIC and PIC32). However, variables should be explicitly initialised at the point of declaration as a matter of course, and this is the aim in FreeRTOS. Sometimes it is not possible, if, for example, a variable is inside a structure for packing reasons, or the variable itself is a structure. Some compilers even complain when you try using valid syntax to clear an array to zero. In these cases the variables/structures are (should be) initialised manually in the code itself. Looking at tasks.c, the only variables I can see that are not initialised at the point of declaration are structures of type xList, and these are initialised by the function prvInitialiseTaskLists(), which is called when the first task is created. Which variable in tasks.c is causing you a problem? By removing the static key word you are making what were file scope variables into global variables. In both cases, the variables, if uninitialised, should go in the .bss section, and get set to 0 by the C start up code (before main() is called). Can you look at your start up code to see why that is not happening. Maybe there is an option to set, or, as per the STARTUP_FROM_RESET definition provided by Rowley, a definition that must be made. Regards.
The portREMOVE_STATIC_QUALIFIER macro is in the ARM23xx port, and is used together with threads.js to enable thread level stack traces in Rowley. I’m aware that this functionality is not 100% supported, but it’s really useful for debugging. I’m not 100% sure which variable is causing the crash – the crash report came in from another team with slightly different hardware and I’ve not managed to replicate. The crashing only started happening after I enabled the portREMOVE_STATIC_QUALIFIER define, and goes away when it’s commented out. I will work with the team to try different combinations of setting variables to zero and report what works. Just noticed that our RTOS isn’t as up to date as I thought – we’re on V6.0.4 – so apologies if this issue has already been spotted.
I’ve confirmed that all uninitialised variables are still stored in .bss even with the macro set, and .bss is cleared on bootup. Will investigate further..
I will point out that, by the standard, turning a static variable to a global variable has no effect on its initialization, both static and globals are guaranteed to be 0 initialized if not otherwise initialized. The only difference that should happen is a global has its name published, and references to it in other modules will refer to that variable. One thing to look at, is remove the portREMOVE_STATIC_QUALIFIER and check your linker map to see if something else in a library is defining a variable with the same name as one of the variables that FreeRTOS defines and makes global with portREMOVE_STATIC_QUALIFIER set.
Looking at the map files from crossworks, with the macro set, the global variables go in the COMMON section rather than .bss. However, crossworks makes things confusing since COMMON lives in a memory area also called .bss – I’m not 100% if the crt0.s start up code erases just .bss section, or the entire .bss memory area. However – I agree that all un-initialised variables are then initialised in the code before use, so this shouldn’t be a problem. The team that found the problem have re-tested and still get the crash only when the #define is set – unfortunately they’re not too familiar with the RTOS, and I’ve not been able to replicate the issue (it only happens with US CDMA modems which I cant test in UK).. For now we will take the #define out, and only use it when needed. So, I would probably call as not a freeRTOS bug for now – if I get any more info I’ll update this post. Thanks for the help!
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.