1、 Author
Hank Fu (付漢杰) Staff FAE embedded, Xilinx, Inc.hankf@xilinx.com
2、問(wèn)題
有工程師反映,根據(jù)MPSoC SWDT在Standalone下的例子xwdtps_polled_example.c,不能實(shí)現(xiàn)MPSoC的PS復(fù)位。SWDT例子來(lái)自于目錄XilinxSDK2018.3dataembeddedswXilinxProcessorIPLibdriverswdtps_v3_1examples。SWDT例子xwdtps_polled_example.c只檢查了超時(shí)狀態(tài),沒(méi)有實(shí)現(xiàn)復(fù)位。工程師把其中的“XWdtPs_DisableOutput(&Watchdog, XWDTPS_RESET_SIGNAL)”改為“XWdtPs_EnableOutput(&Watchdog, XWDTPS_RESET_SIGNAL)”,仍然不能復(fù)位。
工程師根據(jù)FSBL的main.c中的InitWatchDog( ),添加代碼后,依然不能使MPSoC的PS復(fù)位。
3、 分析
3.1. FSBL的main.c
main.c是Zynq-7000的FSBL的代碼??蛻?hù)使用SOurce Insight分析代碼時(shí),使用了錯(cuò)誤的文件。
3.2. MPSoC的FSBL
MPSoC的FSBL的主文件是xfsbl_main.c,wdt的代碼在xfsbl_misc_drivers.c和xfsbl_misc_drivers.h中,初始化WDT的函數(shù)是u32 XFsbl_InitWdt(void),宏定義XFSBL_WDT_EXPIRE_TIME定義了FSBL中wdt的超時(shí)時(shí)間。
在XFsbl_InitWdt(void)中,初始化并啟動(dòng)WDT(XWdtPs_RestartWdt( ))后,直接使用sleep(20),睡眠20秒。睡眠過(guò)程中,因?yàn)閃DT超時(shí),MPSoC的PS會(huì)被復(fù)位。這說(shuō)明FSBL關(guān)于WDT代碼是正確的。
3.3. Standalone下的WDT
對(duì)比MPSoC FSBL初始化WDT的函數(shù)XFsbl_InitWdt( ),發(fā)現(xiàn)它設(shè)置了PMU的ERROR_SRST_EN_1 Register和ERROR_EN_1 Register。把相關(guān)代碼復(fù)制到Standalone下的代碼,在初始化WDT之前運(yùn)行。重新編譯后,WDT超時(shí)會(huì)復(fù)位MPSoC的PS。
3.4. 再次運(yùn)行時(shí),設(shè)置PMU的ERROR_SRST_EN_1后,PS馬上復(fù)位。
WDT超時(shí)后,再次使用Debugger運(yùn)行時(shí),設(shè)置PMU的ERROR_SRST_EN_1后,WDT還沒(méi)有被初始化時(shí),PS馬上被復(fù)位。檢查PMU ERROR_STATUS_1 Register,發(fā)現(xiàn)WDT的超時(shí)狀態(tài)為1。于是把讀取到的ERROR_STATUS_1的值,再寫(xiě)回ERROR_STATUS_1 Register,清除WDT的超時(shí)狀態(tài)。
這樣在WDT超時(shí)后,設(shè)置PMU的ERROR_SRST_EN_1后,PS不會(huì)馬上被復(fù)位。
3.5. FPD_SWDT 和 LPD_SWDT
工程師發(fā)現(xiàn)使用LPD_SWDT,能復(fù)位PS;換成FPD_SWDT,不能復(fù)位PS。
在設(shè)置PMU的ERROR_SRST_EN_1 Register和ERROR_EN_1 Register時(shí),LPD_SWDT和FPD_SWDT有各自的使能位。增加設(shè)置FPD_SWDT的使能位后,換成FPD_SWDT,也能復(fù)位PS。
#define PMU_GLOBAL_ERROR_SRST_EN_1 ( ( PMU_GLOBAL_BASEADDR ) + 0X0000056CU ) #define PMU_GLOBAL_ERROR_SRST_EN_1_LPD_SWDT_MASK 0X00001000U #define PMU_GLOBAL_ERROR_SRST_EN_1_FPD_SWDT_MASK 0X00002000U04 Vivado 設(shè)置
使用WDT,要在Vivado里的PCW里,使能對(duì)應(yīng)的WDT。
5、相關(guān)代碼
5.1. 檢查和清除PMU寄存器
xil_printf(" " ); u32_reg = Xil_In32(0xFFD80530); xil_printf("Old PMU ERROR_STATUS_1 (PMU_GLOBAL) Register: %x. ", u32_reg ); Xil_Out32(0xFFD80530, u32_reg); // Clear PMU ERROR_STATUS_1 (PMU_GLOBAL) Register u32_reg = Xil_In32(0xFFD80540); xil_printf("Old PMU ERROR_STATUS_2 (PMU_GLOBAL) Register: %x. ", u32_reg ); Xil_Out32(0xFFD80540, u32_reg); // Clear PMU ERROR_STATUS_2 (PMU_GLOBAL) Register u32_reg = Xil_In32(0xFFD80530); xil_printf("New PMU ERROR_STATUS_1 (PMU_GLOBAL) Register: %x. ", u32_reg ); u32_reg = Xil_In32(0xFFD80540); xil_printf("New PMU ERROR_STATUS_2 (PMU_GLOBAL) Register: %x. ", u32_reg );
5.2. 檢查SWDT寄存器狀態(tài)
void CheckWDTRegisterValue( u32 EffectiveAddress ) { u32 u32_reg; u32_reg = XWdtPs_ReadReg(EffectiveAddress, XWDTPS_ZMR_OFFSET); xil_printf("WDT Zero Mode Register: %x. ", u32_reg ); u32_reg = XWdtPs_ReadReg(EffectiveAddress, XWDTPS_CCR_OFFSET); xil_printf("WDT Counter Control Register: %x. ", u32_reg ); u32_reg = XWdtPs_ReadReg(EffectiveAddress, XWDTPS_RESTART_OFFSET); xil_printf("WDT Restart Register: %x. ", u32_reg ); u32_reg = XWdtPs_ReadReg(EffectiveAddress, XWDTPS_SR_OFFSET); xil_printf("WDT Status Register: %x. ", u32_reg ); }
-
Standalone
+關(guān)注
關(guān)注
0文章
4瀏覽量
6544 -
MPSoC
+關(guān)注
關(guān)注
0文章
196瀏覽量
24232
原文標(biāo)題:【干貨分享】MPSoC SWDT在Standalone下的應(yīng)用
文章出處:【微信號(hào):FPGA-EETrend,微信公眾號(hào):FPGA開(kāi)發(fā)圈】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論