今天调试UCOSiii的程序,遇到一个问题,程序停止在等待PLL工作的while循环中。
硬件环境: stm32f439igt单板
软件环境: UCOSIII,代码从USOS官网直接下单,没有做任何改动
编译环境: IAR
最近有个项目用到了STM32F439, 客户要求跑一个小的系统调度内核,UCOSII或者UCOSIII。
所以就直接去UCOS的官网查找了一下,还真有439内核的UCOS, 下载下来,编译,连接仿真器运行。
发现程序移植停止在这个函数中:
void BSP_Init (void)
{
CPU_INT32U reg_val;
CPU_INT32U hse_rdyctr ;
BSP_IntInit();
/* ---------- RESET CLOCK CONFIG. REGISTERS ----------- */
DEF_BIT_SET(BSP_REG32_RCC_CR,BSP_BIT_RCC_CR_HSION); /* Set HSION bit */
BSP_REG32_RCC_CFGR = (CPU_INT32U)0u; /* Reset CFGR register */
BSP_REG32_RCC_CR &= 0xFEF6FFFFu; /* Reset HSEON, CSSON and PLLON bits */
BSP_REG32_RCC_PLLCFGR = BSP_MSK_RCC_PLLCFGR_RST; /* Reset PLLCFGR register */
DEF_BIT_CLR(BSP_REG32_RCC_CR, BSP_BIT_RCC_CR_HSEBYP); /* Reset HSEBYP bit */
/* ----------- HSE OSCILLATOR CONFIGURATION ----------- */
/* HSE = 8MHz Ext. crystal. */
DEF_BIT_CLR(BSP_REG32_RCC_CR,BSP_MSK_HSECFG);
DEF_BIT_SET(BSP_REG32_RCC_CR,BSP_BIT_RCC_CR_HSEON);
/* Wait for HSE to Start Up */
do {
hse_rdyctr++;
} while ((hse_rdyctr < HSE_TIMEOUT_VAL) &&
DEF_BIT_IS_CLR(BSP_REG32_RCC_CR, BSP_BIT_RCC_CR_HSERDY));
if (hse_rdyctr == HSE_TIMEOUT_VAL) {
return;
}
/* --------------- SET UP THE AHB PRESCALER ----------- */
/* HCLK = AHBCLK = PLL / AHBPRES(1) = 168MHz. */
reg_val = (CPU_INT32U)0u;
reg_val = BSP_REG32_RCC_CFGR;
DEF_BIT_CLR(reg_val, BSP_MSK_RCC_CFGR_HPRE); /* Clear HPRE[3:0] bits */
DEF_BIT_SET(reg_val, BSP_MSK_RCC_CFGR_SYSCLKDIV1); /* Set HPRE[3:0] bits according to RCC_SYSCLK value */
BSP_REG32_RCC_CFGR = reg_val; /* Store the new value in RCC_CFGR register */
/* ---------------- CONFIGURE APB2 CLOCK -------------- */
/* APB2CLK = AHBCLK / APB2DIV(2) = 84MHz. */
reg_val = BSP_REG32_RCC_CFGR;
DEF_BIT_CLR(reg_val, BSP_MSK_RCC_CFGR_PPRE2); /* Clear PPRE2[2:0] bits */
DEF_BIT_SET(reg_val, BSP_MSK_RCC_CFGR_HCLK_DIV2 << 3u); /* Set PPRE2[2:0] bits according to RCC_HCLK value */
BSP_REG32_RCC_CFGR = reg_val; /* Store the new value */
/* ---------------- CONFIGURE APB1 CLOCK -------------- */
/* APB1CLK = AHBCLK / APB1DIV(4) = 42MHz (max). */
reg_val = BSP_REG32_RCC_CFGR;
DEF_BIT_CLR(reg_val,BSP_MSK_RCC_CFGR_PPRE1); /* Clear PPRE1[2:0] bits */
DEF_BIT_SET(reg_val, BSP_MSK_RCC_CFGR_HCLK_DIV4); /* Set PPRE1[2:0] bits according to RCC_HCLK value */
/* Store the new value in RCC_CFGR register */
BSP_REG32_RCC_CFGR = reg_val;
/* ------------- CONFIGURE AND ENABLE PLL ------------- */
/* PLL_M = 8, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */
/* PLLCLK = HSE * (PLLN / PLLM) = 336MHz. */
/* SYSCLK = PLLCLK / PLLP = 168MHz. */
/* OTG_FSCLK = PLLCLK / PLLQ = 48MHz. */
BSP_REG32_RCC_PLLCFGR = ( BSP_BIT_RCC_PLLCFGR_PLLM ) |
( BSP_BIT_RCC_PLLCFGR_PLLN << 6u ) |
( BSP_MSK_PLLCFGR_PLLSRC_HSE ) |
((BSP_BIT_RCC_PLLCFGR_PLLP >> 1u ) -1u ) << 16u |
( BSP_BIT_RCC_PLLCFGR_PLLQ << 24u);
DEF_BIT_SET( BSP_REG32_RCC_CR, BSP_BIT_RCC_CR_PLLON);
/* Wait for PLL to lock. */
while ( DEF_BIT_IS_CLR( BSP_REG32_RCC_CR,
BSP_BIT_RCC_CR_PLLRDY)) {
;
}
/* ------------- CONFIGURE FLASH MEMORY --------------- */
DEF_BIT_SET(BSP_REG32_FLASH_ACR, BSP_MSK_FLASHLATENCY_5WS); /* Allow 5 Flash Wait States when HCLK > 120MHz. */
/* Enable Prefetch, Instruction Cache, and Data Cache. */
DEF_BIT_SET(BSP_REG32_FLASH_ACR, (BSP_BIT_FLASH_ACR_PRFTEN |
BSP_BIT_FLASH_ACR_ICEN |
BSP_BIT_FLASH_ACR_DCEN));
/* -------- SELECT PLL OUTPUT AS SYSTEM CLOCK --------- */
/* HCLK = SYSCLK = PLL = 168MHz. */
DEF_BIT_SET(BSP_REG32_RCC_CFGR, BSP_MSK_SYSCLK_SRC_PLLCLK);
while((BSP_REG32_RCC_CFGR & BSP_MSK_RCC_CFGR_SWS) /* Wait until PLL is selected as system clock source */
!= BSP_MSK_RCC_CFGR_SWS_PLL){
;
}
BSP_LED_Init(); /* Initialize user LEDs */
#ifdef TRACE_EN /* See project / compiler preprocessor options. */
BSP_CPU_REG_DBGMCU_CR |= BSP_DBGMCU_CR_TRACE_IOEN_MASK; /* Enable tracing (see Note #2). */
BSP_CPU_REG_DBGMCU_CR &= ~BSP_DBGMCU_CR_TRACE_MODE_MASK; /* Clr trace mode sel bits. */
BSP_CPU_REG_DBGMCU_CR |= BSP_DBGMCU_CR_TRACE_MODE_SYNC_04; /* Cfg trace mode to synch 4-bit. */
#endif
}
一直停止在红色代码中,跳不出循环。
查找所有代码,设置都没有问题。
于是继续往前查, 查到HSE是否运行时,发现局部变量hse_rdyctr 的计数远远超过500,很显然超过500是不对的。
再仔细看,发现这个局部变量在定义的时候并没有初始化成一个确定的数值。
用仿真器查看,果然是这里出的问题,定义之后,变量自动初始化成0x50505050, 所以系统在判断等待超时的那个地方,根本没有判断,因为初始值一进去就跳出来。
手工初始化成0.问题解决。
可能是编译器设置的问题,局部变量的初始化没有配置好。等有时间继续查吧