Aurelian Ioan
Published

FreeRTOS on STM32F103C8T6

Running FreeRTOS kernel on STM32F103C8T6 aka "Blue Pill" with the help of Keil uVision IDE from ARM Keil.

BeginnerProtip3 hours20,486
FreeRTOS on STM32F103C8T6

Things used in this project

Hardware components

Jumper wires (generic)
Jumper wires (generic)
×1
STMicroelectronics STM32F103C8T6
×1
SparkFun USB to Serial Breakout - FT232RL
SparkFun USB to Serial Breakout - FT232RL
×1
USB-A to Mini-USB Cable
USB-A to Mini-USB Cable
×1
USB-A to Micro-USB Cable
USB-A to Micro-USB Cable
×1
STMicroelectronics ST-Link V2 STM8 & STM32
×1

Software apps and online services

Arm Keil uVision
FreeRTOS

Story

Read more

Schematics

Keil project

This is the entire project in a zip file. Extract it and run it directly in Keil.

ST-Link V2 SW pins

SW pins layout

STM32F103C8 SW pins

STM32F103C8 SW pins layout can be found on the back of the board

Code

main.c file

C/C++
main.c
/* Include files */
#include <stdio.h>
#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* The task functions prototype*/
void vTask1( void *pvParameters );
void vTask2( void *pvParameters );
/* Task parameter to be sent to the task function */
const char *pvTask1  = "Task1 is running.";
const char *pvTask2  = "Task2 is running.";
/* Extern functions */
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
extern int stdout_init (void);
/*-----------------------------------------------------------*/
/* Global semaphore variable */
SemaphoreHandle_t xSemaphore = NULL; 

int main( void )
{
	/* Board initializations */
        SystemInit();
/* This function initializes the MCU clock, PLL will be used to generate Main MCU clock */  
	SystemCoreClockUpdate();
/* Initialize the serial I/O(console ), making standard output to be send to USART1 */
	stdout_init();
	printf("Initialization is done.\r\n");
	/* Create one of the two tasks. */
	xTaskCreate(vTask1, /* Pointer to the function that implements the task. */
	"Task 1", /* Text name for the task.  This is to facilitate debugging only. */
        configMINIMAL_STACK_SIZE, /* Stack depth in words. */
	(void*)pvTask1,		/* We are not using the task parameter. */
	1,			/* This task will run at priority 1. */
	NULL );		/* We are not using the task handle. */
	
        /* Create the other task in exactly the same way. */
	xTaskCreate( vTask2, "Task 2", configMINIMAL_STACK_SIZE, (void*)pvTask2, 1, NULL );
        /* Create a binary semaphore */
	xSemaphore = xSemaphoreCreateBinary();
	/* make the semaphore token available for the first time */
        xSemaphoreGive( xSemaphore);
	/* Start the scheduler so our tasks start executing. */
	vTaskStartScheduler();
	/* If all is well we will never reach here as the scheduler will now be
	running.  If we do reach here then it is likely that there was insufficient
	heap available for the idle task to be created. */
	for( ;; );
}
/*-----------------------------------------------------------*/
void vTask1( void *pvParameters )
{
char *pcTaskName = (char *) pvParameters;
	/* Task is implemented in an infinite loop. */
	for( ;; )
	{
		/* Take semaphore */
		xSemaphoreTake(xSemaphore,(TickType_t) portMAX_DELAY);
		/* Print out the name of this task. */
	  	printf( "%s\r\n",pcTaskName );
		/* Give semaphore */
		xSemaphoreGive(xSemaphore);
		/* Delay for a period. */
		vTaskDelay( 2000 / portTICK_PERIOD_MS );
	}
}
/*-----------------------------------------------------------*/
void vTask2( void *pvParameters )
{
char *pcTaskName = (char *) pvParameters;
	/* Task is implemented in an infinite loop. */
	for( ;; )
	{
		/* Take semaphore */
		xSemaphoreTake(xSemaphore,(TickType_t) portMAX_DELAY);
		/* Print out the name of this task. */
	  	printf( "%s\r\n",pcTaskName );
		/* Give semaphore */
		xSemaphoreGive(xSemaphore);
		/* Delay for a period. */
		vTaskDelay( 2000 / portTICK_PERIOD_MS );
	}
}

Credits

Aurelian Ioan

Aurelian Ioan

2 projects • 9 followers

Comments