STM32开发笔记80: 在构造函数中调用延时函数应注意的问题

单片机型号:STM32L053R8T6


W5500驱动程序完成后,运行时,单片机死机。W5500驱动程序先前已经在项目中具体应用过,运行的比较稳定。这次移植后,没有做改动,但是单片机运行时死机。

此项目与先前项目的不同点在于,项目中有FreeRTOS操作系统运行,原先的项目没有,最后将问题聚焦于W5500的构造函数上,如下程序所示:

CW5500::CW5500(void):CSpi()
{
	//uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};
		
	//注册相关的函数
	reg_wizchip_cris_cbfunc(w5500_cris_enter, w5500_cris_exit);
	reg_wizchip_cs_cbfunc(w5500_cs_select, w5500_cs_deselect);
	reg_wizchip_spi_cbfunc(w5500_spi_readbyte, w5500_spi_writebyte);
    //硬件复位w5500
    this->reset();
    //软件复位w5500
    ctlwizchip(CW_RESET_WIZCHIP, (void*)NULL);
    //初始化socket buffer
    ctlwizchip(CW_INIT_WIZCHIP, (void*)memsize);
}

void CW5500::reset(void)
{
	this->W5500_RESET.Set_1();
	Target.Delayms(10);
	this->W5500_RESET.Set_0();
	Target.Delayms(10);
	this->W5500_RESET.Set_1();
	Target.Delayms(10);
}

驱动程序在构造函数中调用了延时函数,而延时函数具体的实现如下:

void CTarget::Delayms(uint16_t u16_ms)
{
	osDelay(u16_ms);		
}

延时函数直接调用了FreeRTOS操作系统的osDelay。原先程序的延时函数是如下实现的:

void CTarget::Delayms(uint16_t u16_ms)
{
	HAL_Delay(u16_ms);
#if IWDG_MODE != 0			
	this->Iwdg.Refresh();
#endif
}

再看main函数,程序如下:

int main(void)
{
  osThreadDef(DefaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  DefaultTaskHandle = osThreadCreate(osThread(DefaultTask), NULL);

	osKernelStart();
	
	//以下程序不会被执行
  while (1)
  {

  }
}

FreeRTOS操作系统是在main函数中启动的,也就是只有执行完osKernelStart函数,osDelay函数才会起作用。而构造函数是先于main函数之前执行的,所以驱动程序调用延时函数时,操作系统还没有启动,导致死机现象的出现。

解决方法:

(1)用上述2种方式实现延时函数,通过参数传递加以选择;

(2)或者不在构造函数中调用延时函数。

我觉得第2种方法是比较好的。

 

 

原创性文章,转载请注明出处CSDN:http://blog.csdn.net/qingwufeiyang12346。

 

 

 

 

你可能感兴趣的:(#,STM32快速开发,STM32快速开发)