I have splitted software into two parts: Bootloader(without RTX), Application image with RTX. But the bootloader could not load the application image with RTX. The Flash settings are:
-------------------------------- start address size IROM 1: 0x08000000 0x2800 - Bootloader (without RTX) IROM 2: 0x08002800 0xD000 - Application Image (with RTX)
I have test 3 ways: (1) Use another App without RTX. The bootloader could load the app successfully.
(2) Change the application with RTX project IROM setting. I change the application project IROM start address from 0x08002800 to 0x08000000. And I download the application image into flash from the address 0x08000000. Ihe image could run from 0x08000000 successfully.
(3) The application image IROM start address setting is 0x08002800. After downloading bootloader and app image into flash, I debug the app project in keil step by step. I found that there is a "osTimerthread stack overflow" error. Then the main thread stack is also overflowed. I have tried to increase the stack size, but it doesn't work. I found that the app starks in the RTX kernel switching. All threads are in the waiting state, and are not running. Ps, when I am debugging in the keil,test item(2) also have stack overflow errors during kernel initialization. This is the debugging picture.
I could not find the reason, so I come here for help. Thanks.
"Why is it so difficult to writing boot loader for Keil RTX OS ?"
Let me correct that sentence for you:
"Why is it so difficult to writing boot loader?"
The difficulty of writing a boot loader comes from understanding how a processor functions. And for handing over the processor in a similar state to the application as if the application hadn't been started from a boot loader.
A normal program expects all interrupts and peripheral hardware to be in the reset state. Leave everything in the reset state, and the only thing you need to take care of is the address of the vector table.
So if you have issues with handing over to applications, then maybe the boot loader is doing too much stuff it shouldn't - or doing stuff it should end up undoing before the handover.
In the end, it's important to note that when a compiler produces an embedded application, then assumption for the created application is that the processor is comming from the reset state. So that's the assumption made by the C runtime library and by any OS initialization code. Violate these assumptions, and you are on your own.
If your boot loader has a initUart0() - make sure it has a deinitUart0(). If it has a initSystimer() - make sure it has a deinitSystimer(). Your life will suddenly become so much simpler then.
So I will check and clean the configurations carefully in bootloader. Any way, thank you so much. I will test it and post the progress if there were results need to be shared. thanks.
Hi, I have made another test. In this test, the bootloader is simplified to load application image directly. There are only two functions called: "SystemInit" - Initialize system clock frequency; "_main" - load application image directly.
In the debug viewer, the application image was running. But RTX OS was looped in task switching with no task been put into "RUNNING" state. The OS kernel was in a endless loop and there was no chance for user task to run.
Do you need that system clock? The processor must already have a working oscillator to reach that function. Does it break any assumption of the actual application that thinks it is responsible for setting up the clock?
Because the problem is that you are somehow breaking an assumption of the application.
Do you understand the concept of a processor running in a USER state, and a SYSTEM state, and what that implies about the things you can do, and what might be prohibited?
Then also consider if the processor is in an INTERRUPT context, and that you can't clear that jumping to some other random code. ie don't transfer control from an interrupt, button press, systick, etc.
In the beginning of application image, there is also a startup.s file which will re-initialize system clock frequency. So I don't think initializing system clock frequency will not break the assumption.
That depends on the order of instructions.
If the second initialization performs the steps one by one and gets surprised by the boot loader having already run through the full list.
Things that might normally take time - like synchronizing a PLL - can suddenly be already done. Depending on how the code is written, this can lead to unexpected results, similar to when code tries to initialize a UART, and the UART has already been initialized and already have received data that is just waiting for the interrupt flag to be enabled.
The interesting with "So I don't think initializing system clock frequency will not break the assumption." is that you are making an assumption that two calls will not breaking any assumptions. Lots of assumptions involved, and assumptions are bad. Better make sure.