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
main()
{
  while(1)
  {
    blink_led();
    UART_TXdata();
  }
}

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 http://en.wikipedia.org/wiki/Computer_multitasking. 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

http://blog.vinu.co.in/2011/09/hello-world-asm-msp430g2231.html

http://harijohnkuriakose.blogspot.in/2010/11/translating-c-constructs-to-msp430.html

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 http://karuppuswamy.com/wordpress/2010/10/14/setup-build-and-debug-environment-for-msp430-mcus-using-mspgcc-and-mspdebug-in-ubuntu-linux/

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

Track Every Watt(TEW)


Track every Watt(TEW) is one of the new Open Hardware based project which I am working on for the past few weeks. Track Every Watt is a pluggable device which can be used to measure power consumed by an electrical appliance. The device to be measured is connected to the TEW which has an LCD display which shows power consumed and also some additional information. TEW was inspired from Kill A Watt which is a device that can only measure devices with voltage rating  110V. TEW has a voltage rating of 230V and this is the reason why I started this project.

TEW ProtoType

Track Every Watt can display additional information such as Voltage(V), Current(A), Watts(W), Volt-Amp(VA), Frequency(Hz), Power Factor(PF), Kilo Watt Hour(KWH), Time Elapsed. It uses an Analog Devices Energing Metering IC ADE7763. There is also an application note AN-564 for this IC.

Posted in: GNUduino, Hacking, open hardware, Projects | Tagged under: , | 3 Comments

Experiments with Phoenix-MDK


Today I got a chance to do some hacks on Phoenix-MDK. There was a need of a bootloader for this board. Along with that, we should be able to program the board without hitting any reset switch. The first thing which came into my mind was the arduino boards. They had all the above mentioned features. So I started understanding how the arduino board works, which boot loader is used inside, how reset can be triggered through software etc.

The bootloader used in arduino’s are the optiboot which has a very small footprint (around 512kb) and it was using the serial protocol STK500 for its communication. So I took the optiboot and made some modifications. But it failed. I don’t know where I went wrong and also I bricked one ATMega32 chip.

I had one more ATMega32 chip with me. But this time I was really careful not to brick again a chip. It was really hard to find a bootloader. After a long search I found this page which really helped me a lot – http://wiki.edwindertien.nl/doku.php?id=software:bootloaders

The bootloader can be obtained from http://wiki.edwindertien.nl/lib/exe/fetch.php?media=software:atmegaboot-32.zip. Phoenix-MDK uses 8MHz crystal. So I had to modify a line in the makefile which contains the clock frequency to AVR_FREQ = 8000000L . Thats all. I gave a make and got the hex file.

Below are the steps for flashing the bootloader and using it.

1) Flashing the bootloader using parallel programmer
flashing the hex:
avrdude -c dapa -patmega32 -U flash:w:ATmegaBOOT_168_atmega32.hex
flashing the fuse:
avrdude -c dapa -patmega32 -U lfuse:w:0xff:m -U hfuse:w:0xda:m
2) Testing the bootloader
avrdude -b 19200 -P /dev/ttyUSB0 -pm32 -c stk500v1 -n
This should give a proper response.
3)Uploading a hex file using the serial bootloader
avrdude -b 19200 -P /dev/ttyUSB0 -pm32 -c stk500v1 -U flash:w:a.hex

For the above code to work on Phoenix-MDK, I also had to do some hardware hack. Now the DTR pin is connected to the reset pin so that reset can be done by software. I have to find a software way to reset the chip.

Posted in: Electronics, Hacking, Projects | Tagged under: , , | 3 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

Cooking GNUduino


Today I fabricated the PCB for GNUduino (Arduino made with gEDA). I used screen printing to transfer the PCB layout. Screen printing is another way to transfer the PCB layout to the copper clad instead of the conventional toner transfer method. Download GNUduino  design files

The PCB was successfully fabricated and also tested the LED blink sketch. Everything is working fine.

NOTE: The below shown are only prototype’s to verify the design. High quality PCB’s cab be made with the design files.

Here are some snapshots

The screen printed copper clad’s

screen printed copper clad's of GNUduino

Etching the PCB

Etching GNUduino

After drilling holes

Drill holes in GNUduino

GNUduino is ready

GNUduino - Arduino made with gEDA

Posted in: Arduino, Circuit, Electronics, GNUduino, Hacking, open hardware, Projects | Tagged under: , , , , , , , , | 6 Comments


Older posts