Assembler on Arduino — Part 2

asm_symSome time ago I wrote this article about the build chain for assembler programming on Arduino. The article contained a simple blinking LED example. In the meanwhile I got several questions about Arduino and assembler.

This article is about a more mature real-world blinking LED example. You can download the full source package here which is discussed in the following.

This new implementation is totally different from the original one.

  1. The implementation facilitates interrupts and a timer and the CPU is set into sleep mode during idle time.
  2. The code is split into several source files and sections using assembler directives. Thus, it is more modular and clear and the linker is able to automatically locate specific parts of the code to the appropriate locations within the physical memory of the micro controller.
  3. The package also includes a Makefile which properly assembles and links the program and finally creates an Intel hex file for the flash utility. The source files have the extension .S meaning that they have to be pre-processed by cpp. The advantage is that we can now use #include files containing all macros about AVR SFRs and so on. Gcc will automatically call cpp and then as.

Code Structure

The initialization of the micro controller is done in init.S. In section .vectors at the beginning are the interrupt vectors. In the example this is the reset vector and the timer interrupt.

Directly behind in the section .ctors there’s the most fundamental initialization of the stack and the system status register SREG (lines 20 – 25). Behind it all other basic system initialization tasks are done. This is setting up the output port for the LED (lines 27 – 28) and initializing the timer interrupt (line 30). Finally the main function is called through the RETI instruction which also globally enables the interrupts.

All functions which are relevant for the timer are found in timer.S and are located into the .text section. These functions are the initialization routine init_timer, the interrupt handler t0_handler and user land1 function wait_timer. The function tests for a flag variable and returns if it is set (lines 63 – 69). Otherwise it switches the CPU into sleep mode (line 71) until the next interrupt. This saves a lot of energy. The two variables used by these functions are placed into the .data section.

The actual main program is found in main.S. The code is placed into the .text section as well. The function does in an endless loop just call wait_timer which wait a specific amount of time (which is currently hard code) and then inverts the output port.

To build the project just call `make` and then `make upload` to flash it to your Arduino. Have a look at the Makefile for more information about building.

Have phun playing with Arduino!

  1. Actully, the ATmega core used on the Arduino boards does not support different modes, i.e. user and kernel mode. Nevertheless, I tried to organize the code in such a way.