|
使用Platformio平台的libopencm3开发框架来开发STM32G0,下面为使用FreeRTOS系统。
( `' v# K: C* O2 h* q/ B, f9 p 1 新建项目在PIO主页新建项目,框架选择libopencm3,开发板选择 MonkeyPi_STM32_G070RB; 新建完成后在src目录新建主程序文件main.c; 然后更改项目文件platformio.ini的烧写和调试方式:
( @( Y6 K S- S
- 1upload_protocol = cmsis-dap
) s' R! O8 X$ q2 P% ^ y: b: {4 V - 2debug_tool = cmsis-dap
复制代码
; _9 k) [; N8 u8 A8 o5 i4 A' U: x, h$ G- C4 B' ^, r3 }
2 添加FreeRTOS源码下载FreeRTOS源码 & B, T/ g% H: @" t
( M8 h0 f9 c6 Q: W( w% ?
添加源码到项目: & ?, K0 s) K% y. h: C: M
直接拷贝源码下的FreeRTOS文件夹到项目的lib目录中; 5 H+ R; |3 {) K* W6 M
添加到项目编译 9 Q3 [5 q9 b% }6 k" E: ^" B+ ?( F3 a$ m$ x
在lib目录的FreeRTOS文件夹下新建 library.json 文件,内容如下: - 1{% @2 g; h7 E- |, ^0 e7 m
- 2 "name": "FreeRTOS",
3 ~3 o5 j1 [5 o& d - 3 "version": "202112.00",
' B0 @8 ]/ h* C5 B8 i z - 4 "build": { A2 }, [2 x3 @. d6 a, g
- 5 "flags": [+ q; e- ]/ y% W3 a4 u
- 6 "-Isource",
) G7 y% _2 g0 S5 B3 ?. d! v& m - 7 "-Isource/include",3 N& x( Y1 r0 T Z
- 8 "-Isource/portable/GCC/ARM_CM0",
! H7 X6 z* r1 {3 e& T - 9 "-Isource/portable/RVDS/ARM_CM0"$ _ p7 a F+ z; q
- 10 ],# `& z1 [$ C) T0 V
- 11 "srcFilter": [& V: F$ W1 I) c7 }: o
- 12 "+<source/*.c>", a0 O9 J5 e! d" g2 [( o, n
- 13 "+<source/portable/GCC/ARM_CM0/*.c>",, j) K' w, s1 a( j
- 14 "+<source/portable/MemMang/heap_4.c>"
! @9 H. I- J$ o) C* F - 15 ]
7 _4 g) _7 S* J/ V - 16 }
" r- _) H& c% K - 17}
复制代码添加FreeRTOS配置
1 t& v2 `0 R, Y5 N. _- H% B4 ~9 m" @
从FreeRTOS源码下的demo目录中拷贝一个FreeRTOSConfig.h文件到 lib/FreeRTOS/Source目录,并更改为如下内容: - 1/**
$ W( E6 A: j' K9 ], J4 D - 2 * @file FreeRTOSConfig.h8 t) j! p+ y5 \4 n# x# Q
- 3 *
5 V+ G2 J7 O- @ - 4 * http://www.FreeRTOS.org
0 g1 P1 P- s7 U. e" l+ W# T, L9 M - 5 * http://aws.amazon.com/freertos
7 E1 p2 w! g# ^) V0 Q - 6 * 6 v: f/ U1 C( w; Q4 R
- 7 */
6 ^: n3 B F' b6 t; i: r - 8/ I9 u) Z- Q" y0 F" X& v
- 9#ifndef FREERTOS_CONFIG_H
4 G) U0 x: e, s# {1 s5 w - 10#define FREERTOS_CONFIG_H& ^6 V9 }$ s) @3 ~) S0 \! b
- 11
- |0 x, }) G- S5 ]; n1 Z - 12/*-----------------------------------------------------------, K3 S7 F( [$ ~" f1 u
- 13 * Application specific definitions.- ` U% I: d3 c8 ~7 \7 I2 Q0 n
- 14 *
1 `2 V. _5 S" g' B - 15 * These definitions should be adjusted for your particular hardware and
N( x$ @" d5 y* X - 16 * application requirements.5 Z9 i% U/ j7 T
- 17 *0 S0 K6 R) Z: ^5 T0 E
- 18 * These parameters and more are described within the 'configuration' section of the$ _8 i" \( [. e% }0 o
- 19 * FreeRTOS API documentation available on the FreeRTOS.org web site.( F7 F$ g5 z! H
- 20 *% w# l D% f' w& |1 r" Y, e
- 21 * See http://www.freertos.org/a00110.html
6 ~/ D! C( W9 O1 S5 J - 22 *----------------------------------------------------------*/
0 c% e$ v6 ]. f$ Z( K9 O - 23
" U- M+ {$ u9 J3 [( \5 z) M - 24/* USER CODE BEGIN Includes */
7 ]* \3 ? l; E" q7 g9 Y4 p% @ - 25/* Section where include file can be added */
. J9 ~8 l: f! b5 x n6 C/ g) g7 @- ~ - 26/* USER CODE END Includes */% ~# `( M' i3 @9 Q2 Q0 e
- 27
; s: @, @2 _; [% C+ H$ K, e - 28/* Ensure definitions are only used by the compiler, and not by the assembler. */
2 _7 ^. O9 X9 ]) J' ? - 29#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
5 D+ N9 O& d! _9 n6 s+ r - 30 #include <stdint.h>, {& z" T9 r* [
- 31#endif
% u% o, f* W. m8 Z. | - 32#define configENABLE_FPU 0
% Z5 b1 L$ x% O* H7 F6 D, h - 33#define configENABLE_MPU 0
/ Q, P% c$ c$ p& b1 G - 34* n* l( l% Z: S( ]. ?
- 35#define configUSE_PREEMPTION 1( i; [0 G5 H" m, C" g$ ]
- 36#define configSUPPORT_STATIC_ALLOCATION 0; F# u- X, V# g
- 37#define configSUPPORT_DYNAMIC_ALLOCATION 18 ~7 F" e8 u9 I
- 38#define configUSE_IDLE_HOOK 0) E9 E5 m: D& j4 h# H
- 39#define configUSE_TICK_HOOK 0# e* p, S+ G- Z* n) r" C0 `
- 40#define configCPU_CLOCK_HZ ( ( unsigned long ) 64000000 )
, _ y. U1 H0 u7 U% _' W - 41#define configTICK_RATE_HZ ((TickType_t)1000)- k4 e% Y9 }5 ?2 F# W5 V! h+ ^+ j3 o
- 42#define configMAX_PRIORITIES ( 7 )
& }& ^" F- |7 F! }; t8 y9 K - 43#define configMINIMAL_STACK_SIZE ((uint16_t)256)3 Y/ {7 W5 p8 f2 h
- 44#define configTOTAL_HEAP_SIZE ((size_t)1024*16)5 `6 q( w& G. _# ~5 n- ?! y1 ^
- 45#define configMAX_TASK_NAME_LEN ( 16 )9 |* X2 }& G0 ?0 R7 r: c, j9 O" h
- 46#define configUSE_16_BIT_TICKS 0
4 V- K; Z f3 Q, h. \* j - 47#define configUSE_MUTEXES 1) L0 J! V; d) o1 I$ F4 O
- 48#define configQUEUE_REGISTRY_SIZE 8
2 b2 t; P8 F. x' c8 C, H - 49#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0$ ^6 n; B0 i" |/ o, `4 A
- 50
: C8 e) y, j9 H1 B! W& t - 51/*Software timer related definitions. */
& r3 _0 K2 ~$ p - 52#define configUSE_TIMERS 10 s' Q- i* v2 q1 m/ y1 f0 Y7 _
- 53#define configTIMER_TASK_PRIORITY 5& r/ q- Z) J/ o' D- S" Q4 |/ t
- 54#define configTIMER_QUEUE_LENGTH 10
) [4 U/ @1 x8 I' `' @ - 55#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE, E. N2 D1 o! s/ Z$ X- Y+ J, a
- 56
2 y7 e0 l# I0 L, p8 ~ - 57/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
; O! J3 g7 G1 {7 g6 b - 58/* Defaults to size_t for backward compatibility, but can be changed- t. ], i- k7 W1 P: A+ e9 n' O
- 59 if lengths will always be less than the number of bytes in a size_t. */! O' W+ x2 Q5 W, m+ B' h
- 60#define configMESSAGE_BUFFER_LENGTH_TYPE size_t, M; {+ D z ~! w3 W. v' o2 O( @
- 61/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
/ q* H8 D5 N% v8 o6 j/ W/ [ - 62" A! d; `+ d6 d/ V! Y) D' m
- 63/* Co-routine definitions. */! m+ o! @) Z# [( C- s$ ~8 N
- 64#define configUSE_CO_ROUTINES 0
0 |. T+ Q% ]3 H& X5 ?1 Q" D- X - 65#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
# D! ]% A$ ]# ^+ q* d - 66
0 o, F# F: Y% K& z# H9 h - 67/* Set the following definitions to 1 to include the API function, or zero
5 G; [+ b8 L- q+ S7 W - 68to exclude the API function. */6 L+ l7 N; r5 M
- 69#define INCLUDE_vTaskPrioritySet 18 E) c" O0 l/ s! f. e0 [# t; |
- 70#define INCLUDE_uxTaskPriorityGet 1* U# r Z8 D: f% }( O- y- k- K2 s# V
- 71#define INCLUDE_vTaskDelete 1. ]2 P) I( c- x) G5 L$ i$ o5 ?- |
- 72#define INCLUDE_vTaskCleanUpResources 0" w( i4 N; P: g5 i: Y
- 73#define INCLUDE_vTaskSuspend 1
) I) t/ i+ ^0 z) j0 Z- l - 74#define INCLUDE_vTaskDelayUntil 0
0 }4 y. Q- J E* r( r- k - 75#define INCLUDE_vTaskDelay 1
2 C6 _2 u% n9 w2 d- a - 76#define INCLUDE_xTaskGetSchedulerState 1
$ t9 F8 i' F5 \9 n0 [* ]& F; x - 77+ {5 C/ L8 |4 O; @9 [& Z
- 78/* Normal assert() semantics without relying on the provision of an assert.h4 C; K+ l4 R4 D; H
- 79header file. */
6 n# _( m+ G8 [( i7 Z, o - 80/* USER CODE BEGIN 1 */
1 W* C7 V1 x; T1 o3 B0 f2 ^ - 81//void vAssertCalled(const char *file, int line);4 b% l& M( N0 x; U" L% ~
- 82//#define configASSERT( x ) if( x == 0 ) { taskDISABLE_INTERRUPTS(); vAssertCalled(__FILE__,__LINE__); for(;;); }2 T# `8 H7 O) C
- 83/* USER CODE END 1 */) T( n* K2 N% {* v. V; v
- 84. c4 ?% J2 O5 s& {! M9 {* h! X
- 85/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
4 Y9 ^+ b$ o7 y" \6 N; W Y! w) V - 86standard names. */
6 N3 E. M8 ~: K; h9 H. q7 F - 87#define vPortSVCHandler sv_call_handler* @& r- K* s7 b& _: N+ S( z
- 88#define xPortPendSVHandler pend_sv_handler
# q% J( C8 ?% a( _( g - 89& `/ p$ f3 G! @+ F) i" \
- 90/* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick,
4 p' N) @/ v. T/ n' O5 d& H% f/ T( l - 91 to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
5 x" t) G* Q) C7 Y1 E; M1 [6 b - 92
$ ?; ~; S Y% E! j+ k0 V - 93#define xPortSysTickHandler sys_tick_handler
X0 C6 w$ s x! e% o - 94
9 E3 K7 A/ b/ N# K/ z% ] O - 95/* USER CODE BEGIN Defines */
9 T) K- R$ z' J0 k - 96/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
- Q/ V3 u; M3 E4 v+ q - 97/* USER CODE END Defines */ D" }; ?% L5 `( M. H1 d
- 98( ?; U! @/ }5 Y. K2 \* @
- 99#endif /* FREERTOS_CONFIG_H */
复制代码 4 N. i4 T v8 x6 g3 B* H
上面配置需要根据自己的需要进行更改,如CPU频率,是否需要打开某项功能等; 配置好后的目录结构如下: 3 }6 ?) g/ I+ K
; H4 \; a k2 G! I) n# [3 FreeRTOS示例首先需要设置FreeRTOS需要的时钟 " O9 S8 |5 i0 A# T# a# v1 z+ O
- 1/**4 G0 Z; \+ _; b* b: N
- 2 * @brief systick setup for rtos tick
; Y2 z) S, `) Y - 3 */+ `3 y; z' X& U# \5 A# [$ V
- 4static void systick_setup(void)9 }1 h; [) T# B. }
- 5{
/ R8 D3 P# N8 ^3 U. V& R, p& f - 6 systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
# o/ f6 A2 D: F1 S - 7 systick_set_reload(64*1000);
+ ~! y# t/ c. o! a7 M# |! E - 8
* K+ s1 g) T, l' r( k% A0 ^1 U4 z$ Q - 9 systick_interrupt_enable();
. j$ ~% l) ?; R0 k6 P$ Y! Z$ C - 10
; H: G& w9 q1 h! E: ~ - 11 /* Start counting. */8 P: m* o6 R0 [' i
- 12 systick_counter_enable();* g" o. m0 w$ e; s: Q2 X
- 13}
复制代码 ' O3 X( v( n% ]$ [
4 T% p) q) [% R) Z1 k1 [9 y! P这样在FreeRTOSConfig.h 文件中定义的 - 1#define xPortSysTickHandler sys_tick_handler
复制代码 , i. Z# D! ?' z" k6 ^
就可以通过systick中断提供FreeRTOS时钟; LED任务函数 6 {: g3 i2 k$ q1 j" @/ P! ^
- 1static void led1_task(void *args)& y0 c# u! O% g* w- O6 G3 r" E
- 2{) s( W/ o! m2 B3 B- T: ?
- 3 rcc_periph_clock_enable(RCC_GPIOC);( a9 u1 i5 q- L/ Z
- 4 gpio_mode_setup(GPIOC,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO12);
! N3 R2 j, K! t1 @/ ] - 5
; R. Q4 A% ]2 Z! k( }, J - 6 while (1)
, l) e/ i" a5 a% g5 \4 r' i0 V - 7 {# o) a9 |# p$ i0 G0 y
- 8 gpio_toggle(GPIOC,GPIO12);. O- `& n" c9 v4 M. d
- 9 vTaskDelay(pdMS_TO_TICKS(500));
0 ?& [. q) j2 ^! C+ V( Y' o8 p5 E$ C - 10 }& C( ?( c2 R6 j( C& P; n
- 11}
复制代码 ( v' W/ h, K/ L5 J' c
2 Z* v d% d. F3 |! s
主程序中创建任务并开启多任务调度 $ {- ?5 t" r/ W- u0 e
- 1#include <libopencm3/stm32/rcc.h>8 J0 ]/ M0 s( z, V) ^
- 2#include <libopencm3/stm32/gpio.h>7 N7 p+ o8 y$ f
- 3#include <libopencm3/cm3/systick.h>
+ U. y( Q, D; I" z3 Y - 45 L% A1 u# r: `8 O
- 5#include "FreeRTOS.h"! J; g1 w* B1 [. x. Y; @
- 6#include "task.h"
% F* S+ \' x* R - 7
4 A/ D9 c: O! @2 \1 i/ t - 8
$ E/ k: c5 h1 o. Y- x# }+ S - 9int main(void)# O7 D& e( u& `5 `' [: s) ]
- 10{
" \1 Z% M5 `( Q6 V& ]5 m* h# [ - 11 //system clock3 L9 |! Y3 }: R- g6 l2 X' f' r
- 12 rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);+ }- T9 x; J2 j* d7 w
- 13
) U. m- c' e, b5 F2 t- @ }+ } - 14 systick_setup();
+ h7 u# `) t2 r! L8 h2 I - 153 ?% E# @* {8 {. j8 |
- 16 xTaskCreate(led_task,"led task", 256, NULL,2,NULL);( a* w) \( r) A1 N! A$ H% q0 x
- 173 L, ~' k8 G8 _2 i9 K6 Y
- 18 vTaskStartScheduler();+ Q9 I" ]: P9 N1 ]4 ^
- 195 L$ n, C6 v. e% e3 o, T
- 20 while(1){} u1 Z5 S) C. o7 [, k$ H! m) W% Z
- 21
8 N2 _$ ?+ k6 D; ?1 P - 22 return 0;
. Z+ [6 o% {( z! @. t - 23}
复制代码 ) }8 |: o `5 i- J/ @. V( H
% N. Q9 q5 K8 s, ?1 [% U% r通过xTaskCreate创建多任务函数,然后使用 vTaskStartScheduler 开始调度; 注:如果VSCode中提示 FreeRTOS.h 头文件include path问题,可以将项目文件夹关闭,再重新打开即可;如果是在Clion中,可以在添加lib文件夹后,右键platformio.ini文件选择re init即可; ! m+ K: i; s( x6 A9 k
4 烧写测试点击 PlatformIO:Upload按钮或Ctrl+Alt+U快捷键可以直接编译烧写到目标板,看到LED按预定的程序闪烁运行;
' P2 O4 ]& W- ~/ I, V3 @8 q
转载自: MakerInChina.cn $ Q F7 l: \. E4 |
|