Tuesday, May 26, 2009

A Fablab opens up in Malmö!

A couple of days ago I read about the Fablab opening up soon in Malmö in the southern part of Sweden. I am really happy about this. At least a couple of my sparetime electronic projects have ended up as a PCB without a box or any mechanics at all. For instance, my MP3 player looks like this:


When I designed the PCB, I was planning to design and build a box afterwards, but I realize I'll never get down to actually doing that, drilling and sawing acrylic plastic is just too cumbersome. With a fablab, I will be able to design and mill my own boxes and mechanics without an enormous budget.

Be sure to check in http://www.fablab.se/.

Wednesday, May 13, 2009

First successful context switch!

A couple of days ago, I ran my first fully working context switches. I have two small test processes that actually just yield to each other:

/* Test processes. */
__attribute__ ((naked)) static void proc0()
{
for (;;)
{
asm("mov r0, 0x1\n\t"
"svc\n\t");
}
}

__attribute__ ((naked)) static void proc1()
{
for (;;)
{
asm("mov r0, 0x1\n\t"
"svc\n\t");
}
}



The code is really an ugly mix of C and assembly, and it seems like the __attribute__ ((naked)) thing completely fools gdb as well. If i put a breakpoint on one of these two functions gdb does not put it on the first instruction, as you would probably want it to. Instead, it puts it one instruction after the first instruction. My guess is that gdb believes the first instruction to be a preamble for setting up the stack frame. But we don't have any stack frames here, due to the special attribute used. The workaround is to put a breakpoint on the address of the first instruction.

The processes put 1 in r0, which means call the yield system call, which in turns causes the simple scheduler to switch to the other process.

Thursday, May 7, 2009

A few shots of the development board.

Yesterday, I took a few pictures of the development board and the OCD module I use.

This is the STM32-P103 from Olimex. It features an STM32F103RBT6 µC from ST Microelectronics. It is based on the Cortex M3 architecture from ARM. The 32-bit CPU runs at up to 72 MHz. Equipped with 128 KiB of flash and 20 KiB of SRAM, it should be enough for many fun projects:



A view from the bottom side, showing the SD/MMC card connector:



The ARM-USB-OCD adapter that I use to hook the board up to my Linux laptop:

Monday, May 4, 2009

stmdb, ldmdb, stmfd etc...

It seems that I am getting quite close to my first working context switch right now. As recommended for RTOS:es on Cortex-M3, my context switches actually takes place in the PendSV handler which looks like this:

    .global    CM3_handler_pendsv
.thumb_func
.extern current_pcb
.extern new_pcb
CM3_handler_pendsv:
mrs r12, PSP @ Get PSP for current process.
stmfd r12!, {r4-r11} @ Save remaining registers.
ldr r0, =current_pcb @ r0 = &current_pcb.
ldr r0, [r0] @ r0 = current_pcb
str r12, [r0, 8] @ Update SP in PCB.
ldr r0, =new_pcb @ r0 = &new_pcb
ldr r0, [r0] @ r0 = new_pcb
ldr r12, [r0, 8] @ r12 = SP for new process.
ldmfd r12!, {r4-r11} @ Restore r4-r11 for new process.
msr PSP, r12 @ Update SP for new process.
ldr lr, =0xfffffffd @ Use process stack when returning.
bx lr @ Return to new process.



Make sure to use the proper variants of the stm and ldm instructions.The fd suffix stands for full descending which means that the stack pointer decreases before data is written to the stack using it. Therefore, the stack is always full ie. the stack pointer always points at valid data. When reading from the stack, the stack pointer increases after the reading operation.