使用Platformio平台的libopencm3开发框架来开发STM32G0,下面为使用FreeRTOS系统。
1 新建项目
在PIO主页新建项目,框架选择libopencm3,开发板选择 MonkeyPi_STM32_G070RB;
新建完成后在src目录新建主程序文件main.c;
然后更改项目文件platformio.ini的烧写和调试方式:
1upload_protocol = cmsis-dap
2debug_tool = cmsis-dap
2 添加FreeRTOS源码
在freertos网站:https://www.freertos.org/a00104.html 下载好源码,这里下载最新版202112.00;
添加源码到项目:
直接拷贝源码下的FreeRTOS文件夹到项目的lib目录中;
添加到项目编译
在lib目录的FreeRTOS文件夹下新建 library.json 文件,内容如下:
1{
2 "name": "FreeRTOS",
3 "version": "202112.00",
4 "build": {
5 "flags": [
6 "-Isource",
7 "-Isource/include",
8 "-Isource/portable/GCC/ARM_CM0",
9 "-Isource/portable/RVDS/ARM_CM0"
10 ],
11 "srcFilter": [
12 "+",
13 "+",
14 "+"
15 ]
16 }
17}
添加FreeRTOS配置
从FreeRTOS源码下的demo目录中拷贝一个FreeRTOSConfig.h文件到 lib/FreeRTOS/Source目录,并更改为如下内容:
1/**
2 * @file FreeRTOSConfig.h
3 *
4 * http://www.FreeRTOS.org
5 * http://aws.amazon.com/freertos
6 *
7 */
8
9#ifndef FREERTOS_CONFIG_H
10#define FREERTOS_CONFIG_H
11
12/*-----------------------------------------------------------
13 * Application specific definitions.
14 *
15 * These definitions should be adjusted for your particular hardware and
16 * application requirements.
17 *
18 * These parameters and more are described within the 'configuration' section of the
19 * FreeRTOS API documentation available on the FreeRTOS.org web site.
20 *
21 * See http://www.freertos.org/a00110.html
22 *----------------------------------------------------------*/
23
24/* USER CODE BEGIN Includes */
25/* Section where include file can be added */
26/* USER CODE END Includes */
27
28/* Ensure definitions are only used by the compiler, and not by the assembler. */
29#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
30 #include
31#endif
32#define configENABLE_FPU 0
33#define configENABLE_MPU 0
34
35#define configUSE_PREEMPTION 1
36#define configSUPPORT_STATIC_ALLOCATION 0
37#define configSUPPORT_DYNAMIC_ALLOCATION 1
38#define configUSE_IDLE_HOOK 0
39#define configUSE_TICK_HOOK 0
40#define configCPU_CLOCK_HZ ( ( unsigned long ) 64000000 )
41#define configTICK_RATE_HZ ((TickType_t)1000)
42#define configMAX_PRIORITIES ( 7 )
43#define configMINIMAL_STACK_SIZE ((uint16_t)256)
44#define configTOTAL_HEAP_SIZE ((size_t)1024*16)
45#define configMAX_TASK_NAME_LEN ( 16 )
46#define configUSE_16_BIT_TICKS 0
47#define configUSE_MUTEXES 1
48#define configQUEUE_REGISTRY_SIZE 8
49#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
50
51/*Software timer related definitions. */
52#define configUSE_TIMERS 1
53#define configTIMER_TASK_PRIORITY 5
54#define configTIMER_QUEUE_LENGTH 10
55#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
56
57/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
58/* Defaults to size_t for backward compatibility, but can be changed
59 if lengths will always be less than the number of bytes in a size_t. */
60#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
61/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
62
63/* Co-routine definitions. */
64#define configUSE_CO_ROUTINES 0
65#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
66
67/* Set the following definitions to 1 to include the API function, or zero
68to exclude the API function. */
69#define INCLUDE_vTaskPrioritySet 1
70#define INCLUDE_uxTaskPriorityGet 1
71#define INCLUDE_vTaskDelete 1
72#define INCLUDE_vTaskCleanUpResources 0
73#define INCLUDE_vTaskSuspend 1
74#define INCLUDE_vTaskDelayUntil 0
75#define INCLUDE_vTaskDelay 1
76#define INCLUDE_xTaskGetSchedulerState 1
77
78/* Normal assert() semantics without relying on the provision of an assert.h
79header file. */
80/* USER CODE BEGIN 1 */
81//void vAssertCalled(const char *file, int line);
82//#define configASSERT( x ) if( x == 0 ) { taskDISABLE_INTERRUPTS(); vAssertCalled(__FILE__,__LINE__); for(;;); }
83/* USER CODE END 1 */
84
85/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
86standard names. */
87#define vPortSVCHandler sv_call_handler
88#define xPortPendSVHandler pend_sv_handler
89
90/* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick,
91 to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
92
93#define xPortSysTickHandler sys_tick_handler
94
95/* USER CODE BEGIN Defines */
96/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
97/* USER CODE END Defines */
98
99#endif /* FREERTOS_CONFIG_H */
上面配置需要根据自己的需要进行更改,如CPU频率,是否需要打开某项功能等;
配置好后的目录结构如下:
3 FreeRTOS示例
首先需要设置FreeRTOS需要的时钟
1/**
2 * @brief systick setup for rtos tick
3 */
4static void systick_setup(void)
5{
6 systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
7 systick_set_reload(64*1000);
8
9 systick_interrupt_enable();
10
11 /* Start counting. */
12 systick_counter_enable();
13}
这样在FreeRTOSConfig.h 文件中定义的
1#define xPortSysTickHandler sys_tick_handler
就可以通过systick中断提供FreeRTOS时钟;
LED任务函数
1static void led1_task(void *args)
2{
3 rcc_periph_clock_enable(RCC_GPIOC);
4 gpio_mode_setup(GPIOC,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO12);
5
6 while (1)
7 {
8 gpio_toggle(GPIOC,GPIO12);
9 vTaskDelay(pdMS_TO_TICKS(500));
10 }
11}
主程序中创建任务并开启多任务调度
1#include
2#include
3#include
4
5#include "FreeRTOS.h"
6#include "task.h"
7
8
9int main(void)
10{
11 //system clock
12 rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);
13
14 systick_setup();
15
16 xTaskCreate(led_task,"led task", 256, NULL,2,NULL);
17
18 vTaskStartScheduler();
19
20 while(1){}
21
22 return 0;
23}
通过xTaskCreate创建多任务函数,然后使用 vTaskStartScheduler 开始调度;
注:如果VSCode中提示 FreeRTOS.h 头文件include path问题,可以将项目文件夹关闭,再重新打开即可;如果是在Clion中,可以在添加lib文件夹后,右键platformio.ini文件选择re init即可;
4 烧写测试
点击 PlatformIO:Upload按钮或Ctrl+Alt+U快捷键可以直接编译烧写到目标板,看到LED按预定的程序闪烁运行。