I am trying to write a simple 'go-command' for boot-loader that takes me to specific address in RAM say 0x18000000 and it should execute a program that blinks led. I have two .c files say led.c and go.c in which led.c blinks two leds. But I am wondering and don't know that how can I pass a control/invoke its main() to this go.c file to go to that address and start blinking leds? But it should be done without including other header files, libraries, etc. Kindly help me!! Thanks in advance. Below code is for led.c
void delay ()
{
volatile int i;
for(i=0;i<1000000;i++)
{}
}
int main(void)
{
*led0=0;
*led1=0;
while(1)
{
*led0=1;
delay();
*led0=0;
*led1=1;
delay();
*led1=0;
}
}
In my go.c file I want to pass a control to invoke this led.c main() func
There is a lot you have omitted that is likely to be relevant, but taken at face value, you simply declare a function pointer, initialised with the absolute address and invoke the function through that pointer.
However it may not be that simple since the called program will use the C run-time environment of the calling program; any global static objects will not be initialised - you need to call the program entry point (which is not
main()
) to establish the run-time environment expected by the program. In simple case it may work or appear to work to some extent.So I have an sifive riscv board, going to be a little different than yours but here is an led blinker program (compiled version):
the disassembly spacing is a little broken but thats okay. The entry point IS NOT AT MAIN() for a normal program it is at the start in this case 0x80001000 NOT 0x8000101A which I intentionally name something other than main on purpose (for bare metal)...There should be no reason for you to to enter at main you should enter at the entry point...I will let you simply fail if you continue to try otherwise, you are on your own with that.
So this represents an srec of the above.
I/we assume you are not actually downloading that to ram as is, that will never execute, your bootloader has to parse that then write the program to ram, two different things (the program itself and a file format that describes that program).
Assuming you get to that point, all you need to do is branch to 0x80001000 in my case or 0x18000000 in yours.
so taking the answer already provided to you you can do this to launch the downloaded program
which results in
Or my personal preference would be:
which from C I would call with
that way I can insure the instruction I wanted is used. YMMV.
How far along this path have you gotten? Are you stuck at the last step? Simone provided an answer that should work just fine, there are other variations on that theme from C that you can use, but that one already appears to work.
GCC has an extension that allows jumping to an arbitrary address, so if you know the address of your led.c main you could do something like that:
However, you probably don't have the address of the led routine and it is not a very safe operation. Jumping to some unknown address will probably result in a crash!!