zoukankan      html  css  js  c++  java
  • u-boot下延时程序失效的bug调试

    最近在工作中的一个项目中,大概是将两块板卡相连(一块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
    );  
            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关键字,这个关键词作用如下:这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了,因此编译器不会对这个变量进行优化,而是每次重新读取这个值

  • 相关阅读:
    golang 常见疑惑总结
    golang 详解defer
    golang调试工具Delve
    ACE的源码划分
    通过#define连接字符串的特殊方法[转]
    转:extern "C"的用法解析
    转:3d max 2013 安装教程,凭着一种互联网精神提供给广大朋友
    转:Bullet物理引擎不完全指南(Bullet Physics Engine not complete Guide)
    转:折腾一晚上Bullet及Ogre相关工具的成果 -- 3Ds Max,Maya, blender, GameKit
    转:CMake快速入门教程-实战
  • 原文地址:https://www.cnblogs.com/Ethan-Gao/p/7420440.html
Copyright © 2011-2022 走看看