Hi all,
we've recently updated to CrossCore Embedded Studio (CCES) v2.10.0. Within that context we've also setup our CCES project from scratch and switched to the most recent FreeRTOS port from Analog Devices (adi-freertos-1.5.0 at that time). We've had issues with the system services and device drivers (SSLDD) before - but has been more or less been fixed by not using the prebuilt ones but compiling and linking them from their sources (as documented in the User Guide for the FreeRTOS port).
When updating the FreeRTOS port we also stumbled across the following lines in the head of adi_osal_ThreadSlotAcquire() in the old version of %RTOS_DIR%\FreeRTOS\portable\CCES\osal\adi_osal_freertos_tls.c:
ADI_OSAL_STATUS adi_osal_ThreadSlotAcquire(ADI_OSAL_TLS_SLOT_KEY *pnThreadSlotKey, ADI_OSAL_TLS_CALLBACK_PTR pTerminateCallbackFunc) { /* FreeRTOS can't currently support destroy callbacks */ // if (NULL != pTerminateCallbackFunc) // { // return ADI_OSAL_OS_ERROR; // } ...
So we've commented out the nullpointer check of pTerminateCallbackFunc for some reason - it must have been a workaround back in April/May 2019 which seemed to do the trick for us. As this seemed a bit hacky to us, we've removed the // so that we have the original code for adi_osal_freertos.c as in the most recent version of the FreeRTOS port. However, not commenting out these few lines makes our application crash.
The following happens:
A red error message appears in the Console view of CCES. This presumably happens because adi_fatal_error is called and there's an automatic breakpoint in CCES which lets the toolchain fetch the content of some registers, interpret it and print out of the message. The execution flow then jumps to fatal_error where the processor is kept in an idle endless loop.
Why is adi_fatal_error called and who calls it? The call stack that I've manually identified and verified is: osal_check (defined as inline function in osal_sync.h) --> _osal_sync_error (defined in osal_error.c) --> adi_fatal_error. _osal_sync_error is only called by osal_check when the argument status does not equal ADI_OSAL_SUCCESS (i.e. an error must have occured).
In _osal_sync_error status is directly handed over to adi_fatal_error alongside with _AFE_G_LibraryError and _AFE_S_OSALBindingError (as seen in the red error message).
Where do we come from? To narrow it further down we've put a breakpoint and checked the RETS register. This lead us to a function call inside of _adi_rtl_get_tls_ptr.
According to the linker output file _adi_rtl_get_tls_ptr is part of libcmt. I've found the sources in %CCES_HOME%\Blackfin\lib\src\libc\osal_tls.c. However modified the source code and re-building the project lead me to the conclusion that the prebuilt C standard libary is linked. This was proved by renaming libcmt.dlb to _libcmt.dlb resulting in a linker error.
Is the prebuilt library compatible with FreeRTOS and the FreeRTOS port? If not, what steps are neccessary to compile and link libcmt from sources?
Did we miss some compiler or linker settings? Did we miss to properly configure FreeRTOS? Are we missing something else or is this a bug and commenting out the nullpointer check in adi_osal_ThreadSlotAcquire is still a valid workaround and should be included in the next release of the FreeRTOS port/ ADI OSAL? Has anybody else faced similar issues?
Edit: Is there a way to replace adi_fatal_error by a custom error handling function similar to an exception handler?
Edit: Which role does the Add-In "SSL/DD Add-in (Build ID: 1.0.0)" play here (if any)? It is not installes by default - is it of relevance to this problem?
Best regards,
Matthias
Corrected source code location of adi_osal_ThreadSlotAcquire(): adi_osal_freertos_tls.c
[edited by: matthiaswe at 7:53 AM (GMT -4) on 13 Sep 2021]