Archives

Page Ranking

A Matter of Interrupts and Mutual Exclusion - Part 1

Aside form programming skills the embedded developer has to think of solving problems in a different mindset than the average PC programmer. A good example is the interrupt handling that the embedded developer has to deal with directly. I’m not going to explain what an interrupt is or why interrupts are important in real-time programming: there are plenty of books or tutorials explaining these concepts and their usefulness. I will rather show a typical example where interrupts are used extensively to achieve a responsive and trouble free communication over a serial interface — USART in particular — in two distinct situations: with and without an RTOS. As a side note, most of the examples or code snippets were tested on a STM32F103 evaluation board, but I’ll try to be as generic as possible.

Let’s assume that we need to implement the function GetChar() that receives one byte from the serial interface USART and return it when GetChar() is invoked. Many microcontrollers have a simple serial interface equipped on the receive side with one de-serialization register and one data holding register: this means that while one character is in the de-serialization process, another one may be already available in the data holding register from a previously received character. When the character is de-serialized and sent to the data holding register the receive status flip-flop (Rx Stat FF) is set. When the CPU reads the byte available in the data holding register the Rx Stat flip-flop is reset. The receive status flip-flop is usually available as part of a status register (meaning that the data is ready) and can also generate an Rx interrupt. If the CPU does not read the character in the data holding register in time and another one is de-serialized, the incoming character will overwrite the previous one and that character is lost (the so-called overrun error).

Simple Rx block diagram

As we can see, the CPU has two options: either polling (i.e. wait in a loop for the data to become available by reading the Rx Stat FF) or by using interrupts (when Rx Stat FF is set the USART generates an interrupt getting CPU’s attention and forcing it to read the character). While polling looks simple and straightforward, it is inefficient and difficult to handle in complex systems where the CPU must execute many other tasks. As consequence, the second solution will be discussed here.

From the above, we observe that one obvious fact is the requirement to handle all these interrupts in a way that will ease the CPU burden to ask all the time for the availability of one single byte. The solution is to store the incoming characters into a buffer and let the CPU get them from this reservoir until it becomes empty; only in such a situation, if the CPU cannot continue without data, it will wait until more data will be available. With or without RTOS and multitasking, this “reservoir” placed between the receive interrupt handler and the GetChar() needs to be organized as a first-in-first-out buffer (FIFO). Between the USART receiver and the CPU via GetChar() it was established a producer-consumer relationship that I intend to study in more detail.

FIFO Buffer

The role of the FIFO buffer is to temporarily store the characters until the CPU becomes available to grab them. While the characters arrive slowly the CPU can drain the FIFO buffer quickly and become available for other tasks until the buffer gets full (or almost full) again. As a side note, most modern USARTs have their own internal FIFO implemented in hardware; this way they will generate interrupts less frequently helping the system to increase in efficiency. A hardware FIFO is helpful but it small compared with the FIFO buffer implemented in the software as suggested above. That is why in the next post I will examine the implementation of such a FIFO buffer together with its real-time programming aspects.

1 comment to A Matter of Interrupts and Mutual Exclusion – Part 1

  • dhanraj

    Simple to understand. nice work.

    “Aside form programming skills the embedded developer has to think of solving problems in a different mindset than the average PC programmer.”

    Good point..