views:

168

answers:

4

hi,

I am working with an embedded board , but i don't know the flow of the start up code(C/assembly) of the same.

Can we discuss the general modules/steps acted upon by the start up action in the case of an embedded system.

Just a high level overview(algorithmic) is enough.All examples are welcome.

/Kanu__

+1  A: 

The big question is whether or not your embedded system will be running an operating system. In general, you'll either want to run your operating system, start up some form of inversion of control (an example I remember from a school project was a telnet that would listen for requests using RL-ARM or an open source tcp/ip stack and then had callbacks that it would execute when connections were made/data was received), or enter your own control loop (maybe displaying a menu then looping until a key has been pressed).

marr75
here am running without any OS right now. In future after integrating all applications i may be forced to add that too.. :-)
Renjith G
+9  A: 
  1. CPU gets a power on reset, and jumps to a defined point: the reset vector, beginning of flash, ROM, etc.
  2. The startup code (crt - C runtime) is run. This is an important piece of code generated by your compiler/libc, which performs:
    1. Configure and turn on any external memory (if absolutely required, otherwise left for later user code).
    2. Establish a stack pointer
    3. Clear the .bss segment (usually). .bss is the name for the uninitialized (or zeroed) global memory region. Global variables, arrays, etc which don't have an initializing value (beyond 0) are located here. The general practice on a microcontroller is to loop over this region and set all bytes to 0 at startup.
    4. Copy from the end of .text the non-const .data. As most microcontrollers run from flash, they cannot store variable data there. For statements such as int thisGlobal = 5;, the value of thisGlobal must be copied from a persistent area (usually after the program in flash, as generated by your linker) to RAM. This applies to static values, and static values in functions. Values which are left undefined are not copied but instead cleared as part of step 2.
    5. Perform other static initializers.
    6. Call main()

From here, your code is run. Generally, the CPU is left in an interrupts-off state (platform dependent).

Yann Ramin
Can you please clarify the 3 rd sub point in the 2 nd main point?
Renjith G
I would put setting the stack pointer first, ARM Cortex-M even stores the initial stack pointer alongside the reset vector. With a stack you can start programming in C. Next would be a board-specific subroutine (assuming the stack is in internal RAM) for hardware initialization such as setting up access to external memory and setting up a faster system clock. Many microcontrollers start up on a very slow low-power clock, the faster clock then speeds up the initialization of the .data and .bss segments.
starblue
+1  A: 

Pretty open-ended question, but here are a few things I have picked up.

For super simple processors, there is no true startup code. The cpu gets power and then starts running the first instruction in its memory: no muss no fuss.

A little further up we have mcu's like avr's and pic's. These have very little start up code. The only thing that really needs to be done is to set up the interrupt jump table with appropriate addresses. After that it is up to the application code (the only program) to do its thing. The good news is that you as the developer doesn't generally have to worry about these things: that's what libc is for.

After that we have things like simple arm based chips; more complicated than the avr's and pic's, but still pretty simple. These also have to setup the interrupt table, as well as make sure the clock is set correctly, and start any needed on chip components (basic interrupts etc.). Have a look at this pdf from Atmel, it details the start up procedure for an ARM 7 chip.

Farther up the food chain we have full-on PCs (x86, amd64, etc.). The startup code for these is really the BIOS, which are horrendously complicated.

zdav
AVRs, PICs, and some microcontroller ARMs all have their interrupt tables in flash (the interrupt priorities do need to be defined usually). A fully linked C program will contain code for setting up the stack, clearing .bss, copying .data, and then jumping to main()
Yann Ramin
I think a lot of "simple" CPUs (8086 at least) actually run one of the last instructions in memory, typically a jump command to wherever you have your start up code (what theatrus has described in his answer). When I hear embedded I immediately think uController, not that it's the only possibility, it's just dominant in that field.
marr75
@theatrus and @marr75 The essential problem with this question is whether it is asking about the 'hardware startup' or 'the code you write that runs first'. I decided to go for the latter as it is more programmer oriented vs. compiler writer/architect oriented.
zdav
That means , if i compile one Small C program for helloword, the linker/compiler will add the start up code along with my small application , to perform start up action after downloading my application right?Can you list the general initializations(UART/Clock etc..) that were happening as part of start up action?Also can you little bit specific on the interrupt vector initialization as general concern?
Renjith G
@Renjith 1. Yes the linker adds a bunch of code. (crt.o usually)2. In a low-level environment, the device programmer will init the hardware peripherals (timers/usart/watchdog/CAN/USB/etc.)3. A added a bunch of links - check 'em out.
zdav
@zdav:That means we are having two start up codes (one from H/W manufacturer and one from compiler generated)How can i execute one by another? but in my understanding only one start up code by the H/W manufacturer?I want to know the flow of that one. :-(
Renjith G
A: 

Where is "BOOT LOADER" placed then? It should be placed before the start-up code right? As per my understanding, from the reset vector the control goes to the boot loader. There the code waits for a small period of time during which it expects for data to be flashed/downloaded to the controller/processor. If it does not detect a data then the control gets transferred to the next step as specified by theatrus. But my doubt is whether the BOOT LOADER code can be re-written. Eg: Can a UART bootloader be changed to a ETHERNET/CAN bootloader or is it that data sent using any protocol are converted to UART using a gateway and then flashed.

Jijo
Welcome to SO, additional questions should probably be asked in the comments or open another question specific to your inquiry. You might want to clarify this particular question, or ask a simpler question, it doesn't seem like you've come up with something answerable.
marr75