|
在開(kāi)發(fā)一款智能化儀器時(shí),需定時(shí)采集數(shù)據(jù),并同時(shí)進(jìn)行數(shù)據(jù)分析、儲(chǔ)存和遠(yuǎn)距離光纖傳送。因此選用了帶有浮點(diǎn)運(yùn)算功能的STM32F407高性能 MCU。也移植了許多STM32F4的標(biāo)準(zhǔn)例程。程序編譯仿真等一切順利。但試運(yùn)行時(shí)不定時(shí)死機(jī),多則幾天,少則幾小時(shí),毫無(wú)規(guī)律。
死機(jī)的原因很多,如環(huán)境干擾;電路板設(shè)計(jì)不合理產(chǎn)生自激;中斷沖突;中斷程序中沒(méi)有清除中斷標(biāo)志位;地址溢出;堆棧溢出;無(wú)條件的死循環(huán)等等。
因是試機(jī)時(shí)死機(jī),所以首先考慮環(huán)境干擾問(wèn)題,經(jīng)屏蔽隔離,消除環(huán)境干擾后,故障依舊,機(jī)外因素排除。
認(rèn)真檢查了各中斷優(yōu)先等級(jí),設(shè)置的中斷時(shí)刻,中斷服務(wù)函數(shù)等均無(wú)任何沖突。仿真檢查也無(wú)異常。折騰了一天,程序梳理了幾遍,也沒(méi)發(fā)現(xiàn)蛛絲馬跡,但故障依舊。
無(wú)奈之際,利用逐一停用程序模塊的方法發(fā)現(xiàn)了問(wèn)題,當(dāng)停用sd卡模塊后不再死機(jī)。可以斷定問(wèn)題出在SD卡模塊上,但是SD卡模塊程序是移植的標(biāo)準(zhǔn)例程,不會(huì)是標(biāo)準(zhǔn)例程有問(wèn)題吧!
于是對(duì)sdio_sdcard.c文件逐句分析。在SD_Error SD_SelectDeselect(u32 addr)函數(shù)中發(fā)現(xiàn)如下加黑的語(yǔ)句:
while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)
{
*tempbuff=SDIO->FIFO;
tempbuff++;
}
INTX_ENABLE();
SDIO_ClearFlag(SDIO_STATIC_FLAGS);
}else if(DeviceMode==SD_DMA_MODE)
{
TransferError=SD_OK;
StopCondition=0;
TransferEnd=0;
SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<5)|(1<<9);
SDIO->DCTRL|=1<<3;
SD_DMA_Config((u32*)buf,blksize,DMA_DIR_PeripheralToMemory);
while(((DMA2->LISR&(1<<27))==RESET)&&(TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;
if(timeout==0)return SD_DATA_TIMEOUT;
if(TransferError!=SD_OK)errorstatus=TransferError;
}
return errorstatus;
}
匯編語(yǔ)言中
CPSID I PRIMASK=1 是關(guān)閉中斷
CPSIE I PRIMASK=0 是開(kāi)啟中斷
INTX_ENABLE()是在sys.h中用匯編語(yǔ)言定義的開(kāi)啟所有中斷函數(shù);
即:
_asm void INTX_ENABLE(void)
{
CPSIE I
BX LR
}
INTX_DISABLE()是在sys.h中用匯編語(yǔ)言定義的關(guān)閉所有中斷函數(shù);
即:
__asm void INTX_DISABLE(void)
{
CPSID I
BX LR
}
指令“CPSID I和CPSIE I”都是對(duì)狀態(tài)寄存器CPSR中中斷標(biāo)志位進(jìn)行操作,只是簡(jiǎn)單的不讓CPU響應(yīng)中斷,并沒(méi)有阻止中斷的發(fā)生,也沒(méi)有清除中斷標(biāo)志。
SDIO_ClearFlag(SDIO_STATIC_FLAGS)是在STM32f4xx_sdio.c 中定義的,是清除SDIO 掛起標(biāo)志庫(kù)函數(shù)。
至此不定時(shí)死機(jī)的機(jī)理就真相真相大白了:由于采集的數(shù)據(jù)各不相同,處理這些數(shù)據(jù)的耗時(shí)也不相同,處理數(shù)據(jù)后產(chǎn)生的中斷時(shí)間也就不固定。雖然在程序編制時(shí)精心安排了各中斷的優(yōu)先等級(jí),某些外設(shè)中斷還會(huì)提前或延時(shí)到CF卡的讀寫(xiě)時(shí)間段內(nèi)。因在sdio_sdcard.c函數(shù)中,多次使用了INTX_DISABLE()與INTX_ENABLE()函數(shù)關(guān)閉和開(kāi)啟中斷。由于這些函數(shù)沒(méi)有阻止中斷的發(fā)生,中斷發(fā)生時(shí)同樣會(huì)產(chǎn)生中斷標(biāo)志,只是暫時(shí)停止中斷的執(zhí)行。當(dāng)開(kāi)啟所有中斷時(shí),就有可能出現(xiàn)多個(gè)中斷標(biāo)志,使中斷發(fā)生沖突,這必定會(huì)引起死機(jī)。
解決辦法是注銷掉sdio_sdcard.c文件所有INTX_DISABLE()和INTX_ENABLE()函數(shù),把cf卡的讀寫(xiě)操作放入一個(gè)中斷服務(wù)函數(shù)中,并把該中斷設(shè)為最高等級(jí),退出中斷服務(wù)函數(shù)前,先清除所有中斷標(biāo)志。經(jīng)此處理后再也沒(méi)出現(xiàn)過(guò)死機(jī)。
|
評(píng)分
-
查看全部評(píng)分
|