Hi,
Is there something the RTX does, that then effectively stops a non-RTX process from running?
I have an old and new bootloader (the old is incumbent on the machines and I'm forced, for the time being, to use it)
I have two builds of the application one with the same RTX OS (single thread, looped every 10ms) and a non-RTOS version that runs the same routine every 10ms, so very nearly identical.
* non-RTX bootloader - RTX application works * non-RTX bootloader - non-RTX application works * RTX bootloader - RTX application works * RTX bootloader - non-RTX application FAILS - hard fault - sadly the one I need! and both work when flashed to the root of flash in the debugger.
I have tried to use the debugger to try and understand the differences but have failed to chase out the issue. Map files look good, and Vector table points where they should. I have tried to strip down the application - while(1) runs, virtually anything else I've tried fails. (One with just CAN ran until another device sent a message even though Rx interrupt was not enabled)
It feels like the bootloader has stored interrupts that when allowed fires an interrupt, that executes from a place that is not code and scribbles across memory. I'm not sure if the debugger is causing the fault, feels like I get different behaviour if the debugger is connected or not.
I'm stuck and out of talent, can you help? Any help would be great.
Background info: STM32F103ZG, RTX version 4.74, Keil 5.11
Please ask if there are other details that would be useful.
Cheers Scott
Thanks Rod,
Just tested with the following... A little more bare metal, and I could not find all the registers you mentioned on the device, but hopefully I've reset everything.
SysTick->CTRL &= ~SysTick_CTRL_ENABLE; RCC->APB1RSTR = 0xFFFFFFFF; RCC->APB1RSTR = 0x00000000; RCC->APB2RSTR = 0xFFFFFFFF; RCC->APB2RSTR = 0x00000000; RCC->AHBENR = 0x00000014; NVIC->ICER[0] = 0xFFFFFFFF; NVIC->ICER[0] = 0x00000000; NVIC->ICER[1] = 0xFFFFFFFF; NVIC->ICER[1] = 0x00000000; NVIC->ICPR[0] = 0xFFFFFFFF; NVIC->ICPR[0] = 0x00000000; NVIC->ICPR[1] = 0xFFFFFFFF; NVIC->ICPR[1] = 0x00000000;
Sadly, still did not work.
Thanks for the posting, gave me something else to try.
Scott
Is the RTX boot loader a single thread? Is there another thread doing something?
When deinitialising hardware, first reset the peripheral then disable it's associated NVIC IRQ. That should stop it doing anything. Stopping systick should prevent RTX from doing anything.
What about a really simple test: Modify your boot loader so that after a system reset, it does nothing other than disable systick and jump to the application. Does it then work?
Sounds like your application is not getting the clean start it expects.
Plus, I'm nowhere near a datasheet but I'm pretty sure the NVIC has more like 8 ICER register sets (...?). In your previous post, you appear to only address two.
And why are you writing to each ICER registers twice? Writing 1's to that resister will disable the irq. No need to write the 0's I believe. same goes for the ICPR registers. Have a look at the arm cortex m3 nvic docs.
Hi Rod,
Thanks again... You're away from data sheets and I'm away from the hardware and can't test until Monday.
However I can feedback on some of your points.
* The RTX boot loader has multiple threads * Hopefully there is not another thread doing something at when it resets - But I don't recall any code to stop other threads in the "start app" routine, just stop interrupts. * I've tried many simple tests, but all with the app. I can't modify the RTX boot loader, I need to run with what's installed. First app to run is likely to be "update boot loader" I could test by stripping down the RTX boot loader, might provide some insight You've just given me a thought, I could write the "update boot loader app" with RTX which, I think might work. * The NVIC does have 8 ICER registers (according to the header file), however the debugger only shows 2, so I only set 2... Should I set all 8, what harm can it cause? * I was following the reset/release reset from the section above, also when stopping the execution at the jump point, ICER and ICPR for USART1 are high and I could not clear then in the debugger and thought this might be how it was done.
I think either an interrupt is firing, quite possibly SysTick, or another thread is doing something, while the processor is running SystemInit or __main
What really puzzles me is that it works fine when an RTX app is being installed, therefore there must be something about the locations where stuff is being copied to that's special otherwise it would scribble the RTX app as well.
Thanks again, Scott
Eventually - after having to work on other stuff, and getting back to this have now found the issue...
The RTOS sets up the Process Stack, a non-RTOS program does not...
PSP - Process Stack Pointer, MSP - Main Stack Pointer, both are viewable from the Registers window in uVision
A non-RTOS application sets the PSP and MSP to the same address, knowing that PSP will never be used
However if started from a RTOS boot loader, the PSP is set up for use. The non-RTOS application is then running on the Process Stack (in error) and when an interrupt fires (which are run from the Main Stack), the stack is updated and because they are set to the same location, the interrupt overwrites/corrupts the stack. A fault then occurs when the application returns to main function because the Link Register (LR) has been corrupted.
To de-select the use of the Process Stack Pointer the CONTROL needs to be set to zero
__set_CONTROL((uint32_t)0);
Thanks Scott