Decoder FW
Overview

Abstract
All firmware is written in assembler as this gives me maximum control over the hardware. Since my hardware modules are also small and simple, code maintenance remains manageable even for assemblers.
Memory structure
All RTB Mobile Decoders and RTB Bus Modules share the same code base and thus the same architecture. The main difference is the protocol used for communication. RTB Mobile Decoders use DCC/DCC-R over the tracks whereas the RTB Bus Modules communicate over the Real-time Bus.
Note: I currently use AVR microcontrollers for all of my hardware.
The flash memory in divided into three sections,
- ROM (read-only): code for hardware abstraction
- Bootloader (r/w): code for updating the Application section (firmware update)
- Application (r/w): code implementing normal decoder operation
VT100 terminal
Each hardware device has an onboard ROM that can be accessed through the serial connection pads (1MB, 8N1) using VT100 terminal emulation. The terminal commands allow for code updates as well as memory dumps. This eliminates the need for UPDI programmer in the field.
The decoder terminal prompt allows to,
- check the status of the different cpu memory banks
- L = lock space
- R = rom space
- S = signature space
- U = user code
- A = ram space
- B = bootloader space (backup space)
- C = config/fuses space
- E = eeprom space
- F = main flash space
- dump any of the banks in Intel hex formatting
- clear any of the banks
- update/write any of the banks
The ROM bank ‘R’ is read only and can neither be erased nor overwritten. Any other bank is RW enabled.
The terminal is only used during initial programming of the microcontroller. Any subsequent code updates is done via the DCC-R protocol but the terminal will remain as a last resort to recover a ‘bricked’ decoder.
Firmware encoding
Any Firmware file is encoded using the Intel hex format. In addition all files can contain optional metadata for pre-exec and post-exec actions.
- prologue at the very beginning of the file describing the content of file
- epilogue after the firmware data for any required post process actions
The prologue gives the file loader program information about the content of the file. This allows the loader to check for hardware compatibility of the code and prevent sending code to the wrong hardware.
Note: If for some reason incompatible code is sent to the board, the ROM on the board will detect this and refuse to execute that code (see Code Validation). In all cases, the board remains operational and the upload can be repeated.
Example: Bootloader code
- prologue:
@ba16 code is compiled for PCB version ’16’
@bb02 selects memory bank-2
@bc03 selects write operation - epilogue:
@bf00 create backup of code in CPU
@ba16 ; Affinity
@bb02 ; MemBank
@bc03 ; Command
; -----------------------------------------
:020000020900F3
:1000000087C0FFCFFFC7FFCFFFC7FFCFFFC7FFCF1F
:10001000FFC7FFCFFFC7FFCFFFC7FFCFFFC7FFCF90
: ...
:100AB0001B5B34326D2E2E2E5B4150505D1B5B6DE7
:100AC000202D2000FFFFFFFFFFFFFFFFFFFFFFFFC5
:00000001FF
; -----------------------------------------
@bf00 ; Bootloader backup
; *** EOF
Code validation
Firmware boot sequence
For improved reliability, the decoder validates each code section before execution (ROM, Bootloader, Main) during start-up.
- CPU validates ROM code before its executing via CRC32
- ROM validates Bootloader code before its execution via CRC32
- Bootloader validates Application code before its execution via CRC32
Cold/Warm Start
Mobile decoders have to reckon with brief voltage interruptions. In order to ensure a smooth loco movement, the decoder must return to operating mode very quickly after a short power interruption. For this reason, the decoder distinguishes between a cold and a warm start. A warm start (brown-out) is recognized by an intact RAM CRC32. If the RAM checksum is still valid, the decoder skips most of the memory initialization and switches quickly to operation mode.
Run-Level
My mobile DCC decoder implements 4 different run level,
- Level-0: Bootloader mode
- Level-1: Application mode (normal operational)
- Level-2: <reserved>
- Level-3: <reserved>
Flash Structure
Backup Memory
My mobile decoder flash memory is organized as follows,
- ROM: RO memory which can only be written by UDPI
- Bootloader: R/W after reset but set to RO before switching to Application
- Application: R/W memory
All microcontrollers with 64kB flash (or more) use the second memory bank for bootloader backup. Should the bootloader, for whatever reason, become invalid the ROM will recover the bootloader from the backup copy automatically.
Bootloader update
Bootloader code typically remains stable over the lifetime of a product. But should it ever become necessary to update the bootloader, it can be done using the same procedure as updating the application code.
- Pre-Check: Decoder checks for valid bootloader backup
- Download: Download new bootloader code into Application bank
- MemCopy: Verify & copy code received in Application bank to bootloader
- Erase & Reboot: Erase Application bank and reboot decoder
Bootloader recovery
As indicated above, the mobile decoders maintain a ‘golden copy’ as a boot loader backup. Should the boot loader every become corrupted (e.g., during an aborted bootloader update) the decoder ROM will automatically recover the bootloader from the backup code.
- Reboot: Decoder ROM detects invalid bootloader during restart
- Restore: Restore bootloader from backup
- Reset: Reset decoder
