I'm trying to learn and master embedded C, so I was just gonna test a code that I found on Github, which is built for STM32F4 discovery board. The board that I'm actually working on is STM32L152. when I tried to build/run the code (obviously it won't work) the errors I'm getting are mostly related to functions not being defined or "identifier 'function_name' is undefined", note that the code file includes a library (lib).
take a look at the code file:
https://github.com/TDAbboud/STM32F4_Examples/tree/master/04_PWM_Servo
Generally speaking, What modifications should be done to successfully run the code on STM32L1?
Thanks
These are two different chips. Just because they are from ST just because they are ARM based, they are not the same chip. for starters the stm32f4 is a cortex-m4 the stm32l might not be, 99.9% of your code wont care, just some assembly might. if the stm32l is a cortex-m0 then you have far fewer instructions so the assembly will matter if it is a cortex-m3 then it wont.
The real isssue is peripherals not that this is two st chips not that this is two arm chips, the peripherals can/will vary. ST has a number of chips that use the same uart or same gpio or other, but they have more than one uart they use for STM32 chips, and more than one GPIO. And they mix and match as they make new chips, so if you want to port from one to the other you need to go peripheral by peripheral reading the new and old docs to see what if anything changed.
Sounds like you are using a library so the tool may know from the chip you have chosen what peripherals you have and which library you need, so it might not be finding them because for that chip that peripheral and thus that function and those defines do not apply. Take it one perpheral at a time and port between chips.
stm32 (L) serise incloud EEPROM which are important when they go to sleep mode and want to recover variables after wakup . so make sure application is running in sleep modes need to save data somewhere. so if you use STM (F) series care needs to attache a external EEPROM
For the life of me I can't make a timer for PIC18 or precisely PIC18f87j11. All I want to do is to have a counter that increments every 1 second. I just want to monitor how long PIC18 been running in terms of seconds.
Most of the tutorials out there are for PIC16 and are in assembly. I am trying to do this using C programming. For someone who is beginner I understand better if I see examples, so without examples I can't progress.
please someone show me an example, thank you!
To begin understanding timers you will need to have a look at their documentation. I suggest searching the manufacturers website. There are 5 timer available. If you use Timer0 which is either a 8 bit or 16bit timer. You will need to set the correct configuration for T0CON. Also you will need to have correct interrupt settings (INTCONbits), so a an event can be generated by interrupt service routine once timer expired.
You will most likely need to calculate the prescale value you require for correct timing, in your case 1 second. It does depend on FOsc: Here is a tutorial
Here an example of C code using MPLab and another one based on MPLab and hi-tech compiler. It is not for same chip, however it is based on PIC18F family.
It's been a awhile since I have visited PIC18F, so if any correction required, please do so.
If you use HIGH-TECH compiler, you can simply use its special function for close, open, read and write timers modules in below directory:
...\HI-TECH Software\PICC-18\9.80\sources\plib\Timers
According to your microcontroller name, you can figure out which version of these function is written for your microcontroller. So for first step, open pconfig.h file and search your microcontroller name to see for every module which version is fit to your microcontroller registers.
Good Luck
How can i find from the chip manufacturer the list of magic addresses for several chips? with decent explanations of the values it supports?
I couldn't even figure out the term to call/search for it.
just starting in embedded programming. there's tons of magic bits i have to set to all kinds of things.
usually i'd encounter something:
MOV BLKMGC 0x01
or
REO034 = 0x80; // stops all onboard leds, boot freebsd, makes coffee, do laundy.
// use 0x81 if you have more white clothes than color ones.
which sometimes has comments explaining what they are doing. I'm mostly taking notes of all of those i find in sample codes. The ones for msp430 launchpad usually are written by nice verbose people with lots of comments and i can even find some of the address maps on the chip family notes, but hardly a comprehensible list. chips more common on Arduinos leaves even more be desired when trying to fully understand that. (granted, i'm still not sure how to search for it :)
The best place i found so far is the header file for the chip i'm using... but even so, take this example:
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop Watch Dog Timer
// how 99% of msp430 programs start.
now the header file:
#define WDTCTL_ 0x0120 /* Watchdog Timer Control */
sfrw(WDTCTL, WDTCTL_);
/* The bit names have been prefixed with "WDT" */
#define WDTIS0 (0x0001)
#define WDTIS1 (0x0002)
#define WDTSSEL (0x0004)
#define WDTCNTCL (0x0008)
#define WDTTMSEL (0x0010)
#define WDTNMI (0x0020)
#define WDTNMIES (0x0040)
#define WDTHOLD (0x0080)
#define WDTPW (0x5A00)
/* WDT-interval times [1ms] coded with Bits 0-2 */
/* WDT is clocked by fSMCLK (assumed 1MHz) */
#define WDT_MDLY_32 (WDTPW+WDTTMSEL+WDTCNTCL) /* 32ms interval (default) */
#define WDT_MDLY_8 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS0) /* 8ms " */
#define WDT_MDLY_0_5 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1) /* 0.5ms " */
#define WDT_MDLY_0_064 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1+WDTIS0) /* 0.064ms " */
/* WDT is clocked by fACLK (assumed 32KHz) */
#define WDT_ADLY_1000 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL) /* 1000ms " */
#define WDT_ADLY_250 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS0) /* 250ms " */
#define WDT_ADLY_16 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1) /* 16ms " */
#define WDT_ADLY_1_9 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0) /* 1.9ms " */
/* Watchdog mode -> reset after expired time */
/* WDT is clocked by fSMCLK (assumed 1MHz) */
#define WDT_MRST_32 (WDTPW+WDTCNTCL) /* 32ms interval (default) */
#define WDT_MRST_8 (WDTPW+WDTCNTCL+WDTIS0) /* 8ms " */
#define WDT_MRST_0_5 (WDTPW+WDTCNTCL+WDTIS1) /* 0.5ms " */
#define WDT_MRST_0_064 (WDTPW+WDTCNTCL+WDTIS1+WDTIS0) /* 0.064ms " */
/* WDT is clocked by fACLK (assumed 32KHz) */
#define WDT_ARST_1000 (WDTPW+WDTCNTCL+WDTSSEL) /* 1000ms " */
#define WDT_ARST_250 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS0) /* 250ms " */
#define WDT_ARST_16 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1) /* 16ms " */
#define WDT_ARST_1_9 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0) /* 1.9ms " */
No explanation of the individual bits, no ready-made combination with the most common one.
bonus rant question
since it will always be compiled on powerful, mostly idle, personal computers, why do all compilers/IDE opt to just mimic the user friendliness of bare metal? isn't there tons of better formats to do that? if i'm not going crazy on performance, do i have to know for mundane coding that setting address 0x0120 with the value 0x5A80 stops the watch dog timer? can't the header files/IDE make it be watch_dog_timer( STOP ); to me?
This information is available in the data sheets from the manufacturer. Not all chips have available data sheets1, so keep that in mind when you pick out a chip.
For an example, let's look at the ATmega48. This is a simple chip with a nice set of basic peripherals.
Go to the manufacturer's website and find the product page. You can do a search for it on their website, or you can even use Google, but I've had the most success just clicking through links on the manufacturer's webpage. Go to the "documents" section of the page.
For the ATmega48, the documents are available at http://www.atmel.com/devices/ATMEGA48.aspx?tab=documents
Download the appropriate PDF file. This will probably be called a "datasheet" or a "user manual". It is definitely not an "application note" or an "overview". If the file is smaller than about a meg or less than a hundred pages long, it's probably not the right file.
For the ATmega48, the document is called "ATmega48/88/168 Complete"
The "magic addresses" are called registers. These are IO registers or peripheral registers, not the kind of registers you use when writing user-space programs. Registers are generally unique, and can be read-only, write-only, or read-write.
For the ATmega48, you can see a list of all registers in section 31 "Register summary". A description of how to use each register can be found under the section describing the relevant peripheral. For example, the GPIO registers are described in section 14 "I/O-ports", with example code both in assembly and C.
Bonus rant: If you want to write watch_dog_timer( STOP ); in your code, you can define the necessary macros and/or functions yourself (preferably functions, unless your compiler is no good, which happens sometimes with embedded systems2).
And I hope you're being sarcastic when you say that bare-metal programming is "user-friendly".
Footnotes:
1: For example, you can't get the data sheet for the chip on the Raspberry Pi without a large order and an NDA.
2: In my experience, you often want to choose a chip because it has good compiler support, rather than try to find a good compiler for the chip you already have. At least, if you're a hobbyist. GCC targets Atmel and ARM, which is positively luxurious compared to some of the trashy IDEs I've used.
Being an embedded programmer is not all programming. A big part of it is reading documents, schematics, and hacking (the docs and schematics are always wrong or old or whatever, never trust them 100%).
It is a complete mixed bag. Some vendors make (relatively) great documents, some are dreadful, and everything in between up to and including having to give up your first born to get access to a document (well, not quite but almost). Some companies feel there stuff is secret and you have to sign and NDA, and that doesnt mean good documents will come it is the same mixed bag, just harder to get and more responsibility once you have your hands on it. sometimes you have to give up information (name, phone number, etc) to a sales person, that is the worst as you will get a call every week or month until you quit your job or they quit theirs to see if you are ready to buy that thing you asked about or if you want to hear about the new exciting products. I tend to blacklist companies (every product they make) that require that to get at docs, very often their products are not worth buying.
Each companies document solutions are different. You mentioned the msp430, you have to go to one set of docs for the part family and you get names for registers but not addresses, then you have to go to the specific part datasheet to get the addresses that go with the names. I firmly believe that a big reason why Atmel is so popular is because overall their docs are better, their information is there, sometimes not the best docs, but tons of them, tons of app notes, info that other companies wouldnt give out as easily or at all, etc. Not light years ahead of the competition, sometimes only a few percent better, but you just feel it over time that they are just ahead, you dont worry as much when you have to dig into an atmel part compared to someone elses. ARM, same answer, generally very good documentation (but cores not chips, so you may have a great ARM core doc in a bad chip vendors product). Other companies you have to dig through example programs to find things, the docs dont match the example software, etc.
You are basically doing what the rest of us do. Digging through what is available be it a compiler/assembler sources (actually found info about atmel that was hard to find in an assembler data file, then later finally in the atmel doc), schematics, example programs, header files. Eventually you will become aware that some docs are written by non-technical types who have good writing skills, but no clue what the technical terms are in the docs. Documentation will sometimes fall to the person at the bottom of the totem pole, the new hire the person who turned out to not have any productive skills, etc. Not always, but sometimes. And the docs reflect it. Sometimes the example programs are a one size fits all that may have been designed for a common logic block in many chips that has maybe added or removed some features and you are forever scratching your head why the code keeps fiddling with undocumented or reserved bits (those bits probably do something in a prior version of the logic or in a later version of the logic and if you dig around all the products for the company you might find those bits, not that they matter for the chip you are using). I like to change the code and not touch those undocumented bits just to see what happens. One that I really loved (hated) was an api call to start a card where you had to include a path to a firmware file. turns out if you dig through the driver code, the firmware file was for one flavor of card, if you didnt have that flavor of card you didnt need the file at all, but the api entry code required that file to be real, was pretty annoying when I figured that out (rewrote my on driver, much smaller, faster, better suited to what I was doing).
Some bits and some registers you will never ever find out about. Even if you get a job at the company they may not give you access until you have been in the right department the right amount of time. Dont expect that everything you want to know about is available. Some bits are magic, some bit patterns or data are magic, sometimes you just have to go with the flow and do it the way they tell you...check out the visual6502 project, some folks have been waiting their whole career and into retirement to find out why and how some screwy things in that processor worked...
The best thing to do is what you have perhaps already been doing. Buy boards that are geared toward hobbyists, the arduino, the msp430 launchpad, stm32 discovery boards, mbed, raspberry pi, etc. Get the schematic, or look at their web pages and docs to find the part number for the devices, in particular the processor, then go to their page (usually these are chip vendors peddling their product, not always (arduino). Look up that part, find the docs for that part, sometimes many docs, family plus specific chip, etc. Do some googling see if there are open source projects, read those sources. If you are lucky and keep it up you may get to a point in your carreer where you work somewhere that you can influence or drive the designs, docs, samples, etc. Guess what though, even if you worked at Atmel and were the embedded software guru for a microcontroller, you still have to read other companies docs for the other components on the boards you need to build to test or sell your chip. It doesnt end, it is part of the job.
Many sample programs use defines and functions to hide the raw addresses and bits as many programmers want to see things in words or at least not in hex. Personally I prefer the hex or the bits, because I hate having to wade through layers of macros and header files to verify the bits are right. I have the datasheet (hex numbers, bit numbers) on one side of the screen and text editor programming on the other and having the address in hex match the document is a very warm fuzzy feeling. embedded is about accuracy and reliability. In some way shape or form you have to verify your code is rock solid, if you blindly trust too many people with too many layers of macros/defines/functions without checking every bit somehow, you are going to fail, or at least fail more often than someone else in the department that does check and doesnt fail as much. You cant take forever writing your programs of course so you should find your method that combines your preferences for coding style but delivers reliability. One of the things that makes embedded attractive is that freedom you often get, you dont have the rules of the operating system or limitations of application layer access to things, etc. You can do what you want how you want...
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I'm trying to familiarize myself with the embedded field, but also have limited resources in terms of time and equipment to buy.
What's a good language to wrap my head around embedded, without investing too much time leaning an embedded-specific language? I'm most familiar with PHP, Java, Actionscript, but unfortunately know very little C. I remember reading somewhere that someone used PERL to program embedded systems, but not sure if that's really possible.
Can learning be done without needing to buy chips, etc. via simulators or such?
Can someone recommend a simplified roadmap to show how one would get sarted? I'm a little unsure where to even start.
You need to know C (but every programmer needs to know C !)
Most of these platforms have a simulator/emualtor, but since the point is to learn real applications and real problems ( which are all to do with real world timing issues) then you want a real board.
You probably also want an oscilloscope (a very cheap n'th hand slow analogue scope will do) and have some idea how to use it.
Easiest way in is probably Arduino, perhaps more professional but a little harder is launchpad MSP430
There are a few embedded programming lessons that carry over from one platform and style to another, but it is really a broad field. Different processors can require very different tactics, and different applications can dictate both different firmware design tactics and different microcontrollers. Here's some stuff to get you started....
msp430
Texas Instruments has several very inexpensive USB development kits which they call EZ430 and are based on their MSP430 family of micro-controllers. The simplest one has an msp430 f2013, which has 2K of flash program space, 3x128 bytes of usable user flash (another 128 byte page exists, but it's special), 128 bytes of RAM (yes, 128 bytes but it's enough for lots of things), and 16 CPU registers (some of these are special purpose like the Stack Pointer, Instruction Pointer, Status Register, and maybe one or two more). MSP430s also have several memory mapped special function registers which are used for configuring and controlling the built in peripherals. MSP430s are von Newman processors, so everything lives within one address space. These cost about $20us for both the programmer and a removable tab (pc board) containing the msp430 f2013. For about $10us you can get 3 replacement tabs with msp430 2012, which is pin compatible with the 2013 (mostly) and has a few different peripherals. These tabs have an LED, a button, and several large vias (holes in the pc board) which are connected to the pin of the processor. These vias are easy to solder wires into even if you have never soldered before -- due to capillary action the vias just suck the molten solder up and while it's hot you can just jab the end of your wire in there.
They also have a couple more similar kits with 802.15.4 radios. Even if you aren't interested in the radio you may still be interested in these because their programmer also has a UART pulled over from the removable tab and are compatible with the tabs used on the other kits mentioned above. These kits also contain at least one extra programmable board and a battery pack for it. (one of these kits may contain more, but I don't have mine with me right now, and not going to look it up).
They also have a kit that has a programmable watch as the target platform. I've never had one of these, but they have a display, accelerometers, and several other cool things, but this may overwhelm you for your first project. I'd suggest one of the previous kits to get you started with MSP430s.
You can get free C compilers and development environments for MSP430s in the form of IAR's Embedded Workbench kickstart (4 kb program space limited ) IDE, Code Composer Studio (also limited program size, but higher limit, I think), and gcc/gdb for the MSP430. IAR's kickstart is pretty easy to get started with quickly, though it's not perfect. You may find that you have to shut it down, unplug your USB EZ430, restart IAR, and plug back in to get it going again. Or maybe some different order will work better for you.
TI also provides many examples in badly named files (all of their downloadable files go out of their way to be badly named). Be warned -- similar MSP430s may have different device control register interfaces for similar peripherals, which can be confusing. Make sure that any document or example you are reading really does apply to the microcontroller you are using.
other small systems
There are many many other processors families and kits that you can go with, and you should probably at least know a little bit about them.
AVR -- Atmel's 8/16 bit Harvard architecture. Harvard refers to separate address spaces for code and working memory. It has 32 8 bit registers, some of which may be used in pairs as 16 bit registers. It's a very popular and pretty cool processor. Some of the smallest ones only have registers with no extra RAM, which is scary. Atmel also has an AVR32 which isn't at all the same as the AVR. Unless you make use of an existing bootloader capable of loading your new code you will need to get a JTAG unit for these.
8051 -- This is old as the hills and a pain in the butt to use until you finally understand it. It is an 8/16 bit processor, with many more limits on how you go about doing 16 bit math and only has 1 pair of registers which can act as a pointer. It has 3 separate address spaces (stack, global memory, and code) and lots of odd (compared to other architectures) features. The low level stuff might not mean much to you if your are programming in C except that very simple C operations can turn into much more code than you thought they would. You don't want to start on one of thise, most likely.
propeller -- Parallax's very interesting multi-core processor which is very unlike other processors. It has several cores which act mostly independently and can be used to simulate peripherals or do more traditional computational tasks. I've never used one of these, though I'd like to. Just never had a task that seemed to fit it. They have their own high level language to program them as well as the processor's assembly language.
larger systems
After you get out of the 8/16/24 bit processors you start to blur the lines between embedded and desktop level programming, even if it is technically embedded.
AVR32 -- There are 2 main versions of these. One is a Harvard architecture and the other is von Newman. The von Newman version is essentially a better ARM than ARM, but it's not as popular as ARM. As near as I can tell it was designed with "run Linux" in mind, though not tied to it in any crazy way. You used to be able to get cheap development boards for these and code is often almost as easy to load as copying files from one PC to another, though you will probably make use of uboot and tftp to do some work. JTAG is only needed when you mess up the boot loader. I think all of these have support for native JAVA acceleration. www.AVR32.org
ARM -- The most popular embedded processor. There's many versions of these. Some don't have an MMU (memory management unit) and some do. There's too much to say about them. Some version have native JAVA acceleration, though I think that the ARM lords don't freely tell all of the details of how to use it, so you have to find a JVM which knows how to use it. Many vendors make them, including Atmel, Freescale, Intel, and many others.
MIPS -- A very RISC processor. The RISCiest.
There are many others.
Programming styles
I could write 3 books on this but the general rule is make things as simple as the application can let you. An exception to this is that if you can easily make use of an operating system you might want to make use of it if it simplifies your task.
The first thing you need to know when answering this question is "WHAT IS" an embedded system? A GENERAL definition would be a computer system which is dedicated to a single specific purpose. This doesn't limit the type of hardware you can use, as matter of fact "Embedded PCs" have been used for years. The QNX realtime OS has existed since the early 80s and been used in industrial PCs for embedded applications for years. I've personally used in control systems for steel mills XRAY thickness gages. On the other hand I currently use TI DSPs without any OS support and only using 256K of Ram. Another example would be the key fob for your car. Old ones used to use a PIC microcontroller from Microchip. (That's actually the company's name.)
Some people call the IPhone an embedded system, but due to the fact you can load applications to do just about anything I tend to say it's a palm top computer with phone capabilities. An OLD DUMB cell phone that is just a phone, not PDA is an embedded system. That's just a bit of philosophy.
As a general rule there are a handful of concepts you need to grasp for embedded systems programming, and most of them can be explored on a PC.
EDIT:
The REASON why C or C++ is recommended is C itself was designed to do systems programming. C++ maintains all it's advantages but adds capabilities for OOP programming. Some ASM maybe required in some systems. However a lot of chip vendors, such as TI, provide tools basically make it possible to do your entire system in C++.
:END EDIT
ALOT of simple embedded systems look more or less like this:
While(true) // LOOP FOREVER... There is no command prompt
{
// Typically you want I/O to occur on fixed "timebase."
wait(timerTick);
readDigitalIO(&dioStruct);
readAnalogIO(&aioStruct);
// Combine current system state with input values
// and do some useful calculations. (i.e. Analog input to temperature calc)
Process(dioStruct,aioStruct,&CurrentState);
// This can be a serial output/audio buzzer/leds/motor controller
// or Whatever the system REQUIREMENT call for.
driveOutputs(CurrentState);
// The watchdog timer resets your system if it gets stuck.
petWatchDogTimer();
}
There is nothing here that you can't do using the PC. (Well a PC that still has a parallel port anyway. Which is a more or less just a DIO port.) On a simple system without a os this might be all there is. On a RTOS based system you may have several task that all look somewhat simalar to this, but pass data back and forth between the tasks.
The interesting parts come when you have to interface to the hardware on you're own, the first job I had out of college was writing a device driver for a data acquisition board under QNX.
Basic concepts of dealing with hardware, or device drivers (Which you can experiement with by hacking Linux device drive code which is freely avaliable.), most hardware looks to the programmer like just another memory address. This is called "Memory mapped I/O." What does this mean? Lets use a serial port as an example:
// Serial port registers definition:
typedef struct
{
unsigned int control; // Control bits for the port.
unsigned int baudDiv; // Baud rate divider.
unsigned int status; // READ Status bits/ Write resets fifos;
char TXdata; // The head of the hardware TX fifo.
char RXdata; // The tail of the hardware RX filo.
} serRegs;
// Using the volatile keyword to indicate the hardware can change the value
// independantly from the software.
volatile serRegs *Ser1 = (serRegs *)0x8000; // Hardware exists at a specific location in memory.
volatile serRegs *Ser2 = (serRegs *)0x8010; // Hardware exists at a specific location in memory.
// Bits bits 15-12 enable interupts and select interupt vector,
// bits 11-8 enable,bits 7-4 parity,bits 3-0 stop bits.
Ser1->status = 1; // Reset fifos.
Ser1->baudDiv = CLOCKVALUE / 9600; // Set the baudrate 9600;
Ser1->control = 0x1801; // Enable, 8 data, no parity, 1 stop bit.
// Write out a "OK\r\n" message; (Normally this would be a loop.)
Ser1->Txdata = 'O'; // First byte in fifo Transmission starts.
Ser1->Txdata = 'K'; // Second byte in fifo still transmitting first byte
Ser1->Txdata = '\r'; // Third byte in fifo still transmitting first byte
Ser1->Txdata = '\n'; // Fouth byte in fifo still transmitting first byte
Normally you would have a function or an interrupt handler to handle TXing the data, but for example I wanted to point out that the hardware is working while the software keeps going. Basically hardware works like, I write a value to an address and "STUFF" happens independantly of the software. This is perhaps one of the key concepts for embedded programming, how to make the computer effect a change in the real world.
EDIT:
If you actually want to get a cheap board, the current trend from Micro developers is to put a dev kit on a usb thumb stick. This page has info on several, ranging from 8 bits upto ARM architectures: http://dev.emcelettronica.com/microcontrollers-usb-stick-tool
The Cypress PSOC was one of the first to do this with the "FirstTouch Starter Kit." The PSOC is a very unique part in that it has a micro controller and "Configurable analog and digital blocks" that allow you to plop down a ADC, serial port, or digital I/O using a gui and automatically configures you're C app to use it. The PSOCs also are avaliable in DIP packages which makes them easy to use on a prototyper's breadboard.
Picture your embedded controller sitting in a switched-off circuit...
The Vcc power is applied and the reset circuit asserts reset signal.
Clocks have reached running speeds and voltages stabilized, so reset is de-asserted.
Now your controller sets its instruction pointer to the "reset vector," which is physical address 0xE0000000 on this particular chip. The controller fetches the instruction at that location.
Interrupts are disabled, and the first order of business is to initialize registers such as the stack pointer. On some chips, there are flags bits (e.g., x86 direction flag) which need to be cleared or set.
Once the registers and flag bits are set up correctly, it becomes possible for interrupt service routines to run. By now, we must have run code to about location 0xE0000072 when we get to the code which enables interrupts by first toggling some GPIO pins to the external interrupt controller, then enables the CPU interrupts mask.
At this point, the equivalent of "device drivers" are running in the form of interrupt service routines. Assuming the C environment has a library which matches the interfaces of these routines' data structures, by now our boot-loader code can jump to the main() function of some C object code.
In other words, the code which brought us from power-on to main(), and which handles the low-level I/O, is written in the assembler peculiar to the chip you choose. This means that if you want to be versatile at embedded programming, you must know how to implement assembly code starting at the reset vector.
The reality is that hobbyist embedded programming doesn't allow time for implementing all the ISRs and the boot-loader code. For this reason, many people use standard software frameworks available for specific chips. Others use custom-language chips such as the BASICstamp. The BASICstamp is an embedded chip which hosts a BASIC language interpreter on-board. The interpreter and all the ISRs are pre-written for you. The BASIC environment gives you the ability to control I/O pins, read voltages, everything you could do from assembly with an embedded controller, but a bit slower.
As for the language, C is probably the most important language to know. From Java you should be able to adapt, but just remember that a lot of high level Java will not be available to you. Loads of textbooks out there but I'd recommend the original C programming book by Kernighan and Ritchie http://en.wikipedia.org/wiki/The_C_Programming_Language_(book)
For a good introduction to embedded C you could try a book by Michael J Pont:
http://www.amazon.com/Embedded-C-Michael-J-Pont/dp/020179523X
As for the embedded side of things you could start with Microchip, the IDE is OK to develop in with a reasonable simulator, and the c compilers are free for the slightly limited student editions c18 and c30 compilers, the IDE installer will also ask if you want to install a 3rd party HI-TECH C compiler which you could use. As for the processor I'd recommend selecting a standard 18 series PIC such as the PIC18F4520.
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469&part=SW007002
Whatever the chip manufacturer, you have to get to know the datasheets. You don't have to learn it all at once but will need it to hand!
Embedded, like most programming, tends to revolve around:
1) initialising a resource, in this case rather than data being from a data store it is from computer registers. Just include the processor header file (.h) and it will allow you to access these as ports (usually bytes) or pins (bits). Also micro-processors come with useful resources on the chip such as timers, analogue to digital converters (ADCs) and serial communications systems (UARTs). Remember that the chip itself is a resource and needs initialising before anything else.
2) using the resource. C will allow you to make data as global as possible and everything can access everything at every time! Avoid this temptation and keep it modular like Java will have encouraged you to (though for speed you may need to be a little looser on these rules).
But they do have an extra weapon called interrupts which can be used to provide real-time behaviour. These can be thought of a bit like OnClick() events. Interrupts can be generated by external events (e.g. buttons or receiving a byte from another device) and internal (timers, transmissions completed, ADC conversions completed). Keep interrupt service routines (ISRs) short and sweet, use them to handle real-time events (e.g. take a byte received and store it in a buffer then raise a flag) but allow background code to deal with it (e.g. check a received byte flag, if set then read the byte received). And remember the all important volatile for variables used by ISR routines and background routines!
Anyway, read around, I recommend www.ganssle.com for advice in general.
Good luck!
The scope of embedded computing has grown very broad, so the answers somewhat depend on what kind of device you're aiming at. On one end, there are 8-bit controllers with only a few KB of memory, usually programmed entirely in assembly or C. On the other end, processors such as those in your router are fairly powerful (200 MHz and a few MB of RAM is not uncommon) and often run an OS like Linux, which means you can use pretty much any language, though C and Java are the most common.
It's best to buy a real chip and experiment. Most of the work involved is usually in getting to know a device and how to interface with it, so using a simulator kind of defeats the purpose.
What's a good language to wrap my head around embedded, without investing too much time leaning an embedded-specific language?
As everyone will suggest: C. Now depending on how deep are you going to dig into your platform of choice, you may also need some assembly, but don't be scared about that: typically you'll use just a little.
If you are learning C, my personal suggestion is: work as you would do in assembly; the programming language won't give you much abstractions, so think in terms of memory management. When you've learnt how to do it move up towards abstractions and live happy.
C++ is also popular on embedded platforms, but IMHO is difficult unless you know well how to program in C you can also understand what's under the hood of its abstraction.
When you feel confident with C/C++ you can start to mess with embedded operating systems. You'll notice that they can be totally different from your OS of choice (By example not all operating systems have a C standard library, processes and splitting between userspace and kernelspace).
You'll learn how to build a cross compiler, how to mess with linker scripts, the tricks of binary formats and a lot of cool stuff.
For the theoretical point of view there's a lot of stuff as well: if you study Computer Science you can get a master's degree in embedded systems.
Can learning be done without needing to buy chips, etc. via simulators or such?
Yes: many operating systems can be run on simulators like qemu.
Can someone recommend a simplified roadmap to show how one would get sarted? I'm a little unsure where to even start.
Try to get a simple operating system which can be run on emulators, hack it and follow your curiosity. Don't be scared of messing with knotty code.
1) Most of the time for most and usually the lower end embedded system, you need to know C.
And I will still recommend you to get a vanilla development board to get yourself familiar with the work flow and tricky part of working with embedded system like debugging and cross compiling. You will run into trouble if you only rely on emulator.
You can try out The Linux Stamp, it is not expensive and is good for beginner but you do need some prior knowledge on Linux.
2) For high end embedded system, a good example is Smartphone from HTC (CPU speed can reach 1Ghz)or some other Android phone it run fast and you can even code Java on it.
C and the assembly specific to your chip.
No, you really need a real chip. Simulators aren't the real thing. You need to be able to deal with keypress jitter, voltage funkyness, etc.
The Arduino is the current fad for embedded hobbyists. I'm not a big fan of Harvard architecture, personally. But you will find oodles of help out there for it. I use an XCore for my thesis work and I have found it super easy to program multicore stuff. I would suggest starting with an AVR32 and going from there.
As everyone else is saying, you need to know C.
Have a look at AVR butterfly for a cheap development board.
Smileymicros have a simple kit with dev board and book:
http://www.smileymicros.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=41
The soon to ship Raspberry Pi board looks like an incredibly cheap way to get into this field.
Yup, Arduino would be the way to go. Agreed.. Cheap (about $20 to start) and has great API to get started with high level functions. C is a must though, can't avoid it. But if you can program in other languages you'll be all good.
My recommendation is to start shopping at http://www.sparkfun.com lots of examples to work from and helpful hints of what devices to buy.