最近由于工作的需要,需要移植uCosIII到stm32f107,移植完成后就写了这个文章来记录移植的过程,其中主要参考了安富莱的uCosIII教程,更多具体的内容大家可以去安富莱的论坛下载。
移植前要从官网下载相关的源代码,一般官方会为 IC 厂商新推出的评估板配套相应的移植工程。对于stm32f107,Micrium也提供了相应的移植工程,我们就在此基础上进行移植。
官网地址:https://www.micrium.com/download/micrium_uc-eval-stm32f107_ucos-iii/
当然,如果从官网下载需要注册。(然后我注册之后也提示权限被拒绝。。。不知道是那里没搞对。。。)或者再这里下载:
--> UCOSIII_V3.03.01 源代码
下载完解压缩之后,里面会有如下4个文件夹:
第一步: 将这4个文件夹拷贝到自己的工程下,并建立一个uCos_User,用来存放需要需改的文件,如下如所示:
把EvalBoards\Micrium\uC-Eval-STM32F107\uCOS-III 目录下载9个文件拷贝到uCos_User文件下:
其中的app.c就是我们常用的main.c,只不过官网给他改了名字吧里,程序的入口main函数就在app.c中。这里我把app.c改回了main.c(C++版本对应main.cpp),并放到了我的User文件夹下面了。
第二步:工程中需要的文件已经都复制到工程中了,下一步就是将这些文件添加到工程里面,并添加头文件路
径。如下图所示(uC开头的):
①uC/CPU 中添加如下 6 个文件,这 6 个文件位于路径:Pro107_uCosiii\uCosIII\uC-CPU 和路径 Pro107_uCosiii\uCosIII\uC-CPU\ARM-Cortex-M3\RealView下面。
②uC/Lib 中添加如下 10 个文件,这 10 个文件位于路径 Pro107_uCosiii\uCosIII\uC-LIB 和路径 Pro107_uCosiii\uCosIII\uC-LIB\Ports\ARM-Cortex-M3\RealView 下面
③uC/OS-III Source 中添加如下 20 个文件,这 20 个文件位于路径:Pro107_uCosiii\uCosIII\uCOS-III\Source 下面
④uC/OS-III Port 中添加如下 3 个文件,这 3 个文件位于路径:Pro107_uCosiii\uCosIII\uCOS-III\Ports\ARM-Cortex-M3\Generic\RealView下面
⑤uC/User 中添加如下 9 个文件,这 9 个文件位于路径:V5-001a_GPIO 实验_跑马灯\User 下面
⑥bsp文件,将Pro107_uCosiii\uCosIII\EvalBoards\Micrium\uC-Eval-STM32F107\BSP路径下的bsp.c和bsp.h拷贝到自己的User目录下,然后添加到工程中,如下图所示:
⑦上面这些文件添加完以后,一个完整的工程就算建立了,下面需要添加一下头文件的路径,如下图所示:
⑧ 修改bsp文件和启动文件.s:
其中bsp.c中需要保留和ucos相关的几个预定义和函数,其他的部分,可以删除掉
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define BSP_MODULE
#include
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
#define BSP_LED_START_BIT (13 - 1) /* LEDs[3:1] are sequentially connected to PTD[15:13]. */
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
CPU_INT32U BSP_CPU_ClkFreq_MHz;
/*
*********************************************************************************************************
* REGISTERS
*********************************************************************************************************
*/
#define DWT_CR *(CPU_REG32 *)0xE0001000
#define DWT_CYCCNT *(CPU_REG32 *)0xE0001004
#define DEM_CR *(CPU_REG32 *)0xE000EDFC
#define DBGMCU_CR *(CPU_REG32 *)0xE0042004
/*
*********************************************************************************************************
* REGISTER BITS
*********************************************************************************************************
*/
#define DBGMCU_CR_TRACE_IOEN_MASK 0x10
#define DBGMCU_CR_TRACE_MODE_ASYNC 0x00
#define DBGMCU_CR_TRACE_MODE_SYNC_01 0x40
#define DBGMCU_CR_TRACE_MODE_SYNC_02 0x80
#define DBGMCU_CR_TRACE_MODE_SYNC_04 0xC0
#define DBGMCU_CR_TRACE_MODE_MASK 0xC0
#define DEM_CR_TRCENA (1 << 24)
#define DWT_CR_CYCCNTENA (1 << 0)
/*
*********************************************************************************************************
* BSP_CPU_ClkFreq()
*
* Description : Read CPU registers to determine the CPU clock frequency of the chip.
*
* Argument(s) : none.
*
* Return(s) : The CPU clock frequency, in Hz.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
CPU_INT32U BSP_CPU_ClkFreq (void)
{
RCC_ClocksTypeDef rcc_clocks;
RCC_GetClocksFreq(&rcc_clocks);
return ((CPU_INT32U)rcc_clocks.HCLK_Frequency);
}
/*
*********************************************************************************************************
* OSProbe_TmrInit()
*
* Description : Select & initialize a timer for use with the uC/Probe Plug-In for uC/OS-II.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : OSProbe_Init().
*
* Note(s) : none.
*********************************************************************************************************
*/
#if ((APP_CFG_PROBE_OS_PLUGIN_EN == DEF_ENABLED) && \
(OS_PROBE_HOOKS_EN == 1))
void OSProbe_TmrInit (void)
{
}
#endif
/*
*********************************************************************************************************
* OSProbe_TmrRd()
*
* Description : Read the current counts of a free running timer.
*
* Argument(s) : none.
*
* Return(s) : The 32-bit timer counts.
*
* Caller(s) : OSProbe_TimeGetCycles().
*
* Note(s) : none.
*********************************************************************************************************
*/
#if ((APP_CFG_PROBE_OS_PLUGIN_EN == DEF_ENABLED) && \
(OS_PROBE_HOOKS_EN == 1))
CPU_INT32U OSProbe_TmrRd (void)
{
return ((CPU_INT32U)DWT_CYCCNT);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_TS_TmrInit()
*
* Description : Initialize & start CPU timestamp timer.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : CPU_TS_Init().
*
* This function is an INTERNAL CPU module function & MUST be implemented by application/
* BSP function(s) [see Note #1] but MUST NOT be called by application function(s).
*
* Note(s) : (1) CPU_TS_TmrInit() is an application/BSP function that MUST be defined by the developer
* if either of the following CPU features is enabled :
*
* (a) CPU timestamps
* (b) CPU interrupts disabled time measurements
*
* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1'
* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'.
*
* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR'
* data type.
*
* (1) If timer has more bits, truncate timer values' higher-order bits greater
* than the configured 'CPU_TS_TMR' timestamp timer data type word size.
*
* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR'
* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be
* configured so that ALL bits in 'CPU_TS_TMR' data type are significant.
*
* In other words, if timer size is not a binary-multiple of 8-bit octets
* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple
* octet word size SHOULD be configured (e.g. to 16-bits). However, the
* minimum supported word size for CPU timestamp timers is 8-bits.
*
* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2'
* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'.
*
* (b) Timer SHOULD be an 'up' counter whose values increase with each time count.
*
* (c) When applicable, timer period SHOULD be less than the typical measured time
* but MUST be less than the maximum measured time; otherwise, timer resolution
* inadequate to measure desired times.
*
* See also 'CPU_TS_TmrRd() Note #2'.
*********************************************************************************************************
*/
#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
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_TS_TmrRd()
*
* Description : Get current CPU timestamp timer count value.
*
* Argument(s) : none.
*
* Return(s) : Timestamp timer count (see Notes #2a & #2b).
*
* Caller(s) : CPU_TS_Init(),
* CPU_TS_Get32(),
* CPU_TS_Get64(),
* CPU_IntDisMeasStart(),
* CPU_IntDisMeasStop().
*
* This function is an INTERNAL CPU module function & MUST be implemented by application/
* BSP function(s) [see Note #1] but SHOULD NOT be called by application function(s).
*
* Note(s) : (1) CPU_TS_TmrRd() is an application/BSP function that MUST be defined by the developer
* if either of the following CPU features is enabled :
*
* (a) CPU timestamps
* (b) CPU interrupts disabled time measurements
*
* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1'
* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'.
*
* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR'
* data type.
*
* (1) If timer has more bits, truncate timer values' higher-order bits greater
* than the configured 'CPU_TS_TMR' timestamp timer data type word size.
*
* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR'
* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be
* configured so that ALL bits in 'CPU_TS_TMR' data type are significant.
*
* In other words, if timer size is not a binary-multiple of 8-bit octets
* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple
* octet word size SHOULD be configured (e.g. to 16-bits). However, the
* minimum supported word size for CPU timestamp timers is 8-bits.
*
* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2'
* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'.
*
* (b) Timer SHOULD be an 'up' counter whose values increase with each time count.
*
* (1) If timer is a 'down' counter whose values decrease with each time count,
* then the returned timer value MUST be ones-complemented.
*
* (c) (1) When applicable, the amount of time measured by CPU timestamps is
* calculated by either of the following equations :
*
* (A) Time measured = Number timer counts * Timer period
*
* where
*
* Number timer counts Number of timer counts measured
* Timer period Timer's period in some units of
* (fractional) seconds
* Time measured Amount of time measured, in same
* units of (fractional) seconds
* as the Timer period
*
* Number timer counts
* (B) Time measured = ---------------------
* Timer frequency
*
* where
*
* Number timer counts Number of timer counts measured
* Timer frequency Timer's frequency in some units
* of counts per second
* Time measured Amount of time measured, in seconds
*
* (2) Timer period SHOULD be less than the typical measured time but MUST be less
* than the maximum measured time; otherwise, timer resolution inadequate to
* measure desired times.
*********************************************************************************************************
*/
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
CPU_TS_TMR CPU_TS_TmrRd (void)
{
return ((CPU_TS_TMR)DWT_CYCCNT);
}
#endif
修改启动文件startup_stm32f10x_cl.s,修改这个文件中 Systick 和 PendSV 中断入口名,以便于和μ
COS-III 中命名统一。
DCD OS_CPU_PendSVHandler
DCD OS_CPU_SysTickHandler
OS_CPU_PendSVHandler PROC
EXPORT OS_CPU_PendSVHandler [WEAK]
B .
ENDP
OS_CPU_SysTickHandler PROC
EXPORT OS_CPU_SysTickHandler [WEAK]
B .
ENDP
到此,uCosIII的移植就全部完成了。
下面提供我自己移植的C和C++两个版本的工程,有需要的请自行下载。