"startup code" is a fragment of program that gets the "environment" ready for use by (typically) a higher level language: setting up chip-selects, bus widths, processor options, stack pointers (all the stuff that doesn't really fit in to the way e.g. C works).
Startup code will be specific to the particular processor that you are using, and will be specific to the way the processor is connected to the other devices in your design. You have to write it.
I'd like to disagree with this. In all compilers I used so far, the startup code only set's up the very basic things like the stack pointer, code and data segments dependig on the CPU used and initializing all variables and constants. The rest, like further processor and peripheral initialisation is done in user written C functions. And so far, I have never written start up code, I could always use the start up code supplied by the compiler vendor, which is automatically chosed and configured by most IDE's. My experience anyway,
In my opinion, startup code is code executed from the reset of the CPU, until the call to main(). So any function you call from main() to setup up further things, no matter how low level and essential they are, is not called startup code.
If need be, yes.
Again, all startup codes I have seen so far, were written in assembler. Probably because at startup time, there is no environment set up yet to run compiled C code at all. But this only holds true with "my" definition of startup code, where the call to main() is not executed yet.
I'm working on an example of how NOT to do startup code- the Zilog eZ80 ZDSII development system. It gets worse- more prescriptive- with each release of the system, so much so that the latest version won't work at all with most of their example code.
It's all done in an attempt to make a system, PIC style, where you use vendor- supplied and compile-time configured code fragments rather than having to read the data sheet and modify (or even write) configuration files for yourself. All very laudable- except that to swap the default printf console from UART0 to UART1 you have to RECOMPILE THE BLOODY LIBRARY in the latest version. OK that's not startup, but you get the point about unhelpful nannying.
No, in embedded systems, startup code should be restricted to setting up stack pointers etc., initialising or clearing variables, setting up the bones of the interrupt system where this needs to be done in RAM, and executing main(). Anything else should be explicit, in C, easily accessible to the code writer, well documented, and obvious where it is.
What you call "startup code" is a matter of taste. There are a few things that need to be done before the main part of a program can run - setting up critical hardware (chip selects, memory areas, etc.), setting up the stack, clearing out bss, copying initial data segments, copying program data from flash to ram (if necessary), calling C++ constructors (for C++ only, obviously), starting main(), initializing other hardware and software.
Normally everything after the start of main() is the application programmer's domain, and it is written in C (I'm assuming the main language here is C/C++). You can call it startup code if you like.
Code for setting up the stack, clearing bss, and copying the initial data segment is generally part of the "crt0" module that comes with your C compiler. It's frequently written in assembler, by the compiler library designers.
Code for configuring critical hardware like chip selects is generally only necessary on "big" microcontrollers with flexible external memories. Code to do this is often part of a boot loader of some kind, and may or may not come with the compiler. It's often part of a "board support package" for an OS, and is also frequently written in assembler.
Personally, I tend to use compiler-generated startup code for small micros, but write my own for bigger micros. I have a couple of lines of assembly (typically "enable internal ram, set stack pointer, jump to C code") to get started, then the rest of the setup is in C. Such code has to be a little careful - bss variables and const are not yet initialized - but it's far more convenient than doing everything in assembly.
I tend to get some semblance of a limited C environment ready first, then call something (in C) perhaps called _premain, which sets things up some more and then calls main. _premain would typically operate under certain restrictions (like no/limited stack, no assumption that .bss is zeroed, cpu running at a low clock speed. It then alters those and then calls the real main().
Start up code is the minimum code required to get to main... The start point of the C code.
It depends on the processor how much start up code there is. This is usually a file supplied with the compiler. I have know embedded C programmers never realise there was start up code before the main as the compiler added it transparently. This file is of course is all written in assembler.
On some MCU some people modify this start up assembler. Most don't. On other MCUs the start up file is a template that the user has to set up various variables (stack, memory, clocks etc.).
So the answer as to what is start up code is "it depends" but it usually refers to the assembler that sets up enough of the MCU so that the C program can start at main.
Note strictly speaking if you are using start up code there is no OS and therefore the first C function is not required to be called main.
-- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ /\/\/ firstname.lastname@example.org
I'd hardly call memory testing "one of the most important reasons for having boot code". While it is sometimes relevant to have a memory test pass, it's not a big thing. How often does memory actually fail in real life (outside of specialist systems in very harsh environments)? In particular, how often does a microcontroller's integral sram fail, or external sram or dram? If you know some statistics or web references, I'd be very interested to hear them. I think in most embedded systems, there are far more relevant hardware checks to make - the chances of having a minor memory error (major ones, like badly soldered pins, get "detected" pretty quickly) are fairly negligible in comparison.
Horses for courses boy. If I've got 2k of flash and 256 bytes of RAM, I haven't got room for POST. If no one is going to get hurt if the system fails, why bother with POST? Why bother anyway for non- critical systems? Who's going to thank you for it? It malfunctions, the customer curses his luck or the mains, reboots, and that's it for another 15 years.
On the other hand, a soft failure in RAM can happen at any time, not just startup. The program gives a wrong result or crashes, the drive trips out or the watchdog kicks in, the customer curses his luck...
If on the other hand it fails every time you start up (either because the RAM has died and it fails POST, or the RAM has died and the program crashes), customer service is called out, and it gets fixed. Or not, because they went bust 10 years ago...
While all kinds of self tests are nice, but the real question is what to do, if the test fails.
For a critical redundant control system, the only thing would be to take the device off-line and let the redundant system(s) take over and let them raise the alarm. For other systems, in which faulty data can be harmful, some means of checking the device integrity is needed.
For a harmless toy (and "toy" is here used in a broader sense), if the POST detects a problem, what could the user do, especially if there is no display. So realistically, why test something, if there are no actions to be taken to rectify the problem other than throwing the malfunctioning device away ?
For a safety device we made we had self tests for 30 seconds after reset and continuously by slices during the normal operation. If either test fail, the application is stopped immediately and the system must be designed so that all outputs are put in a safe state in this case. This is a regulatory issue. A safety device must have a safe state in the absence of voltage. This is also an issue for the whole installation, not only the equipment.
Every hardware component is tested, including outputs by feedback to inputs and inputs by alternating input voltage instead of continuous voltage.
that is ONE of the reasons... not the most important. As many MCU have a only a little RAM. eg the 8051 with 128 BTYES many of which are the registers it will not boot itf there is a problem let alone be able to run a memory test. Most systems run from ROM (or block write able flash) so again a memory test would not do much.
You don't. Why would you need to? There are many times when a memory test is *required* others where it is a good idea, other times when it does not matter and some times when it is pointless.
remember embedded systems go from 4-128 bits from trivial (pointless) to safety critical.
Who said you have a watchdog?
On many MCU the chip is the HW.... There is nothing else.
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/