Other Parts Discussed in Thread: MCU-PLUS-SDK-AM263X
Tool/software:
We found an issue when porting TI example: "uart echo interrupt lld no rtos" to our environment.
- using the MCU-PLUS-SDK-AM263X SDK (9.2.0.56). Compiling source code. Not linking in library.
- compiler flags are the same:
- using arm-none-eabi-gcc and ld for toolchain
- compiler flags: -mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16 -mlittle-endian -mthumb -DSOC_AM263PX -D_DEBUG_=1 -g
- Linker flags: -mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16 -mlittle-endian -mthumb -DSOC_AM263PX -D_DEBUG_=1 -g
This example runs on CCS and the AM263P-CC eval board successfully. But when ported to our environment, unmodified causes the SoC to jump to an unexpected address and eventually generating an "undefined address" interrupt.
The code in question is uart_echo_interrupt_lld.c ln 161.
void UART_lld_writeCompleteCallback(void *args)
{
unlock_mutex(gUartObject[CONFIG_UART_CONSOLE].writeTransferMutex);
return;
}
Mutex_armv7r_asm.S ln 94
// unlock_mutex
unlock_mutex:
mov r1, #0
dmb // Required before releasing protected resource
str r1, [r0] // Unlock mutex
signal_update
bx lr
During uart interrupt UART_lld_writeCompleteCallback calls unlock_mutex. And when stepping into unlock_mutex, the core jumps to a unexpected address during the dmb instruction.
Our developer found the problem and fixed it using .type directive. Here is his comment.
===============================================================
There’s a problem when mixing assembly code with C. Typically, the assembly code is compiled in ARM mode, but the rest of the C code is compiled in Thumb mode. The gist of it is that the wrong instruction is used to call ARM mode from C code. For example, a C function calling “unlock_mutex” (in mcu_plus_sdk_am263x_09_02_00_56\source\kernel\nortos\dpl\r5\Mutex_armv7r_asm.S) get compiled as “bl <unlock_mutex>”, which is wrong; the processor would stay in Thumb mode and start to misinterpret ARM code as Thumb.
However, we found out that curiously, functions in this file do not have the “.type %function” directive declaring them as functions, and other assembly files (ex: PmuP_armv7r_asm.S) have those properly applied to functions. If we add those directives to functions in Mutex_armv7r_asm.S (ex: “.type unlock_mutex, %function”), then the generated code is good (the function call gets compiled to “blx <unlock_mutex>”) and the code works correctly.
Compiler used: arm-none-eabi-gcc (xPack GNU Arm Embedded GCC x86_64) 11.2.1 20220111 with linker arm-none-eabi-ld (xPack GNU Arm Embedded GCC x86_64) 2.37.20220122, but it seems to be independent of the version used; we observed the same issues with arm-none-eabi-gcc (Arch Repository) 14.1.0 and linker arm-none-eabi-ld (GNU Binutils) 2.42.
===============================================================
Please provide assistance in regards to the following questions:
1. TI/CCS somehow manages to build/link this properly. How does TI's toolchain handle this? It is using the same code and same flags as our GCC environment?
2. What are TI's suggestion to mitigate this in our environment? Edit the SDK and add .type directive to all assembly functions?
3. Can TI update the SDK to support GCC?
Thanks for the support