From c29722f2ac81828a1c2cce974a528a412481c234 Mon Sep 17 00:00:00 2001 From: ywh <2227158009@qq.com> Date: Thu, 23 Jul 2026 17:04:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Src/main.c | 43 +++++++++++++++++++ Core/Src/stm32f4xx_it.c | 7 +++ EWARM/startup_stm32f407xx.s | 4 +- .../Third_Party/Micrium/Config/app_cfg.h | 10 ++++- .../Third_Party/Micrium/Config/os_cfg.h | 12 +++--- 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/Core/Src/main.c b/Core/Src/main.c index b02d3bd..83b3578 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -22,6 +22,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +/* uC/OS-II的公开接口、任务类型和配置宏都由此头文件提供。 */ #include "ucos_ii.h" /* USER CODE END Includes */ @@ -51,6 +52,12 @@ static volatile uint32_t uart1_tx_ok_count; static volatile uint32_t uart1_tx_busy_count; static volatile uint32_t uart1_tx_error_count; static volatile uint32_t uart1_tx_complete_count; + +/* + * 每个任务必须拥有独立栈空间。 + * OS_STK在本工程中为32位,因此256个OS_STK占用1024字节RAM。 + * Cortex-M栈从高地址向低地址增长,创建任务时要把数组末元素作为栈顶传入。 + */ static OS_STK AppTaskStartStk[APP_TASK_START_STK_SIZE]; /* USER CODE END PV */ @@ -69,14 +76,21 @@ static void AppTaskStart(void *p_arg); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ +/* + * uC/OS-II任务函数的固定形式是 void Task(void *p_arg)。 + * 任务通常包含一个永久循环;需要等待时应调用OS延时或等待内核对象, + * 让出CPU给其他就绪任务,而不是在任务里忙等待。 + */ static void AppTaskStart(void *p_arg) { HAL_StatusTypeDef uart_status; + /* 当前没有给任务传递参数,显式转换可避免编译器产生未使用警告。 */ (void)p_arg; while (1) { + /* DMA发送启动后立即返回,真正的发送完成由DMA中断回调通知。 */ uart_status = HAL_UART_Transmit_DMA(&huart1, (uint8_t *)uart1_test_message, sizeof(uart1_test_message) - 1U); @@ -94,6 +108,11 @@ static void AppTaskStart(void *p_arg) uart1_tx_error_count++; } + /* + * 把当前任务延时OS_TICKS_PER_SEC个系统节拍。 + * 当前OS_TICKS_PER_SEC为1000,SysTick周期为1ms,因此这里延时1秒。 + * 延时期间任务处于等待态,内核会调度其他就绪任务(目前主要是空闲任务)。 + */ OSTimeDly(OS_TICKS_PER_SEC); } } @@ -134,8 +153,27 @@ int main(void) MX_USB_DEVICE_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ + /* uC/OS-II接口通常用返回错误码的方式报告执行结果。 */ INT8U os_err; + + /* + * 初始化内核的任务表、就绪表、事件控制块等内部数据。 + * OSInit()只完成初始化,此时任务调度尚未开始。 + */ OSInit(); + + /* + * 创建应用启动任务,各参数依次为: + * 1. 任务入口函数; + * 2. 传给任务的参数(当前不需要,所以为0); + * 3. 初始栈顶地址; + * 4. 任务优先级,数值越小优先级越高; + * 5. 任务ID,本工程暂时与优先级取相同值; + * 6. 栈底地址; + * 7. 栈容量,单位是OS_STK元素而不是字节; + * 8. 用户扩展指针(当前不用); + * 9. 创建选项:允许栈检查并在创建时清零任务栈。 + */ os_err = OSTaskCreateExt(AppTaskStart, 0, &AppTaskStartStk[APP_TASK_START_STK_SIZE - 1u], @@ -151,6 +189,11 @@ int main(void) { Error_Handler(); } + + /* + * 启动抢占式调度,内核会运行当前最高优先级的就绪任务。 + * OSStart()成功后不会返回,后面的裸机while循环不会再被执行。 + */ OSStart(); /* USER CODE END 2 */ diff --git a/Core/Src/stm32f4xx_it.c b/Core/Src/stm32f4xx_it.c index bd7fbca..2a13a5c 100644 --- a/Core/Src/stm32f4xx_it.c +++ b/Core/Src/stm32f4xx_it.c @@ -190,8 +190,15 @@ void SysTick_Handler(void) /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ + /* 维持STM32 HAL自己的1ms时基,HAL_GetTick()等接口依赖它。 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* + * HAL_Init()会先于OSInit()启动SysTick,因此必须先判断内核是否已经运行。 + * 内核运行后,每个1ms中断调用一次OS节拍处理: + * 更新任务延时,并在有更高优先级任务就绪时请求一次PendSV任务切换。 + */ if (OSRunning == OS_TRUE) { OS_CPU_SysTickHandler(); diff --git a/EWARM/startup_stm32f407xx.s b/EWARM/startup_stm32f407xx.s index 21f1af4..a62fd0c 100644 --- a/EWARM/startup_stm32f407xx.s +++ b/EWARM/startup_stm32f407xx.s @@ -48,7 +48,7 @@ EXTERN __iar_program_start EXTERN SystemInit - EXTERN OS_CPU_PendSVHandler + EXTERN OS_CPU_PendSVHandler ; uC/OS-II context-switch exception handler PUBLIC __vector_table DATA @@ -68,7 +68,7 @@ __vector_table DCD SVC_Handler ; SVCall Handler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved - DCD OS_CPU_PendSVHandler ; uC/OS-II context switch + DCD OS_CPU_PendSVHandler ; PendSV is owned by uC/OS-II for task switching DCD SysTick_Handler ; SysTick Handler ; External Interrupts diff --git a/Middlewares/Third_Party/Micrium/Config/app_cfg.h b/Middlewares/Third_Party/Micrium/Config/app_cfg.h index 80634a2..bd83e5b 100644 --- a/Middlewares/Third_Party/Micrium/Config/app_cfg.h +++ b/Middlewares/Third_Party/Micrium/Config/app_cfg.h @@ -1,10 +1,18 @@ #ifndef APP_CFG_H #define APP_CFG_H +/* + * uC/OS-II优先级数值越小,任务优先级越高。 + * 每个任务必须使用不同的优先级;0通常留给最紧急的系统任务。 + */ #define APP_TASK_START_PRIO 5u #define APP_TASK_TEST_PRIO 6u +/* + * 任务栈大小的单位是OS_STK元素。当前OS_STK为32位, + * 所以每个256元素的任务栈实际占用1024字节RAM。 + */ #define APP_TASK_START_STK_SIZE 256u #define APP_TASK_TEST_STK_SIZE 256u -#endif \ No newline at end of file +#endif diff --git a/Middlewares/Third_Party/Micrium/Config/os_cfg.h b/Middlewares/Third_Party/Micrium/Config/os_cfg.h index 4e2235d..ee70005 100644 --- a/Middlewares/Third_Party/Micrium/Config/os_cfg.h +++ b/Middlewares/Third_Party/Micrium/Config/os_cfg.h @@ -27,9 +27,9 @@ /* ---------------------- MISCELLANEOUS ----------------------- */ -#define OS_APP_HOOKS_EN 0u /* Application-defined hooks are called from the uC/OS-II hooks */ +#define OS_APP_HOOKS_EN 0u /* 初次移植不使用应用层钩子函数 */ #define OS_ARG_CHK_EN 0u /* Enable (1) or Disable (0) argument checking */ -#define OS_CPU_HOOKS_EN 1u /* uC/OS-II hooks are found in the processor port files */ +#define OS_CPU_HOOKS_EN 1u /* 使用Cortex-M4端口提供的CPU钩子函数 */ #define OS_DEBUG_EN 1u /* Enable(1) debug variables */ @@ -43,12 +43,12 @@ #define OS_MAX_FLAGS 5u /* Max. number of Event Flag Groups in your application */ #define OS_MAX_MEM_PART 5u /* Max. number of memory partitions */ #define OS_MAX_QS 4u /* Max. number of queue control blocks in your application */ -#define OS_MAX_TASKS 10u /* Max. number of tasks in your application, MUST be >= 2 */ +#define OS_MAX_TASKS 10u /* 应用最多可创建10个任务(不包括内核自动创建的系统任务) */ #define OS_SCHED_LOCK_EN 1u /* Include code for OSSchedLock() and OSSchedUnlock() */ #define OS_TICK_STEP_EN 1u /* Enable tick stepping feature for uC/OS-View */ -#define OS_TICKS_PER_SEC 1000u /* Set the number of ticks in one second */ +#define OS_TICKS_PER_SEC 1000u /* 每秒1000个节拍,即每个系统节拍为1ms */ #define OS_TLS_TBL_SIZE 0u /* Size of Thread-Local Storage Table */ @@ -68,8 +68,8 @@ #define OS_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */ #define OS_TASK_QUERY_EN 1u /* Include code for OSTaskQuery() */ #define OS_TASK_REG_TBL_SIZE 1u /* Size of task variables array (#of INT32U entries) */ -#define OS_TASK_STAT_EN 0u /* Enable (1) or Disable(0) the statistics task */ -#define OS_TASK_STAT_STK_CHK_EN 0u /* Check task stacks from statistic task */ +#define OS_TASK_STAT_EN 0u /* 初次移植关闭CPU使用率统计任务 */ +#define OS_TASK_STAT_STK_CHK_EN 0u /* 统计任务关闭时同时关闭它的周期栈检查 */ #define OS_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */ #define OS_TASK_SW_HOOK_EN 1u /* Include code for OSTaskSwHook() */