Tag Archives: delay

Real Time Counter and Integer Overflow

After writing the article about event-based firmware, I realised there are some misunderstandings how real-time counter are working and should be used. Especially there is a misconception about an imagined problem if such counter overflows. In this article, I try to explain this topic in more detail, using example code for the Arduino IDE.

What is a Real-Time Counter?

A real-time counter is a variable or register which increases at a given time interval. The term real-time may be confusing. It just states the fact this counter ideally does count independently of any other parts of the firmware. Therefore, even if the main code stops at one point and waiting for a specific condition, the real-time counter will get increased in the “background” at the given interval.

How is the Real-Time Counter Implemented?

These counters are usually implemented using a hardware timer and an interrupt. For the Arduino platform, a hardware timer is set to create an interrupt each millisecond. If you can find most of this code in the file wired.c (AVR) or delay.c (SAMD). The following code is a summary of the relevant parts of the simpler implementation for the SAMD platform:

static volatile uint32_t _ulTickCount=0;

unsigned long millis(void)
{
  return _ulTickCount;
}

void SysTick_DefaultHandler(void)
{
  _ulTickCount++;
}

You see the variable _ulTickCount which is an unsigned 32bit integer. It is marked as volatile to tell the compiler, this variable can be modified from an interrupt and reads can not be optimised away.

You can access the current value using the millis() function. Interrupts do not need to be blocked while reading this value, because reading a single 32bit value is an atomic operation for the SAMD platform. It means, it is not possible to process an interrupt in the middle of reading the integer. The interrupt will occur before or after reading the value, but never e.g. after reading the first byte of the integer value. For some platforms, this can be a problem.

The last function is SysTick_DefaultHandler which just increases the variable by one every millisecond.

What is Integer Overflow?

An integer overflow happens, if you add to an integer value and the result exceeds the maximum number it can store. You can easily verify this using the following code:

Continue reading Real Time Counter and Integer Overflow

Event-based Firmware (Part 1/2)

In this article, I explain the event-based approach for writing an embedded firmware. While I use the term event-based, it is similar to events systems used for desktop application but much more straightforward. It is nothing new or innovative; the shown approach is just good practice to keep your firmware modular and extensible.

I will guide you in small iterations, using practical examples, through this complex topic. You can stop at any point and start improving your code to that level of complexity you fully understand and can handle.

What are Event-Driven Applications?

For desktop applications, an event-driven approach is chosen because the software always reacts to events generated by the user. Each movement of the mouse, key and mouse button press and release will generate an event. These events are pushed into a queue and processed in an event loop.

The second important source of events is timers. Either fixed timers, which will e.g. generate an event every 100ms – or delayed timers which will create an event after a defined delay.

For embedded code, we mostly use timers as an event source. If implemented correctly, you can easily generate events from button presses, interrupts or other asynchronous sources as well.

In this article, I will focus on events generated by timers. These will solve most of the problems in firmware. Asynchronous input sources can be implemented using polling to integrate them into the event-based approach.

The Blink Example – Without Events

Let us start with a simple example application, you can find for any platform. For this article, I will explain everything based on examples for the Arduino Uno platform, using the Arduino IDE. I do this because anyone can easily reproduce the examples, and it will remove the additional complexity of the actual hardware access layer from the code.

Nevertheless, the shown concepts are meant to be used on any platform, especially for real-world applications. I try to explain the core concepts to you, so you will be able to apply them in any situation.

The Simple Blink Example

blink1.ino

const uint8_t cOrangeLedPin = 13;

void setup() {
  pinMode(cOrangeLedPin, OUTPUT);
}

void loop() {
  digitalWrite(cOrangeLedPin, HIGH);
  delay(1000);
  digitalWrite(cOrangeLedPin, LOW);
  delay(1000);
}

The Example Explained

If you are not familiar with the Arduino libraries: There are two predefined functions, setup() and loop(). The setup() function is called once after the start to set up things and the loop() function is called endlessly afterwards. This structure is already prepared for the event-based approach.

In the blink example above, I set the pin where a red or orange LED is attached as output, using pinMode() and in the loop, I toggle the output from low to high and back with a delay of one second.

While this example works perfectly, it is not very extensible or modular. If you like to e.g. blink a second LED on another pin, test the states of several sensors and buttons, you will get into trouble.

Introducing a Real-Time Counter to use Time Points

Instead of just blocking the CPU until an amount of time has passed (using the delay function), a better approach is to introduce a real-time counter. Often this is also called real-time clock, which can easily get confused with the special chips which hold the current date and time. This is just a counter which starts at zero at the start of the firmware and is increased every millisecond or another time unit.

If you write a firmware from scratch, you use a hardware timer and interrupts to create a timer like this:

// pseudocode:

uint32_t gTimer = 0;

setup {
    // setup the hardware timer to create an interrupt
    // every millisecond.
}

interrupt {
    ++gTimer;
}

In the Arduino environment, this is already implemented, and there is the function millis() to get the current value of the counter. The counter will flip over at the highest value and restart at zero.

Continue reading Event-based Firmware (Part 1/2)