从开始移植ecos到stm32开发板以来,“程序运行过程中时不时跑飞或死掉,或者一加载就死掉”的问题一直令我头痛和百思不得其“姐”。如下图:程序一加载就死掉了。

程序运行过程中跑飞的现象类似,也是出现这种类似信息:$T050f:00800068;0d:e80f0d68;#98$T050f……

今天在编写按键程序时,频繁出现,是时把它解决了。功夫不负有心人,终于定位问题为外扩的SRAM时序不正确导致的,重新配置下SRAM的FSMC时序就解决了。

问题定位

首先,排除是否自己编写的程序有问题。经过反复试验,保证了自己编写的程序无问题,确定了不是自己编写的程序有问题。

http://velep.com/archives/600.html一文中,曾经说到,直接下载bin格式程序到内存时,下载到内存中的数据居然有问题。redboot中使用xmodem协议的load命令应当是没有问题的,因为这是官方的代码,经过无数人的验证,如果有问题,早就暴露出来并修正了。所以,我开始怀疑是不是sram有问题了。

sram时序配置

既然怀疑SRAM有问题,所以找了个开发板光盘中有使用外扩SRAM的例程,把例程中SRAM的配置与ecos中SRAM配置进行了对比。先看下开发板例程中SRAM的配置代码(Ex021—I2S录音和回放例程(WM8978),bsp_sram.c文件):

void SRAM_Init(void)
{
	FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
	FSMC_NORSRAMTimingInitTypeDef  p;
	GPIO_InitTypeDef GPIO_InitStructure; 

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOE |
	                     RCC_APB2Periph_GPIOF, ENABLE);

	/* 配置SRAM数据线 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
	                            GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure); 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
	                            GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | 
	                            GPIO_Pin_15;
	GPIO_Init(GPIOE, &GPIO_InitStructure);

	/* 配置SRAM 地址线 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | 
	                            GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 | 
	                            GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_Init(GPIOF, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | 
	                            GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_Init(GPIOG, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; 
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	/* 配置 NOE 和 NWE */  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	/* 配置 NE3 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
	GPIO_Init(GPIOG, &GPIO_InitStructure);

	/* 配置 NBL0, NBL1 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; 
	GPIO_Init(GPIOE, &GPIO_InitStructure); 

	/* 配置FSMC */
	p.FSMC_AddressSetupTime = 0;
	p.FSMC_AddressHoldTime = 0;
	p.FSMC_DataSetupTime = 3;           /* 根据SRAM的最大速度进行调整  */
	p.FSMC_BusTurnAroundDuration = 0;
	p.FSMC_CLKDivision = 0;
	p.FSMC_DataLatency = 0;
	p.FSMC_AccessMode = FSMC_AccessMode_A;

	FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
	FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
	FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
	FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
	FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
	FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;  
	FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
	FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
	FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
	FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
	FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
	FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
	FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
	FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
	FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

	FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 

	/*!< Enable FSMC Bank1_SRAM Bank */
	FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);  
}

上面代码中,主要看下配置FSMC这段代码,参考:STM32F10xxx参考手册_cn.pdf 文档的19.5.6节内容,形成FSMC的配置字如下:

  • BCR3寄存器配置字:0x00001011;
  • BTR3寄存器配置字:0x00000300

现看下ecos中SRAM的FSMC配置字(基于我移植的模板,stm32f10xxx_misc.c文件hal_system_init()函数中):

    // Set up FSMC NOR/SRAM bank 3 for SRAM
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR3, 0x00001011 );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR3, 0x00000200 );

我们看到BTR3寄存器的配置字,两者有差异:BTR3寄存器的bit[15:8]域即数据保持时间不一样,开发板例程配置的是3个HCLK周期,而ecos中是2HCLK周期,且开发板例程配置中有明显说明:数据保持时间,根据SRAM的最大速度进行调整

肯定的是,开始板例程是正确的。把ecos中SRAM的FSMC BTR3寄存器配置字调整为与开发板例程的一样,然后重新编译出redboot再烧写到内部flash中。这时使用redboot load命令load到内存中的程序运行稳定,不再出现:程序运行过程中时不时跑飞或死掉以及程序一加载就死掉的问题。

原因分析

安富莱开发板使用的SRAM器件与ST官方STM3210E_EVAL评估板使用的SRAM器件不一样。为了省成本,开发板使用了更为便宜但也更为慢速的SRAM器件,如下描述:

安富莱开发板使用的SRAM器件

安富莱开发板使用的SRAM器件

» 文章出处: reille博客—http://velep.com , 如果没有特别声明,文章均为reille博客原创作品
» 郑重声明: 原创作品未经允许不得转载,如需转载请联系reille#qq.com(#换成@)
分享到:

 Leave a Reply

(必须)

(我会替您保密的)(必须)

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

   
© 2012 velep.com | reille blog | 管理| 粤ICP备12094833号-2| 谷歌地图| 百度地图| Suffusion theme|Sayontan Sinha

无觅相关文章插件,快速提升流量