Jeffrey's Log

Archives | Subscribe

Older posts

Multitask scheduler for MSP430F5529 launchpad

One of the best ways to gain some good understanding about a concept is by doing experiments rather than reading theory about it. Multitasking in operating system was one such concept for me. In the beginning stages of learning C programming, I used to wonder how operating systems were implemented. At that time I knew that operating systems were written in C language but never knew how.

Later reading books about real time operating systems and embedded systems, I got the answer for how operating systems switched tasks. Its known as “context switching“. Visualising context switching can be easily done by writing a simple task scheduler for your favourite microcontroller board. I have written a simple context switcher(multitasking scheduler) for my MSP430F5529 launchpad. I will explain about it in this post.

What is multitasking, scheduling and context switching ?

Mutlitasking is a method where a CPU does multiple jobs at the same time. If you have programmed microcontrollers in C, you would have written a main() function inside which you put what you want the CPU to do. What ever you write inside it will be executed line by line by the microcontroller. Just imagine you have written a program to blink a LED and also to send data via UART inside a while(1) loop.

//pseudo code

Here the microcontroller will first blink the LED, then it will stop blinking the LED, then it will send data via UART, then stop sending the data, then again it would start blinking the LED… and this process goes on. But what if you want both of these to be executed in parallel i.e blink LED and in parallel send data ? Yes, this is possible. This is way of doing multiple tasks at the same time is called as multitasking. You can read more from here The multitasking scheduler which I have written here is preemptive.

Actually a CPU is not executing multiple instructions at the same time. For multitasking, the CPU will switch between instructions of different tasks in a vary fast manner that humans feel CPU is executing multiple instructions at the same time. This way of switching between tasks is known as context switching.

Which task should be executed next(i.e to be context switched) is decided by the scheduler. Once the time has reached, the scheduler will trigger a context switch. Scheduler gets support from a timer to trigger the context switching i.e if you want to switch between tasks every 1ms then the timer is configured for 1ms. Every 1ms a interrupt will be triggered which will call the scheduler.

But how to do this ?

A CPU does manipulation on the data stored in its registers. When you write a C program, the C compiler will generate assembly instructions to manipulate data on these registers. In some cases when you write large programs, the available registers wont be enough. In that case, stack is used. Extra data are stored in stack and when required will be moved to registers for the CPU to use. If you want to know how a C code uses the CPU registers and stack, read these links

So data stored in CPU registers and data stored in stack are very important. If you have multiple task, you need to divide the RAM to those tasks. E.g. If you have 4kB of RAM, you may divide it to 1kB per task. Some RAM is also required(in our case the leftover 1kB) for scheduler, initialisation routines etc.

When we write a C program for our microcontroller, there is a main loop where we write the task for the CPU. Just imagine we have two functions (as I said when I explained about multi tasking) which needs to be executed in parallel. C code that we have written will be executed line by line one after the other. But if we have a scheduler which could do context switching, then we can achieve parallel execution.

As I said before, inside the main() function whatever we write will be considered as a single task. But while implementing scheduler, we will write our scheduler code inside the main() function (and also partially inside timer interrupt service routine which I will explain later). Tasks which have to be multi-tasked should be written as separate functions. In order to context switch at particular intervals, a timer should be configured. In the timer’s interrupt service routine we should write the code to switch to the next task. Before switching to the next task, we must backup the values kept in the CPU registers and stack so that next time when this old task again comes, we need to load back these values into the CPU registers and stack. The function address will be loaded to the program counter so that the CPU will execute that function.

You should read these two chapters from the FreeRTOS which has pictorial representation of context switching

Section 1 – RTOS fundamentals

Section 2 – RTOS Implementation Example

Lets implement our Multitask Scheduler !

MSP430F series uses 20-bit address space. Some other MSP430 series has a 16-bit address. So if you want to migrate it to such architectures, make sure you make necessary – The extra 4bits in addition to the 16bits are stored along with status register(SR) which needs to be corrected. My scheduler is currently designed to run on MSP430F5529 Launchpad. It can handle upto 3 tasks(but we can alter it as required). Tasks will be switched in round robin way. MSP430F5529 has totally 8 kB of RAM out of which each task will get 2kB and pending 2kB is used by the scheduler.

Before doing the scheduling, we need to do certain initialisations. First we need to switch off the watchdog timer. Then we will clock the CPU to its highest frequency so that it runs at its best speed. Then we have to initialise the RAM(I will explain this in the below paragraph) for each task. The watchdog timer will be used to call the scheduler periodically. It needs to be configured in timer mode(otherwise each watchdog interrupt would trigger a CPU reset). The watchdog timer will be automatically enabled when we load our first task for execution. After all these, we are ready to load our first task. For this we have to load the stack pointer(SP) with the first tasks initialised RAM. After this the watchdog timer will be enabled and also the CPU will start executing the first task. In between the interrupt will be triggered when the timer has elapsed. This will call the scheduler which has to first save the current CPU registers, then has decide which task has to be loaded next and then trigger a context switch.

RAM initialisation and context switching are the most trickiest part since you need to know the hardware well. I will first explain about RAM initialisation. As we know for the CPU to execute, there are few registers it requires (i.e R0 to R15). These register should be filled with proper values for attaining code execution.

Below are the CPU register of MSP430F5529 and its uses.

# CPU Register Name Use
1 R0 Program Counter (PC) Holds the address of the next instruction to be executed
2 R1 Pointer Stack (SP) Holds the address of the last value pushed to stack
3 R2 Status Register Can control the CPU and also holds CPU flags
4 R3 Constant Generator Registers (CG1 and CG2) Not our interest. Refer datasheet for more info
5 R4 – R15 General Purpose Registers Used by CPU for data manipulation

Out of these, R0, R1, R2 and R4 to R15 are the most important registers which have to be backed up. Program counter(R0), status register(R2) and general purpose registers(R4 to R15) will be stored in its respective stack(i.e RAM location). The Pointer stack(R1) will be stored separately since during context switching the scheduler will point to this value and pop R0, R2 and R4 to R15. During the RAM initialisation(i.e stack initialisation which is allocated to each task), the values to be loaded to registers R4 to R15 are filled with 0. Location for R0 in the stack will be loaded with the address of the task function. Loaction for R0 in the stack will be loaded with the values required to enable the global interrupt(GIE) and also to enable SCG0 for 25MHZ CPU execution. Reading the source code will give more clarity.

Once the task has started execution, the CPU will automatically increment the program counter(PC) register. So each time when we come back to a task after context switching, the execution is continued from the location where the task had reached. We wont start from the beggining of the task each time. During RAM initialisation, we didn’t store the pointer stack(SP) in the stack along with other registers. This is stored separately. When a task was executing, it would have pushed some values into stack. Stack pointer(SP) register will have that value. While context switching we will save this value so that next time when we come to this task, we will again load this value to stack pointer(SP) register so that the execution is resumed from the place where we stopped.

Enough talk! Show me the code!

I have checked in the code to my github repo. Its an completely open source scheduler. Feel free to use it and learn more. I have made the code self explanatory. Enjoy!

There are three tasks – first task for blinking the red LED at a particular rate, the second for blinking the green LED at a particular rate and last one for reading both the buttons. When you press the button, you could toggle the blinking of both the LED’s. Buttons are not properly detected due to software debouncing issue.

NOTE: If you want to program your MSP430F5529 launchpad using GNU/Linux, read my previous post – Running MSP430F5529 Launchpad using GNU/Linux

Further development:
1) Try to send data via serial port in a task
2) Find a way to compute the stack consumed by each task and send this value via serial port
3) The scheduler is premptive. Try implementing a cooperative scheduler.
4) In cooperative scheduler, also add a feature to find the free time left in a process.

If you want to debug your code, read this – Debugging with msp430-gdb using mspdebug as gdb proxy

Posted in: MSP430, operating systems, Projects, tutorials | Tagged under: , , | 10 Comments

ATMEGA32U2 board using gEDA

Two years before I had designed a mini development board for AT90USB162. There was a small mistake in that board. It didn’t have the 1MFD capacitor connected across the UCAP (PIN 27) and ground. Because of that the board was not detected while connected via USB. Last month I thought of repairing that board and do some USB projects. I ordered samples of ATMEGA32U2 from ATMEL. Thanks ATMEL for the samples.

Today I did a small hacking on the board. I added the capacitor as needed by USB. Now the board is working fine. There came the next problem. GCC-AVR version which I had, didn’t support ATMEGA32U2. Also for loading the hex into the controller, I used the dfu-programmer. Since I had installed it from the Ubuntu repository, dfu-programmer was of older version and it also didn’t support ATMEGA32U2.

After a few Google search, I found that if you compile for AT90USB162, the hex generated is supported by ATMEGA32U2. So I wrote the C code and compiled it for AT90USB162. Next task was to make the dfu-programmer to work. The only solution was to get the latest code and compile it. Below shown is the way to compile the dfu-programmer from source

$ mkdir dfu-programmer
$ svn co dfu-programmer
$ cd dfu-programmer/dfu-programmer
$ ./
$ ./configure
$ make

Once installed, flashing the controller is very easy. First we have to bring the controller into USB bootloader mode. For that first press and hold the RESET button. Then press and hold the HWB button. Now release the RESET button and then release the HWB button. This will bring the controller into USB bootloader mode. Now we can issue the following instructions to flash the controller.

$ dfu-programmer atmega32u2 erase
$ dfu-programmer atmega32u2 flash blink.hex
$ dfu-programmer atmega32u2 reset

This is an Open Hardware project and I will soon post the schematic and PCB layout once adding the missing capacitor in the old design. Below shown is the snap shot of the board.

Posted in: Circuit, Electronics, open hardware, tutorials | Tagged under: , , | 5 Comments

LPC2148 (ARM 7) Test bench setup

This is my LPC2148 (ARM 7) test bench setup.

The LPC2148 header board was bought from Rhydo Labz. You cannot directly power up and start to use. It lacks communication interface. To flash the controller, you need a serial port or a JTAG port. Since this board doesn’t have these port connectors, you need to solder them. So it might be hard for a newbie.

Instead of this board, you can try the BlueBoard which has all the port connectors. I will recommend this for a newbie. I hope that board is worth for its price.

The next thing which you need is a power supply to power the board. You can build your own power supply (If someone needs to know how to build a power supply, I will write a tutorial. But please put a comment in this post saying that you need the tutorial.) ,or you can buy 5V DC power supply (adapters).

Once the board is powered up, it can start to execute your code in its memory. But a fresh controller wont be having any code in its memory to execute. You need a programmer to load the code into its memory. But the LPC series controllers have built-in serial boot-loaders. These boot-loaders can get the code from the serial port and write into its flash memory. So you don’t need a programmer.

To program the controller using the serial boot-loader, you just need to connect the controller to the host PC and the host PC needs to run a serial programmer software. You can get a lot of serial programmer software for LPC controllers. Some of them are

So thats all. Power up the board and connect the serial port to the controller. Run the serial programmer software in the PC. You controller will execute the code flashed into its memory.

But wait. From where you can get the hex file to flash into its memory? Its simple. You just need a cross-compiler. To the cross-compiler, you just need to feed your C source file. It will compile and give you *.out files, which later can be converted into *.hex files.

I will soon try to post a wiki page about how to compile and flash the code into the memory.

Posted in: Circuit, Electronics, Embedded Linux, GNU/Linux, Hacking, open hardware, Projects, tutorials | Tagged under: , , , , , | 6 Comments

Link Pad

Some useful links 😉

1) Introduction to Robotics (Free Course from MIT)

This is a free course about Robotics from MIT. This course gives a small introduction to robotics. Course is made for intermediate users(Not that simple to understand if you don’t know mathematics). You can find more such free courses from MIT in MIT OCW.

2) Linux Device Drivers

Learn about Linux Device Driver

3) ARM Projects

Some ARM projects

4) Learn Git

Know some basics about Git which will become useful in future.

Posted in: Electronics, Embedded Linux, Mathematics, Open Course, Robots, tutorials | Tagged under: , , , | Leave a comment

Current Sinking & Current Sourcing Tutorials

I have seen some web pages defining that current sinking and current sourcing are same. But the truth is that they are different. This is a tutorial about current sinking and current sourcing in Integrated Circuits(IC).

Current Sinking & Current Sourcing Tutorials

Posted in: Circuit, Electronics, tutorials | Tagged under: , , | Leave a comment

Older posts