GD32F310 porting FreeRTOS

[GD32F310 development board trial] GD32F310 porting FreeRTOS

Project address:

Environmental description

First, let me explain my environment:
The version of keil5 I use is V5 36. The computer system is WIN10, and the firmware library version used is the latest version 2.2.0 downloaded from the official website (download address of the official website: ), the FreeRTOS version I transplanted is v202112 00 (official website download address:

Development board information

Let's take a look at this development board:
GD32F310K-START evaluation board uses GD32F310K8T6 as the main controller. The LED pin is PA8, which we will use later.

We are looking at the Flash and RAM sizes of 64KB and 8KB respectively. We'll be at freertosconfig Set the size in H.

Transplantation process

You can refer to the materials in my project. All the required documents are placed in the doc folder.
Set up the folder and order the name:

We put the files of FreeRTOS in the Middleware middleware folder.
Downloaded FreeRTOS folder:

We just choose FreeRTOS. There is no need to use Plus. All the folders we need are in FreeRTOS. Copy it to our own project file.

We put the downloaded firmware library and CMSIS files in the Drivers folder we built.

Next, keil5 related settings:
1. Predefined: remember to check C99 support and add header file path.

2. Add files in keil5 according to the of the folder

A little note here is: port C is the file that selects the path in the figure (because our chip is M4 kernel), and we choose heap for memory management_ 4.c

So far, we still lack a FreeRTOS configuration file, freertosconfig h;
The content is:

#include "main.h"
 * Application specific definitions.
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 * See

/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined(__ICCARM__)   ||  defined(__CC_ARM) ||  defined(__GNUC__)
	#include <stdint.h>
	extern uint32_t SystemCoreClock;

#define configUSE_ Preemption 1 / / 1 uses preemptive kernel and 0 uses co process
#define configUSE_ TIME_ Slicing 1 / / 1 enable time slice scheduling (default enabled)
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 	 1 / / 1 enable special methods to select the next task to run
                                                     //Generally, the hardware calculates the leading zero instruction if it is used
                                                     //If MCU does not have these hardware instructions, this macro should be set to 0!
#define configUSE_TICKLESS_IDLE 	         0 / / 1 enable low power tickless mode
#define configUSE_QUEUE_SETS 	         1 / / enable queue when it is 1
#define configUSE_IDLE_HOOK 				 0 / / 1, use free hook; 0, not used
#define configUSE_TICK_HOOK 				 0 / / 1, use time slice hook; 0, not used
#define configCPU_CLOCK_HZ 				 (systemcorelock) / / CPU frequency
#define configTICK_RATE_HZ 				 ((ticktype_t) 1000) / / clock beat frequency, set here as 1000, and the cycle is 1ms
#define configMAX_PRIORITIES 			 (16) / / maximum priority available
#define configMINIMAL_STACK_SIZE 		 ((unsigned short) 128) / / stack size used by idle tasks
#define configTOTAL_HEAP_SIZE 			 ((size_t) (6 * 1024)) / / total heap size of the system
#define configMAX_TASK_NAME_LEN 			 (16) / / task name string length

#define configUSE_16_BIT_TICKS 			 0 / / system beat counter variable data type,
                                            //1 represents 16 bit unsigned integer and 0 represents 32-bit unsigned integer

	#define INCLUDE_xTaskGetHandle 1

#define configIDLE_SHOULD_YIELD 			 1 / / give up CPU usage rights for idle tasks and give them to other user tasks with the same priority
#define configUSE_ TASK_ Notifications 1 / / when it is 1, the task notification function is enabled. It is enabled by default
#define configUSE_MUTEXES 				 1 / / use mutually exclusive semaphores when it is 1
#define configQUEUE_REGISTRY_SIZE 		 8 / / if it is not 0, queue recording is enabled. The specific value is OK
                                            //Maximum number of queues and semaphores recorded.
#define configCHECK_FOR_STACK_OVERFLOW 	 0 / / enable stack overflow detection when it is greater than 0. If you use this function
                                            //The user must provide a stack overflow hook function, if used
#define configUSE_RECURSIVE_MUTEXES 		 1 / / use recursive mutex semaphores when it is 1
#define configUSE_MALLOC_FAILED_HOOK 	 0 / / 1 use memory request failed hook function
#define configUSE_COUNTING_SEMAPHORES 	 1 / / use count semaphore when it is 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1 / / supports dynamic memory request
#define configUSE_TRACE_FACILITY 		 1 / / enable visual trace debugging for 1

#define configGENERATE_RUN_TIME_STATS 	 0 / / enable runtime statistics when it is 1

#define configUSE_STATS_FORMATTING_FUNCTIONS 	 1 / / with macro configure_ TRACE_ When facility is 1 at the same time, the following three functions will be compiled

#define INCLUDE_uxTaskGetStackHighWaterMark 1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES  		 0 / / when it is 1, enable the collaboration. After enabling the collaboration, you must add the file croutine c
#define configMAX_ CO_ ROUTINE_ Priorities (2) / / number of valid priorities of the collaboration

/* Software timer definitions. */
#define configUSE_TIMERS 				 1 / / enable the software timer when it is 1
#define configTIMER_TASK_PRIORITY 		 (2) / / software timer priority
#define configTIMER_QUEUE_LENGTH 		 10 / / software timer queue length
#define configTIMER_TASK_STACK_DEPTH 	 (configMINIMAL_STACK_SIZE * 2) / / software timer task stack size

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet		1
#define INCLUDE_uxTaskPriorityGet		1
#define INCLUDE_vTaskDelete				1
#define INCLUDE_vTaskCleanUpResources	1
#define INCLUDE_vTaskSuspend			1
#define INCLUDE_vTaskDelayUntil			1
#define INCLUDE_vTaskDelay				1

/* Cortex-M specific definitions. */
	/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
	#define configPRIO_BITS       		__NVIC_PRIO_BITS
	#define configPRIO_BITS       		4        /* 15 priority levels */

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 			 0xf / / interrupt lowest priority

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 	 5 / / the highest interrupt priority that the system can manage

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See */
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }	
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
//#define xPortSysTickHandler SysTick_Handler

#endif /* FREERTOS_CONFIG_H */

Lighting test

After looking at the official routine, I'm still a little not used to it. I'm used to the writing of structure. So I've rewritten here and intend to finish the following peripherals one by one. Those who are interested can pay attention to the project.
The lamp pin is PA8

main.c Documents

#include "gd32f3x0.h"
#include "systick.h"

#include "FreeRTOS.h"
#include "task.h"

#include "gpio.h"

#define START_TASK_PRIO		1
#define START_STK_SIZE 		128  
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);

#define TASK1_TASK_PRIO		2
#define TASK1_STK_SIZE 		128  
TaskHandle_t Task1Task_Handler;
void task1_task(void *pvParameters);

    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
int main(void)

    xTaskCreate((TaskFunction_t )start_task,           
				(const char*    )"start_task",        
				(uint16_t       )START_STK_SIZE,      
				(void*          )NULL,                  
				(UBaseType_t    )START_TASK_PRIO,      
				(TaskHandle_t*  )&StartTask_Handler);   

void start_task(void *pvParameters)
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   

void task1_task(void *pvParameters)
		gpio_bit_write(GPIOA, GPIO_PIN_8, SET);
		gpio_bit_write(GPIOA, GPIO_PIN_8, RESET);		

Test video

GD32F310 transplanting FreeRTOS lighting experiment


Thank you for the development board provided by the Jishu community. This is also the first time I use GD32. STM32 has been used before. In fact, the domestic 32 board is very good. Although the ecology of STM32 is indeed speechless, with tools such as CubeMX, it is not necessary. Considering the current price of STM32, I think we can support domestic production more. The ecology of MCU also depends on our developers. The ecology depends on our construction together.

Tags: Embedded system stm32 rtc gd32

Posted by leebo on Sat, 02 Apr 2022 03:47:17 +1030