Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
7 years, 10 months ago.
ARM GCC toolchain not initializing RTOS (was: simple RTOS example ends in HardFault_Handler)
Hi,
I tried running the RTOS Thread example on LPC1768, but when creating a Thread, a HardFault occurred. It happens always if the code was compiled with ARM GCC.
Callstack
> HardFault_Handler() <signal handler called>() SVC_Handler() <signal handler called>() __svcMutexWait() osMutexWait() rtos::Mutex::lock() rtos::Thread::start(mbed::Callback<void ()>)() rtos::Thread::constructor(mbed::Callback<void ()>, osPriority, unsigned long, unsigned char*)() rtos::Thread::Thread() main()
The SVC_Handler() causes the exception when executing line 10 of the following partial code listing, because the PSP contains an uninitialized random invalid value:
HAL_CM3.S (partyl)
SVC_Handler: .ifdef IFX_XMC4XXX .global SVC_Handler_Veneer SVC_Handler_Veneer: .endif .fnstart .cantunwind MRS R0,PSP /* Read PSP */ LDR R1,[R0,#24] /* Read Saved PC from Stack */ LDRB R1,[R1,#-2] /* Load SVC Number */ CBNZ R1,SVC_User LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ BLX R12 /* Call SVC Function */
After some debugging I found out, that the startup file does not initialize the RTOS component. This may also be the issue while people have trouble running code compiled with CodeSourcery.
Maybe somebody could forward it to the mbed-os developers so it can be integrated into one of the following releases?
A replacement startup file (.c instead of .S) could be:
startup_LPC17xx.c
/*---------------------------------------------------------------------------- Description: LPC17xx startup file for ARM GCC compilers Copyright: unknown, files did not contain any copyright info License: unknown, files did not contain any license info - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: This file is a adption of the basic startup code from Sysprogs (ORIGINAL_CR_startup_lpc175x_6x.c), extended with functionality from mbed TOOLCHAIN_GCC_CR (startup_LPC17xx.cpp) to call the necessary routines to run CMSIS RTOS/RTX from mbed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------*/ // common defintions #define NULL ((void *)0) // Local functions void Reset_Handler(); void Default_Handler(); // External functions extern void SystemInit(void); extern void pre_main(void) __attribute__((weak)); extern void software_init_hook(void); extern void __libc_init_array(void); // this comes from newlib-nano extern int main(void); // The following external defintions are part of the linker script extern void* __StackTop; extern void* __etext; extern void* __data_start__; extern void* __data_end__; extern void* __bss_start__; extern void* __bss_end__; // Interrupt handler defintions with weak Default_Handlers void NMI_Handler() __attribute__((weak, alias("Default_Handler"))); void HardFault_Handler() __attribute__((weak, alias("Default_Handler"))); void MemManage_Handler() __attribute__((weak, alias("Default_Handler"))); void BusFault_Handler() __attribute__((weak, alias("Default_Handler"))); void UsageFault_Handler() __attribute__((weak, alias("Default_Handler"))); void SVC_Handler() __attribute__((weak, alias("Default_Handler"))); void DebugMon_Handler() __attribute__((weak, alias("Default_Handler"))); void PendSV_Handler() __attribute__((weak, alias("Default_Handler"))); void SysTick_Handler() __attribute__((weak, alias("Default_Handler"))); void WDT_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void TIMER0_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void TIMER1_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void TIMER2_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void TIMER3_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void UART0_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void UART1_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void UART2_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void UART3_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void PWM1_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void I2C0_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void I2C1_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void I2C2_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void SPI_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void SSP0_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void SSP1_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void PLL0_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void RTC_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void EINT0_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void EINT1_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void EINT2_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void EINT3_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void ADC_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void BOD_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void USB_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void CAN_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void DMA_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void I2S_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void ENET_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void RIT_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void MCPWM_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void QEI_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void PLL1_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void USBActivity_IRQHandler() __attribute__((weak, alias("Default_Handler"))); void CANActivity_IRQHandler() __attribute__((weak, alias("Default_Handler"))); // The Interrupt Vector table void* g_pfnVectors[0x33] __attribute__((section(".isr_vector"))) = { &__StackTop, // Top of Stack &Reset_Handler, // Reset Handler &NMI_Handler, // NMI Handler &HardFault_Handler, // Hard Fault Handler &MemManage_Handler, // MPU Fault Handler &BusFault_Handler, // Bus Fault Handler &UsageFault_Handler, // Usage Fault Handler NULL, NULL, NULL, NULL, &SVC_Handler, // SVCall Handler &DebugMon_Handler, // Debug Monitor Handler NULL, &PendSV_Handler, // PendSV Handler &SysTick_Handler, // SysTick Handler &WDT_IRQHandler, // 16: Watchdog Timer &TIMER0_IRQHandler, // 17: Timer0 &TIMER1_IRQHandler, // 18: Timer1 &TIMER2_IRQHandler, // 19: Timer2 &TIMER3_IRQHandler, // 20: Timer3 &UART0_IRQHandler, // 21: UART0 &UART1_IRQHandler, // 22: UART1 &UART2_IRQHandler, // 23: UART2 &UART3_IRQHandler, // 24: UART3 &PWM1_IRQHandler, // 25: PWM1 &I2C0_IRQHandler, // 26: I2C0 &I2C1_IRQHandler, // 27: I2C1 &I2C2_IRQHandler, // 28: I2C2 &SPI_IRQHandler, // 29: SPI &SSP0_IRQHandler, // 30: SSP0 &SSP1_IRQHandler, // 31: SSP1 &PLL0_IRQHandler, // 32: PLL0 Lock (Main PLL) &RTC_IRQHandler, // 33: Real Time Clock &EINT0_IRQHandler, // 34: External Interrupt 0 &EINT1_IRQHandler, // 35: External Interrupt 1 &EINT2_IRQHandler, // 36: External Interrupt 2 &EINT3_IRQHandler, // 37: External Interrupt 3 &ADC_IRQHandler, // 38: A/D Converter &BOD_IRQHandler, // 39: Brown-Out Detect &USB_IRQHandler, // 40: USB &CAN_IRQHandler, // 41: CAN &DMA_IRQHandler, // 42: General Purpose DMA &I2S_IRQHandler, // 43: I2S &ENET_IRQHandler, // 44: Ethernet &RIT_IRQHandler, // 45: Repetitive Interrupt Timer &MCPWM_IRQHandler, // 46: Motor Control PWM &QEI_IRQHandler, // 47: Quadrature Encoder Interface &PLL1_IRQHandler, // 48: PLL1 Lock (USB PLL) &USBActivity_IRQHandler, // 49: USB Activity &CANActivity_IRQHandler, // 50: CAN Activity }; // Reset_Handler(): Entry point after reset void __attribute__((naked, noreturn)) Reset_Handler() { // Copy initialized RAM section from Flash void **pSource, **pDest; for (pSource = &__etext, pDest = &__data_start__; pDest != &__data_end__; pSource++, pDest++) *pDest = *pSource; // Initialize BSS section in RAM for (pDest = &__bss_start__; pDest != &__bss_end__; pDest++) *pDest = 0; // Run system intialization SystemInit(); if (pre_main) { // give control to the RTOS software_init_hook(); // this will also call __libc_init_array } else { // for BareMetal (non-RTOS) build __libc_init_array(); (void)main(); } // done - this should never be reached for (;;) ; } // The Default_Handler that gets executed if your code is missing an interrupt handler void __attribute__((naked, noreturn)) Default_Handler() { //If you get stuck here, your code is missing a handler for some interrupt. for (;;) ; }