This page covers how the service mode firmware updating logic is implemented in software.
The Atmega2560 has a capacity of 256KB of flash memory which is divided into pages of 256 bytes. 8 KB of this sits way at the back and is reserved for the bootloader: software that runs before the sketches execute. The service mode uses an additional, artificial memory section: the service mode routine. A single page (256 Bytes) at the very beginning of the bootloader section is reserved for a piece of software that is capable of writing the other 7936 bytes when instructed to do so by the bootloader. In a diagram, this looks as follows:
During normal operation, the execution begins at the first instruction, which is inside the service routine. This very first instruction jumps exactly 256 bytes forwards, skipping the entire service routine logic, starting to execute the main firmware logic. Nothing about the existence of the service routine will be noticed, it doesn’t run and sits idle waiting for a potential firmware update in the future.
When the SERVICE_MODE command is issued by the computer, the main firmware jumps back to the second instruction inside the service routine. This time, there is no jump back, and execution of the main service routine begins. Execution never leaves the service routine’s 256 bytes. The processor is forever stuck inside the region until the chip is reset. LED 13 is turned on to indicate this.
Since the main firmware executed before the service routine did, the USB communication, watchdog timer and the stack are all already initialized. The service routine is now free to receive data from USB and program the rest of the memory.
Once the service routine is executed, the fun begins. The computer can send several simplistic messages to the routine through USB, to which the service routine responds with an exact echo. If you send it ‘HELLO’, you will get ‘HELLO’ printed back. This is the way service routine connection can be verified. All except the 256 bytes of the service routine can be written to. The following commands are supported:
- a[4-byte address] – Set the address in flash memory to read or write. Replies with an echo.
- w[256 bytes of data] – Write the page at the last-set address. Replies with an echo.
- r[256 bytes of value 0] – Read the page at the last-set address. Replies with r and then the page data.
Service Mode Protection
If the device is reset while programming the firmware, the firmware is put in an unknown state. Since the firmware is required to jump into the service routine, you would have a problem! The firmware would run and crash, making it impossible to correct the incomplete write. To prevent such issues, service mode protection is engaged by the computer.
The 256 bytes directly after the service routine are written first to initialize the stack, USB communication and watchdog timer and finally jump into the service routine. The result is that, if you reset the device while not all firmware is written, the device automatically runs the service routine. The computer can pick up at a later time and attempt again to flash the firmware.
To make sure protection is best, the data is written in reverse order. First the last bytes of the firmware are written, the first bytes last. This means the protected area is written at the very last moment.
You need the computer to do any programming at all. So what is the role of the computer in all of this?
The primary role of the computer is to establish a connection with the STK500-based firmware currently on the device. Once that is established, the SERVICE_MODE (0xEF) extended STK command can be issued. The firmware does not respond to this, instead directly going into the service routine.
Once inside the service routine, the computer essentially has full control over the memory on the chip using the a, w and r commands. The following is done by the computer, in order of operations:
- Enter STK500 processing loop
- Issue SERVICE_MODE (0xEF) STK500 command
- Verify connection by sending HELLO token. Check that HELLO is received.
- Set address (a) to BOOT_START (0x3E000)
- Read (r) page to read the service routine data
- Verify that the service routine data matches up with the firmware we are going to program
This is important, because we can not program this area of flash memory
If it does not match, abort. Unsupported firmware version.
- Set address (a) to BOOT_START (0x3E000) + 256
- Write (w) out the protection data (initialization and jump back to service routine)
- Write out pages in reverse order:
- Set address (a) to the address of the first byte of the 256-byte page to be written
- Write (w) out the page data
- Reset the device
- Resume STK500 processing loop