從零開始建立uCosIII專案(二):配置uCosIII
新增BSP檔案
新建BSP.h檔案,內容如下
#ifndef _BSP_H_ #define _BSP_H_ #include <stdarg.h> #include <stdio.h> #include <cpu.h> #include <cpu_core.h> #include <lib_ascii.h> #include <lib_def.h> #include <lib_mem.h> #include <lib_str.h> #include <stm32f10x.h> #include <app_cfg.h> void BSP_Init (void); void BSP_IntDisAll (void); CPU_INT32U BSP_CPU_ClkFreq (void); #endif
新建BSP.c檔案,內容如下
/* Includes ------------------------------------------------------------------*/ #include "BSP.h" /* Private define ------------------------------------------------------------*/ #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) /* Periph functions ---------------------------------------------------------*/ void SysTick_Configuration(void); void BSP_Init(void) { /* Configure the SysTick to generate an interrupt each 1 millisecond */ SysTick_Configuration(); } void BSP_IntDisAll (void) { CPU_IntDis(); } CPU_INT32U BSP_CPU_ClkFreq (void) { RCC_ClocksTypeDef rcc_clocks; RCC_GetClocksFreq(&rcc_clocks); return ((CPU_INT32U)rcc_clocks.HCLK_Frequency); } 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); } CPU_TS_TMR CPU_TS_TmrRd (void) { return ((CPU_TS_TMR)DWT_CYCCNT); } /** * @brief Configures the SysTick to generate an interrupt each 1 ms. * @param None * @retval None */ void SysTick_Configuration(void) { /* SysTick interrupt each 1 ms with SysTick Clock equal to (HCLK/8) */ if (SysTick_Config(SystemCoreClock / 1000)) { /* Capture error */ while (1); } }
可在User資料夾下新建BSP資料夾,把這兩個檔案放進去。上一篇工程設定裡已經把BSP路徑包含進來了。
開啟includes.h檔案,去掉64和65行,改為#include <bsp.h>。
現在再次編譯一遍,應該可以通過了。
執行uCOS
修改μCOS-III\uC-CPU\Cfg\cpu_cfg.h
第135行:#if 1改為#if 0,表示不測量關中斷時間。
修改μCOS-III\uCOS-III\Cfg\os_cfg.h
第42行:#define OS_CFG_ISR_POST_DEFERRED_EN 0u,表示關閉中斷延遲提交
第44行:#define OS_CFG_TS_EN 1u改為0u,表示不時間取樣
第50行:#define OS_CFG_SCHED_LOCK_TIME_MEAS_EN 1u改為0u,表示不測量任務排程時間
第63行:#define OS_CFG_MEM_EN 1u改為0u,表示不使用記憶體管理(後面將介紹一個更好的記憶體池)
第76行:#define OS_CFG_Q_PEND_ABORT_EN 1u改為0u
第82行:#define OS_CFG_SEM_PEND_ABORT_EN 1u改為0u
第87行:#define OS_CFG_STAT_TASK_EN 1u改為0u,表示不建立統計任務
第96行:#define OS_CFG_TASK_SEM_PEND_ABORT_EN 1u改為0u
官方手冊中有這樣說明
“最低程度, uC/OS-III須建立空閒任務OS_IdleTask(),當沒有其他任務執行時就執行空閒任務。uC/OS-III也建立時基任務。 根據配置檔案中所配置的,uC/OS-III 會建立統計任務 OS_StatTask()、定時器任務OS_TmrTask()、中斷佇列處理任務OS_IntQTask()。”
這裡我們取消了OS_StatTask()和OS_IntQTask(),分別由OS_CFG_STAT_TASK_EN和OS_CFG_ISR_POST_DEFERRED_EN決定,所以系統執行起來後,最少有四個任務(外加建立任務的任務)在執行。
關於如何將uCos時基與STM32硬體時鐘繫結,有兩種方式:一種是修改startup_stm32f10x_md.s檔案中的PendSV_Handler為OS_CPU_PendSVHandler,SysTick_Handler為OS_CPU_SysTickHandler;另外一種是修改uCOS-III\Ports下的os_cpu.h、os_cpu_a.asm和os_cpu_c.c中的OS_CPU_PendSVHandler為PendSVHandler、OS_CPU_SysTickHandler為SysTickHandler,並去掉PendSV_Handler和SysTick_Handler在stm32f10x_it中的宣告和定義。
這裡我覺得采用第二種比較合適。
在app.c中的142行處設定斷點,啟動程式,怎麼樣,是不是每隔200毫秒break一次呢。
看我大招