We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
question 1: This is the original reset handler that is in the startup file (*.s)
Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP
which i modify to
Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT OSInit IMPORT __main LDR R0, =SystemInit BLX R0 LDR R0, =OSInit BLX R0 LDR R0, =__main BX R0 ENDP
Here the OSInit is a function. This works fine.
But when i modify the original to following, I get a hard fault.
Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT main IMPORT OSInit LDR R0, =SystemInit BLX R0 LDR R0, =main BLX R0 ;getting hardfault here LDR R0, =OSInit BX R0 ENDP
Irrespective of whether the OSInit is a function or a task, i get Hardfault.
question 2: does the '__' (two underscores) before 'main' have any significance. Because when i write __OSInit, the compiler is unable to locate OSInit function (Error L6218E: undefined symbol). but for '__main' the function name is always 'main' and compiler locates it.
Yes, the underscores has significance.
The __main function is an initialization file in the C runtime library. Consider where all your global variables gets their initial values...
If you don't initialize the CRTL, then you do not deliver the processor is the proper state when you enter your main() function.
Note that __main() doesn't return - it initializes everything and then calls your main(). So you can't expect to have other functions called after __main() in your startup code.
OK.
__main function is an initialization file in the C runtime library. which means i cannot change __main to return back.
Can you tell me why you don't want to have main() perform the reset of the initialization?
if OSInit is a task, then too i get a hardfault. I want OSInit to be the master task, which initializes other tasks and then deletes itself.
I have nothing to do with main. Want to initialize the RTOS before main. (prior to your reply, was thinking of doing it after main.)
I am unable to call a task from the asm reset handler. it generates a hardfault error.
Also if i call function OSInit, from asm, and if i initialize the tasks in that function, the tasks never get executed. none of them. I dont understand, why the tasks are not initializing.
Why doesn't the car function as expected, if I put the engine in the back seat and have the passenger sitting under the hood?
Note that code normally is written based on a number of assumptions. You are breaking these assumptions when you try to do things differently.
Have you seen any example code where tasks are started before main()?
Another thing - you obviously can't do anything after main(), since main() is never intended to return.
@Dhaval Solanki,
This ain't gonna work, OK? You have to execute __main BEFORE you setup your kernel !
Note that code normally is written based on a number of assumptions. You are breaking these assumptions when you try to do things differently. Why assumptions... This ain't gonna work, OK It should.
Why we dont have a RTOS in which the user only has to design only an executable file and run it (just as in desktop OS)?
Let us think in this direction... We dont have RTOS where, we can only patch up the new code on to the device already running. We have to load the whole code. (increases the service cost for the company as it has to regulate site visits. site visits are avoidable if i have an ethernet based boot-loader, then too i have to flash the whole code!!) Like for example, an application on my mobile-phone has a new update. the application gets updated without switching off the phone or for that matter even the application.
also the coders from all around the world can develop the applications.
similarly, my colleagues dont have to bother what is going on (eg: about the interrupt functions and data generated from there. they just have the locations [or mailboxes or any other method] form where they get the values captured in the interrupt functions). they have the starting point and they just have to start from there.
Hence i need some more initialization before main.
@Tamir Refer to the link sent by John Linq. Intended to say 'there must be some way'. the tools, the codes, etc have been developed by humans. at the end its only the binaries that run on core. and we can generate this binaries to work as we want them to.cant we?
NO, you refer to that link !
"Copies non-root (RO and RW) execution regions from their load addresses to their execution addresses. Also, if any data sections are compressed, they are decompressed from the load address to the execution address"
Now look in the mirror and say (X 100000 times): "yes, yes, yes, my kernel can run if I did not execute scatter load. yes, yes, yes I can !"
Maybe you can convince __main to branch to your kernel init function, but I doubt it.
They have been developed by humans to work in a particular way.
If you want to use them, you have to work with them.
You don't have to use them - you may do it all yourself, from scratch, if you wish.
When you do it all yourself from scratch you are, of course, entirely free to do it however you like.
@Tamir The link is informative. as i said, i just want to alter the way. I definitely dont want to disturb the scatter file.
Dont we have any method by which, we can bring the code to main() after initialization of RTOS
as per my understanding, __main has some piece of code which copies non-root ro & rw regions, etc and at the end calls main(). so want to call os_sys_init jus before main or the other way, execute some piece of code (initialisation code in the same way as SystemInit is done in asm code) and then call os_sys_init and finally the main function.
like, in desktop pcs. Boot up, POST, then kernel is loaded and then windows starts up. Now the user is free to do as he wishes. he can also execute his own codes, other programmer codes etc.
will i have to read the procedure in which the os are booted up and try to do the same thing on my embedded board?
Why assumptions?
Because you can't design _anything_ without making assumptions.
What assumptions did a car manufacturer base the design on? - that people can buy gasoline? - that there exists tire companies? - that a human will sit with the legs down and the arms on the steering wheel? - that the customers will value safety and expect safety belt, air bags, impact zones, ... - that the customer would be angry if the noise levels did give loss of hearing. - that a normal road doesn't have holes larger than a certain size. - what size to expect for a normal parking space.
There are always assumptions.
Some are so obvious that you don't document them. S the car is designed for humans of "normal" size. The manufacturer leaves it up to people who are 270 cm long or weights 340 kg to check if they will fit.
Some are non-obvious and needs to be documented. So you get a document that tells the maximum weight you may transport with the car. And which specific fuel it can run on.
For majority of code written, the code is written under the assumption that someone else have already set up the processor stack. And all global variables have been given their intended start values.
If you play with the startup file, then you invalidate these design decisions, and ends up with a non-working program.
Your fault is that you don't realize that main() can be the function that initializes the OS. And that main() can then call funny_end_user_stupid_main_run_only_after_os_initialized_for_thread_1() and another_funny_end_user_main_run_only_after_os_initialized_for_thread_2().
As long as your goal is to put the donkey behind the wagon, you are going to have huge issues. The world works much better if you try to follow the normal path instead of going against the stream. Especially since you don't really have anything to gain by mucking up the startup sequence.