u-boot下延時程序失效的bug調試
阿新 • • 發佈:2017-08-23
val boot 結果 dump pre spa quest pri 默認
結果:
最近在工作中的一個項目中,大概是將兩塊板卡相連(一塊STM32跑裸機程序,另一塊AM335x跑Linux系統),但是發現在u-boot有時無法啟動成功,需要通過一個GPIO的狀態來判斷,具體來說就是本來上電後端口默認高阻抗,先利用程序先拉低大概100ms,然後在使用程序拉高100ms,然後STM32程序檢測這段電平跳變,從而確定系統正確啟動,否則會進行軟件復位使AM335X的單板能夠正常啟動,程序本身並不難,但是調試時遇到了一個奇怪的bug,簡單記錄下。
平臺:
am335x,u-boot v2010.07,linux v3.1,arm-none-linux-gcc 2009.01
代碼:
核心部分如下
//gpmc_a5(GPIO1_21=1*32+21=53):first low for 100ms,then high for 100ms
void set_gpmc_a5_level(void){
int i = 0;
configure_module_pin_mux(gpmc_a5_pin_mux);
if(gpio_request(53, "gpmc_a5") != 0) {
printf("gpmc_a5 request failed\n);
return;
}
gpio_direction_output(53, 0);
while(1){
gpio_set_value(53 , 0);
for (i = 0; i < 500; i++);
gpio_set_value(53, 1);
for (i = 0; i < 100; i++);
}
}
問題:
編譯燒寫到單板,使用示波器測量,發現這個GPIO口的占空比始終為50%,高低電平一直都是2ms左右,然後又修改了幾個數字,發現依舊這樣
調試:
由於程序看不出問題,示波器測得波形有問題,就考慮使用objdump對u-boot進行反匯編看看最後編譯成的實際代碼,然後發現無論如何修改for (i = 0; i < 500; i++);這句話裏面的時間,反匯編裏面的set_gpmc_a5_level延時都是0x53,示波器測得是2ms,後來考慮到u-boot可能會對代碼進行優化,嘗試修改了變量為volatile int i = 0;,重新測量波形,一切正常
結果:
volatile int i = 0;
由於此版本u-boot會對代碼進行優化,因此需要加volatile關鍵字,這個關鍵詞作用如下:這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了,因此編譯器不會對這個變量進行優化,而是每次重新讀取這個值
u-boot下延時程序失效的bug調試