samedi 13 octobre 2012

Doing multiTask application using an STM32 using CoOS and stm32 discovery board

Have you ever wanted to do the same thing at the same time to win more time?! Cleaning the house while doing your homework :D that would be very helpful.
Working with embedded systems made crucial to deal with different tasks at the same time while having (most of the time) only one CPU that can handle only one task at a time.
To schedule between different tasks, embedded systems use RTOS (real time operating systems) which is in same how a little software is responsible to manage all the different tasks that want to use the CPU.

I found lately a wonderful tool to programme STM32 microcontrollers which is CoIDE from Coocox. It's based on the eclipse which makes programming the STM32 a lovely journey you don't want to miss.
 You can download Cocenter from here which contains all the other great software that come with CoIDE like CoOS which is a free RTOS that we will use it in this Tutorial.


So... Our mission is to blink a led in an infinite task and to watch for the value of the button in an other task.
I used the STM32 discovery board that contains an STM32F100RB.


After creating a project in your CoIDE, make sure to add the GPIO, RCC and CoOS libraries from the repository.

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include <CoOs.h>

#define STACK_SIZE_DEFAULT 512

OS_STK task1_stk[STACK_SIZE_DEFAULT];
OS_STK task2_stk[STACK_SIZE_DEFAULT];

void initializeBoard(){

        GPIO_InitTypeDef GPIO_InitStructure_Led;
        GPIO_InitTypeDef GPIO_InitStructure_Button;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//for LEds
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//for buttons

        GPIO_InitStructure_Led.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
        GPIO_InitStructure_Led.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure_Led.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_InitStructure_Button.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure_Button.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure_Button.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOC,&GPIO_InitStructure_Led);
        GPIO_Init(GPIOA,&GPIO_InitStructure_Button);

}

void task1 (void* pdata){
        while(1){
                GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);
                CoTickDelay (10);
                GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET);
                CoTickDelay (10);
        }
}

void task2 (void* pdata){
        int i;
        while(1){
                i = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);
                GPIO_WriteBit(GPIOC,GPIO_Pin_9,i);
        }
}

int main(void)
{
        initializeBoard();
        CoInitOS();
        CoCreateTask(task1,0,0,&task1_stk[STACK_SIZE_DEFAULT-1],STACK_SIZE_DEFAULT);
        CoCreateTask(task2,0,1,&task2_stk[STACK_SIZE_DEFAULT-1],STACK_SIZE_DEFAULT);
        CoStartOS();
    while(1);
}