Microcontrollers such as TI MSP430 series and Atmel AVR series are widely used in embedded systems. Microcontroller needs non-volatile memory such as flash memory to hold user application code. This post discusses how flash memory, ROM, and RAM are used in microcontrollers and how flash memory is programmed in field, aka ISP (In System Programming).
Flash memory can be embedded inside microcontroller. Most TI MSP430 microcontrollers fail into this category. Architecture of a generic microcontroller with on-chip flash memory is shown as below. On-chip flash is normally a NOR type flash. Compared to NAND flash, NOR flash supports random read/write access which is suitable to execute code out of it. But its density is low so it is of high cost to keep large side NOR flash inside microcontroller.
When microcontroller powers up, CPU first fetches code from ROM or a special flash which is pre-programmed at manufacturer and holds critical code such as BSL (bootstrap loader). CPU checks if on-chip main flash is programmed and if so CPU can execute code out of flash directly.
NOR flash is normally slow compared to CPU and interconnect bus speed. This can tremendously degrade overall performance. On-chip RAM can be used to speed up. CPU first copies flash code into RAM and then executes code out of RAM. This approach requires extra RAM to hold instructions. But RAM density is normally much higher than NOR flash. The extra chip area increase due to this extra RAM is not much compared to existing NOR flash area. If extra RAM size/area is a concern, sometimes a compromise can be made. Code that are frequently used or need high execution speed are copied to RAM and others can still execute out of flash.
Copying code from flash to RAM can be done by CPU itself or by DMA instructed by CPU.
External flash is used if large amount of user code needs to be stored. External flash is likely NAND type flash which has higher density and therefore is much cheaper than NOR flash of the same size. SPI bus is normally used to interface to standalone flash memory. NAND flash doesn’t support random access so execute code out of it is no-no. Code in external NAND flash needs to be copied to internal RAM at power up and CPU executes code out of internal RAM.
Then the next question is how to program on-chip or external flash memory in field. A good reference is MSP430 Memory Programming User Guide
Most MSP430 devices have nonvolatile flash memory that can store data or machine code for execution. This flash can be written using three primary methods: the MSP430 CPU/DMA, JTAG, or the bootstrap loader (BSL).
Below illustrates a hypothetical scenario that UART is employed to program on-chip flash. At power up, CPU first executes code out of ROM or a special flash. CPU enters idle mode and waits for command from user. User sends a command to CPU through UART. This actually is a complicated process. First uart module receives data, saves data in some FIFO, and interrupts CPU to read FIFO and process data. It is also possible UART saves data in FIFO but requests DMA to move data to RAM. Then when all data related to that command is in RAM, DMA interrupts CPU to read data out of RAM and process it.
CPU interprets the UART command and realizes it is about programming flash. Then CPU executes BSL code which basically uses in-coming UART data to program flash.
Programming external flash is similar.
MSP430 also supports use SBW bus to program flash memory through JTAG logic.
We can try to integrate above diagram into our generic microcontroller architecture. One way is to have a dedicated access channel from JTAP controller to flash controller. This allows JTAP controller to program flash.
Another way is more flexible. JTAP controller can drive a JTAP bus master module. Through this module JTAP can access any slave on interconnect bus. This allows JTAP controller not only to program flash but also access other modules on bus.