我是靠谱客的博主 受伤小鸭子,这篇文章主要介绍基于STM32实验:uC/OS-III操作系统移植并创建多任务系统实验一、创建工程二、uC/OS-III操作系统移植入工程三、主函数分析及实验运行演示四、总结五、参考文献,现在分享给大家,希望可以做个参考。

本次实验内容:
将uC/OS-III操作系统移植到stm32F103C8T6上,构建至少3个任务(task):
分别以1s和3s周期对LED灯进行点亮-熄灭的控制;
另外一个task以2s周期通过串口发送“hello uc/OS! 欢迎来到RTOS多任务环境!”。


实验器材及软件:
stm32f103c8t6、若干杜邦线跳线、面包板、USB转TTL接口、两个LED灯
stm32CubeMx、Keil 5、flymcu烧录工具、串口调试助手

文章目录

  • 一、创建工程
  • 二、uC/OS-III操作系统移植入工程
    • 1、下载准备文件并完成外部文件移植操作
    • 2、Keil中加入工程组件
    • 3、更改文件内容(包含实验内容代码)
  • 三、主函数分析及实验运行演示
  • 四、总结
  • 五、参考文献


一、创建工程

  • 打开stm32CubeMx,选择创建MCU工程
    -在这里插入图片描述

  • 选择stm32f103c8t6芯片
    在这里插入图片描述

  • 进入工程初始化界面

  • 选择RCC,配置时HSE高速时钟

在这里插入图片描述

  • 选择SYS设置调试模式接口

在这里插入图片描述

  • 选择USART1中,模式设置为Asynchronous,实现实验要求中串口通信的任务

在这里插入图片描述

  • 在右面芯片视图中选择两个输出引脚实现实验要求中两个周期闪烁的LED任务,此处我选择的是PB 12/13,在GPIO设置中分别选择命名为LED 1/2(方便Keil中调用)

在这里插入图片描述

  • 进入时钟配置,按下图配置好72MHz时钟
    在这里插入图片描述

  • 最后进入项目管理,选择生成MDK文件,即Keil编程环境

在这里插入图片描述

  • 在下一栏中勾选生成.c/.h文件,即可点击右上角生成项目工程(GENERATE CODE)

在这里插入图片描述

  • 至此,已完成在stm32CubeMx中的所有步骤,下面为设置完后芯片视图
    在这里插入图片描述

二、uC/OS-III操作系统移植入工程

复制代码
1
2
对于uC/OS-III操作系统移植操作,本文大量参考了文章:https://blog.csdn.net/weixin_43116606/article/details/105532222

1、下载准备文件并完成外部文件移植操作

请参考上方链接中的文章(文章中的官网链接打不开,所以我直接下载了作者上传的网盘文件)

  • 下载完成后,会有如下图4个文件
    在这里插入图片描述

  • 打开创建好的工程目录,创建UCOSIII文件(用于存放操作系统文件)
    在这里插入图片描述

  • 将下载好的文件中uC-CPU / uC-LIB /uCOS-III文件放入UCOSIII
    在这里插入图片描述

  • 打开CORE=>Src,创建OS文件
    在这里插入图片描述

  • 打开下载好的文件,按下图路径,找到选中的9个文件,复制到OS文件中
    在这里插入图片描述

  • 继续在OS文件中创建:app.h/bsp.c/bsp.h三个文件
    在这里插入图片描述

  • 至此,以上完成了外部文件的移植操作(目的是为了在Keil中方便导入管理)

2、Keil中加入工程组件

  • 打开生成的MDK-ARM工程目录,进入工程
    在这里插入图片描述
  • 打开组件项目管理
    在这里插入图片描述
  • 在Groups中创建红框中的6个分组:CPU/LIB/PORT/SOURCE/CONFIG/BSP

在这里插入图片描述

  • 接下来,就是在各个分组中加入文件

  • 首先选中Application/User/Core,Add Files,添加OS文件下的app.c
    在这里插入图片描述在这里插入图片描述

  • 分组选中CPU,Add Files
    添加UCOSIII=>uC-CPU下的cpu_core.c/cpu_core.h/cpu_def.h
    添加UCOSIII=>uC-CPU=>ARM-Cortex-M3=>RealView下的cpu.h/cpu_a.asm/cpu_c.c
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 分组选中LIB,Add Files
    添加UCOSIII=>uC-LIB下的所示9个文件
    添加UCOSIII=>uC-LIB=>Ports=>ARM-Cortex-M3=>RealView下的lib_mem_a.asm文件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 分组选中PORT,Add Files
    添加UCOSIII=>uCOS-III=>Ports=>ARM-Cortex-M3=>Generic=>RealView下的3个文件
    在这里插入图片描述
    在这里插入图片描述

  • 分组选中SOURCE,Add Files
    添加UCOSIII=>uCOS-III=>Source下的20个文件
    在这里插入图片描述
    在这里插入图片描述

  • 分组选中CONFIG,Add Files,添加OS文件下,如图所示8个文件
    在这里插入图片描述

  • 分组选中BSP,Add Files,添加OS文件下,如图所示2个文件
    在这里插入图片描述

  • 选择OK(不然前功尽弃),完成导入

  • 工程一览

在这里插入图片描述

在这里插入图片描述

  • 最后,选择Options for Target=>C/C++,加入上述文件的7个路径
    在这里插入图片描述
    在这里插入图片描述

3、更改文件内容(包含实验内容代码)

  • 打开startup_stm32f103xb.s,将下图两个位置的
    Pend_SVHandler更改为OS_CPU_PendSVHandler
    Sys_TickHandler更改为OS_CPU_SysTickHandler
    此处已改好
    在这里插入图片描述
    在这里插入图片描述

  • 打开app_cfg.h
    #define APP_CFG_SERIAL_EN DEF_ENABLED改为DISABLED
    #define APP_TRACE BSP_Ser_Printf改为#define APP_TRACE(void)
    在这里插入图片描述
    在这里插入图片描述

  • 打开includes.h,加入包含所示3个头文件,并将#include <stm32f10x_lib.h>改为#include "stm32f1xx_hal.h"
    在这里插入图片描述
    在这里插入图片描述

  • 打开bsp.c和bsp.h,复制以下代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// bsp.c #include "includes.h" #define DWT_CR *(CPU_REG32 *)0xE0001000 #define DWT_CYCCNT *(CPU_REG32 *)0xE0001004 #define DEM_CR *(CPU_REG32 *)0xE000EDFC #define DBGMCU_CR *(CPU_REG32 *)0xE0042004 #define DEM_CR_TRCENA (1 << 24) #define DWT_CR_CYCCNTENA (1 << 0) CPU_INT32U BSP_CPU_ClkFreq (void) { return HAL_RCC_GetHCLKFreq(); } void BSP_Tick_Init(void) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; cpu_clk_freq = BSP_CPU_ClkFreq(); #if(OS_VERSION>=3000u) cnts = cpu_clk_freq/(CPU_INT32U)OSCfg_TickRate_Hz; #else cnts = cpu_clk_freq/(CPU_INT32U)OS_TICKS_PER_SEC; #endif OS_CPU_SysTickInit(cnts); } void BSP_Init(void) { BSP_Tick_Init(); MX_GPIO_Init(); } #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) void CPU_TS_TmrInit (void) { CPU_INT32U cpu_clk_freq_hz; DEM_CR |= (CPU_INT32U)DEM_CR_TRCENA; /* Enable Cortex-M3's DWT CYCCNT reg. */ DWT_CYCCNT = (CPU_INT32U)0u; DWT_CR |= (CPU_INT32U)DWT_CR_CYCCNTENA; cpu_clk_freq_hz = BSP_CPU_ClkFreq(); CPU_TS_TmrFreqSet(cpu_clk_freq_hz); } #endif #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) CPU_TS_TMR CPU_TS_TmrRd (void) { return ((CPU_TS_TMR)DWT_CYCCNT); } #endif #if (CPU_CFG_TS_32_EN == DEF_ENABLED) CPU_INT64U CPU_TS32_to_uSec (CPU_TS32 ts_cnts) { CPU_INT64U ts_us; CPU_INT64U fclk_freq; fclk_freq = BSP_CPU_ClkFreq(); ts_us = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC); return (ts_us); } #endif #if (CPU_CFG_TS_64_EN == DEF_ENABLED) CPU_INT64U CPU_TS64_to_uSec (CPU_TS64 ts_cnts) { CPU_INT64U ts_us; CPU_INT64U fclk_freq; fclk_freq = BSP_CPU_ClkFreq(); ts_us = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC); return (ts_us); } #endif
复制代码
1
2
3
4
5
6
7
8
9
10
11
// bsp.h #ifndef __BSP_H__ #define __BSP_H__ #include "stm32f1xx_hal.h" void BSP_Init(void); #endif
  • 打开app.c和app.h,复制以下代码
复制代码
1
2
3
4
// app.c #include <includes.h>
复制代码
1
2
3
4
5
6
7
8
9
// app.h #ifndef __APP_H__ #define __APP_H__ #include <includes.h> #endif /* __APP_H__ */
  • 打开main.c,复制以下代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "gpio.h" #include "usart.h" #include "string.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <includes.h> #include "stm32f1xx_hal.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* 任务优先级 */ #define START_TASK_PRIO 3 #define LED1_TASK_PRIO 4 #define MSG_TASK_PRIO 5 #define LED2_TASK_PRIO 6 /* 任务堆栈大小 */ #define START_STK_SIZE 64 #define LED1_STK_SIZE 64 #define MSG_STK_SIZE 64//任务堆大小过大会报错,可以试着改小一点 #define LED2_STK_SIZE 64 /* 任务栈 */ CPU_STK START_TASK_STK[START_STK_SIZE]; CPU_STK LED1_TASK_STK[LED1_STK_SIZE]; CPU_STK MSG_TASK_STK[MSG_STK_SIZE]; CPU_STK LED2_TASK_STK[LED2_STK_SIZE]; /* 任务控制块 */ OS_TCB StartTaskTCB; OS_TCB Led1TaskTCB; OS_TCB MsgTaskTCB; OS_TCB Led2TaskTCB; /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* 任务函数定义 */ void start_task(void *p_arg); static void AppTaskCreate(void); static void AppObjCreate(void); static void led_pb12(void *p_arg); static void led_pb13(void *p_arg); static void send_msg(void *p_arg); /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /**Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { OS_ERR err; OSInit(&err); HAL_Init(); SystemClock_Config(); //MX_GPIO_Init(); 这个在BSP的初始化里也会初始化 MX_USART1_UART_Init(); /* 创建任务 */ OSTaskCreate((OS_TCB *)&StartTaskTCB, /* Create the start task */ (CPU_CHAR *)"start task", (OS_TASK_PTR ) start_task, (void *) 0, (OS_PRIO ) START_TASK_PRIO, (CPU_STK *)&START_TASK_STK[0], (CPU_STK_SIZE) START_STK_SIZE/10, (CPU_STK_SIZE) START_STK_SIZE, (OS_MSG_QTY ) 0, (OS_TICK ) 0, (void *) 0, (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), (OS_ERR *)&err); /* 启动多任务系统,控制权交给uC/OS-III */ OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */ } void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; /* YangJie add 2021.05.20*/ BSP_Init(); /* Initialize BSP functions */ //CPU_Init(); //Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //统计任务 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //进入临界区 /* 创建LED1任务 */ OSTaskCreate((OS_TCB * )&Led1TaskTCB, (CPU_CHAR * )"led_pb12", (OS_TASK_PTR )led_pb12, (void * )0, (OS_PRIO )LED1_TASK_PRIO, (CPU_STK * )&LED1_TASK_STK[0], (CPU_STK_SIZE)LED1_STK_SIZE/10, (CPU_STK_SIZE)LED1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); /* 创建LED2任务 */ OSTaskCreate((OS_TCB * )&Led2TaskTCB, (CPU_CHAR * )"led_pb13", (OS_TASK_PTR )led_pb13, (void * )0, (OS_PRIO )LED2_TASK_PRIO, (CPU_STK * )&LED2_TASK_STK[0], (CPU_STK_SIZE)LED2_STK_SIZE/10, (CPU_STK_SIZE)LED2_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); /*创建message传输任务*/ OSTaskCreate((OS_TCB * )&MsgTaskTCB, (CPU_CHAR * )"send_msg", (OS_TASK_PTR )send_msg, (void * )0, (OS_PRIO )MSG_TASK_PRIO, (CPU_STK * )&MSG_TASK_STK[0], (CPU_STK_SIZE)MSG_STK_SIZE/10, (CPU_STK_SIZE)MSG_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err); //挂起开始任务 OS_CRITICAL_EXIT(); //进入临界区 } /** * 函数功能: 启动任务函数体。 * 输入参数: p_arg 是在创建该任务时传递的形参 * 返 回 值: 无 * 说 明:无 */ static void led_pb12 (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); AppTaskCreate(); /* Create Application Tasks */ AppObjCreate(); /* Create Application Objects */ while (DEF_TRUE) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET); OSTimeDlyHMSM(0, 0, 1, 0,OS_OPT_TIME_HMSM_STRICT,&err); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET); OSTimeDlyHMSM(0, 0, 1, 0,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } static void led_pb13 (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); AppTaskCreate(); /* Create Application Tasks */ AppObjCreate(); /* Create Application Objects */ while (DEF_TRUE) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); OSTimeDlyHMSM(0, 0, 3, 0,OS_OPT_TIME_HMSM_STRICT,&err); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET); OSTimeDlyHMSM(0, 0, 3, 0,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } static void send_msg (void *p_arg) { uint8_t data[]="hello uc/OS!欢迎来到RTOS多任务环境!n"; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); AppTaskCreate(); /* Create Application Tasks */ AppObjCreate(); /* Create Application Objects */ while (DEF_TRUE) { HAL_UART_Transmit(&huart1,data,strlen(data),0xFF); OSTimeDlyHMSM(0, 0, 2, 0,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /* USER CODE BEGIN 4 */ /** * 函数功能: 创建应用任务 * 输入参数: p_arg 是在创建该任务时传递的形参 * 返 回 值: 无 * 说 明:无 */ static void AppTaskCreate (void) { } /** * 函数功能: uCOSIII内核对象创建 * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ static void AppObjCreate (void) { } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %drn", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  • 打开lib_cfg.h,将堆空间减小点(此芯片最大只有20K),此处我改为了5,否则在编译会报错空间不足
    在这里插入图片描述
    在这里插入图片描述
    以上就是uC/OS-III操作系统移植入stm32f103c8t6的全部过程,上文的main.c文件内容已经包含了完成三个任务的代码,编译运行烧录即可实现三个任务的同时运行。下面是代码main.c代码的理解分析及实际演示。

三、主函数分析及实验运行演示

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/* 任务优先级 */ /* 任务创建所需参数1:设立任务优先级*/ #define START_TASK_PRIO 3 #define LED1_TASK_PRIO 4 #define MSG_TASK_PRIO 5 #define LED2_TASK_PRIO 6 /* 任务堆栈大小 */ /* 任务创建所需参数2:分配任务堆栈空间*/ #define START_STK_SIZE 64 #define LED1_STK_SIZE 64 #define MSG_STK_SIZE 64 #define LED2_STK_SIZE 64//任务堆大小过大会报错,可以试着改小一点 /* 任务栈 */ /* 分配任务栈 */ /* 任务创建所需参数3:分配任务栈*/ CPU_STK START_TASK_STK[START_STK_SIZE]; CPU_STK LED1_TASK_STK[LED1_STK_SIZE]; CPU_STK MSG_TASK_STK[MSG_STK_SIZE]; CPU_STK LED2_TASK_STK[LED2_STK_SIZE]; /* 任务控制块 */ /* 任务创建所需参数4:规定任务控制模块 */ OS_TCB StartTaskTCB; OS_TCB Led1TaskTCB; OS_TCB MsgTaskTCB; OS_TCB Led2TaskTCB; /* 任务函数定义 */ /* 各个任务的定义函数 */ void start_task(void *p_arg);//启动文件实现的函数,此函数中创建三个任务的多任务系统 static void AppTaskCreate(void);//创建应用任务,本实验未使用 static void AppObjCreate(void);//uCOSIII内核对象创建,本实验未使用 static void led_pb12(void *p_arg);//具体实现LED1以1秒为周期闪烁 static void led_pb13(void *p_arg);//具体实现LED2以3秒为周期闪烁 static void send_msg(void *p_arg);//具体实现以2秒为周期向上位机发送指定字符
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* 创建启动文件任务(次) */ int main(void) { OS_ERR err; OSInit(&err); HAL_Init(); SystemClock_Config(); //MX_GPIO_Init(); 这个在BSP的初始化里也会初始化 MX_USART1_UART_Init(); /* 创建启动文件任务 */ OSTaskCreate((OS_TCB *)&StartTaskTCB, /* Create the start task */ (CPU_CHAR *)"start task",//定义函数名 (OS_TASK_PTR ) start_task,//定义函数 (void *) 0, (OS_PRIO ) START_TASK_PRIO, (CPU_STK *)&START_TASK_STK[0], (CPU_STK_SIZE) START_STK_SIZE/10, (CPU_STK_SIZE) START_STK_SIZE, (OS_MSG_QTY ) 0, (OS_TICK ) 0, (void *) 0, (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), (OS_ERR *)&err); /* 启动多任务系统,控制权交给uC/OS-III */ OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */ }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//启动文件创建多任务线程 void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; /* YangJie add 2021.05.20*/ BSP_Init(); /* Initialize BSP functions */ //CPU_Init(); //Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //统计任务 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //进入临界区 /* 创建LED1任务 */ OSTaskCreate((OS_TCB * )&Led1TaskTCB, (CPU_CHAR * )"led_pb12", (OS_TASK_PTR )led_pb12, (void * )0, (OS_PRIO )LED1_TASK_PRIO, (CPU_STK * )&LED1_TASK_STK[0], (CPU_STK_SIZE)LED1_STK_SIZE/10, (CPU_STK_SIZE)LED1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); /* 创建LED2任务 */ OSTaskCreate((OS_TCB * )&Led2TaskTCB, (CPU_CHAR * )"led_pb13", (OS_TASK_PTR )led_pb13, (void * )0, (OS_PRIO )LED2_TASK_PRIO, (CPU_STK * )&LED2_TASK_STK[0], (CPU_STK_SIZE)LED2_STK_SIZE/10, (CPU_STK_SIZE)LED2_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); /*创建message传输任务*/ OSTaskCreate((OS_TCB * )&MsgTaskTCB, (CPU_CHAR * )"send_msg", (OS_TASK_PTR )send_msg, (void * )0, (OS_PRIO )MSG_TASK_PRIO, (CPU_STK * )&MSG_TASK_STK[0], (CPU_STK_SIZE)MSG_STK_SIZE/10, (CPU_STK_SIZE)MSG_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err); //挂起开始任务 OS_CRITICAL_EXIT(); //进入临界区 }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//LED1以1秒为周期闪烁任务定义函数 static void led_pb12 (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); AppTaskCreate(); /* Create Application Tasks */ AppObjCreate(); /* Create Application Objects */ while (DEF_TRUE) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET); OSTimeDlyHMSM(0, 0, 1, 0,OS_OPT_TIME_HMSM_STRICT,&err); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET); OSTimeDlyHMSM(0, 0, 1, 0,OS_OPT_TIME_HMSM_STRICT,&err); } } //LED2以3秒为周期闪烁任务定义函数 static void led_pb13 (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); AppTaskCreate(); /* Create Application Tasks */ AppObjCreate(); /* Create Application Objects */ while (DEF_TRUE) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); OSTimeDlyHMSM(0, 0, 3, 0,OS_OPT_TIME_HMSM_STRICT,&err); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET); OSTimeDlyHMSM(0, 0, 3, 0,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } //串口以2秒为周期持续发送指定字符任务定义函数 static void send_msg (void *p_arg) { uint8_t data[]="hello uc/OS!欢迎来到RTOS多任务环境!n"; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); AppTaskCreate(); /* Create Application Tasks */ AppObjCreate(); /* Create Application Objects */ while (DEF_TRUE) { HAL_UART_Transmit(&huart1,data,strlen(data),0xFF); OSTimeDlyHMSM(0, 0, 2, 0,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
  • 上述流程简单来说就是:
    创建启动任务——开启多任务系统——启动任务定义函数中创建多任务——在每个任务定义函数中键入实现目标代码
  • 以下为实验结果演示
    两个LED灯分别以1/3秒为周期闪烁
    在这里插入图片描述
  • 串口以2秒为周期,持续发送“hello uc/OS! 欢迎来到RTOS多任务环境!”至上位机
    在这里插入图片描述


四、总结

 本次实验主要学习了stm32f103c8t6移植uC/OS-III操作系统的具体流程,并完成了多任务创建实现的实验要求。实验过程中遇到过不少问题,比如在参考文章移植时不够细心,总有缺漏导致编译运行不成功;在研究主函数文件如何创建多任务系统时,对具体的函数定义并不理解等,本次任务的实现只是对多任务系统建立有了一个大概的认识,并没有深入地理解使能时间片轮转、临界区等实现多任务系统实现代码,希望在接下来的综合系统设计中能够运用并更加深刻理解此操作系统下多任务系统创建的深层逻辑。


五、参考文献

https://blog.csdn.net/weixin_43116606/article/details/105532222
https://blog.csdn.net/qq_45659777/article/details/121570886

最后

以上就是受伤小鸭子最近收集整理的关于基于STM32实验:uC/OS-III操作系统移植并创建多任务系统实验一、创建工程二、uC/OS-III操作系统移植入工程三、主函数分析及实验运行演示四、总结五、参考文献的全部内容,更多相关基于STM32实验内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(86)

评论列表共有 0 条评论

立即
投稿
返回
顶部