Programming

Handling Delays without Blocking


This entry is part 3 of 3 in the series RTOS Alternatives.

RTOS Alternatives

In an earlier article we looked at the design and implementation of a time-triggered scheduler, but we didn’t consider the implications of actually using it. This can take some getting used to if you have never used such a system before. Imagine that we wanted to create a simple traffic light system… in a more traditional event-triggered design, it might look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
typedef enum {
    LIGHT_RED,
    LIGHT_RED_AMBER,
    LIGHT_GREEN,
    LIGHT_AMBER
} traffic_light_state;

// Event triggered RTOS version.
void Traffic_Light_Controller(void *parameters) {
    while (1) {
        Set_Lights(LIGHT_RED);
        Delay(15000); // wait 15 seconds
        Set_Lights(LIGHT_RED_AMBER);
        Delay(2000); // wait 2 seconds
        Set_Lights(LIGHT_GREEN);
        Delay(15000);
        Set_Lights(LIGHT_AMBER);
        Delay(2000);
    }
}

In a typical RTOS, calling the Delay function will cause the task to become blocked for the given duration (it is often hard to tell from the documentation if the delay is up to or at least the value — I have seen both). Blocking a task involves removing it from the list of tasks that the scheduler can execute (the ready list) and using a context switch to resume another task instead. Obviously this functionality is not available in our simple scheduler, as we do not have the ability to save and restore contexts (which generally requires platform-specific assembly code).

Continue reading Handling Delays without Blocking →


Simple Co-Operative Scheduling


This entry is part 2 of 3 in the series RTOS Alternatives.

RTOS Alternatives

Last time, I looked at some of the simplest alternatives to using a Real-Time Operating System. The problem is, as soon as you need both accurate timing and prioritised tasks, you are out of luck — a foreground/background system would need a separate interrupt source per task priority, which can bring its own problems to the table:

Graph of predictability and functionality against number of interrupt sources

In order to meet our requirements and avoid these issues, we really need a scheduler… luckily, they aren’t too hard to write. The simplest of all schedulers is the Time-Triggered Co-operative (TTC) scheduler, in which tasks are released by a single timer interrupt (hitting the green ‘sweet spot’ on the above graph). This differs from foreground/background scheduling in that tasks are actually executed from the main function and not from the interrupt handler itself.

Continue reading Simple Co-Operative Scheduling →


Super Loops, Sandwich Delays and Foreground/Background Scheduling


This entry is part 1 of 3 in the series RTOS Alternatives.

RTOS Alternatives

As microcontrollers increase in speed and capacity, it’s becoming much more tempting to simply fit a full Real-Time Operating System (RTOS) into a design, without considering other options. This is a shame, because over time a number of alternatives have been developed that can be simple and effective. In this series, I will be discussing some of these, starting with the very simplest — the super loop.

Continue reading Super Loops, Sandwich Delays and Foreground/Background Scheduling →


Central Repositories in Mercurial


This entry is part 3 of 3 in the series Bite-Sized Mercurial.

Bite-Sized Mercurial

As a distributed version control system, Mercurial allows us to push and pull changes between any two repositories in an ad hoc manner. In reality, most projects can benefit from a central server (even if it’s just a repository on the lead developer’s machine) — somewhere accessible to keep an authoritative copy of the project.

In this article, I’ll look at one way to work with a remote central repository in order to share code with other developers.

Continue reading Central Repositories in Mercurial →


Release Management in Mercurial


This entry is part 2 of 3 in the series Bite-Sized Mercurial.

Bite-Sized Mercurial

As I discussed previously there are many possible workflows to use with Mercurial; I will only be looking at some very specific scenarios. For example, it’s often the case that we want to separate work being done on cutting edge development from bug-fixes that get applied to the latest stable release. This is often done with branching — you have a main development branch and a separate branch for every significant release.

As with everything else, there are many ways to branch in Mercurial. I’ll start in this article by looking specifically at the use of named branches.

Continue reading Release Management in Mercurial →


Introduction to Bite-Sized Mercurial


This entry is part 1 of 3 in the series Bite-Sized Mercurial.

Bite-Sized Mercurial

For a while now I have been trying to get to grips with some of the newer version control systems, with a view to learning Mercurial in particular. There are several truly superb introductory articles covering the basics of Mercurial, but I have found them all either too large to digest in one sitting or too lacking in details of daily Mercurial usage. This is a series of short articles about learning the basics of Mercurial from the perspective of one particular workflow. I’ll start with a basic overview of Mercurial for those who are already familiar with Subversion.

Continue reading Introduction to Bite-Sized Mercurial →