精华内容
下载资源
问答
  • 近期在用nios ii做项目时,发现一个奇怪的现象,在NIOS II EDS软件中编写好的代码,烧写到芯片中,第一次能够正常运行,但是当我按下板卡上的复位键之后,系统却卡死了,再也运行不起来,除非重新下载程序。
  • 近期在用nios ii做项目时,发现一个奇怪的现象,在NIOS II EDS软件中编写好的代码,烧写到芯片中,第一次能够正常运行,但是当我按下板卡上的复位键之后,系统却卡死了,再也运行不起来,除非重新下载程序。...

    http://bbs.ednchina.com/BLOG_ARTICLE_3029418.HTM?source=sina


    近期在用nios ii做项目时,发现一个奇怪的现象,在NIOS II EDS软件中编写好的代码,烧写到芯片中,第一次能够正常运行,但是当我按下板卡上的复位键之后,系统却卡死了,再也运行不起来,除非重新下载程序。经过分析系统可知,系统的硬件设计和Qsys系统中NIOS II CPU系统的搭建都是没有任何问题的。那么为什么会存在这样的问题呢,这里我先简单介绍下我的系统:

    我的系统主要由NIOS II最强板CPUSDRAM、预留系统定时器、预留时间戳定时器、system IDEPCS控制器以及JTAG_UART组成。具体如下图所示(点击图片可查看高清大图):

    Qsys环境中,我一开始将CPU的复位向量(Reset Vector)设定在了EPCS上,然后在NIOS II EDS中建立了软件工程,编译,下载运行都没有问题,但是并没有将fpga配置文件和代码固化到EPCS中去,因此复位时存在问题是肯定的。后来为了调试方便,在Qsys系统中将CPU的复位向量也修改指向了SDRAM,然后在NIOS II EDS软件中,重新生成了BSP之后,软件的编译,下载运行都没有问题,只是每当我按下板卡上的复位键之后,系统却卡死了,再也运行不起来。

    记起去年做毕业设计时,曾经为在含有EPCS的系统中无法下载程序的问题苦恼过,当时下载程序时,每次都在进度为64%时报如下的错误,“Nios II ‘Launching New_configuration’ has ecountered a problem.Dowenloading Elf Process failed.”相信这个报错也是大家最深恶痛绝的(注,此图是我从网上下载的,自己做系统已经很久不出这个问题了,想弄张这样的图片只能百度了):

    在网上找了一大堆问题,有说是SDRAM相位不对的,这个我以前也确实遇见过不过自从我将SDRAM的时钟相移设定为-90度后,就基本没遇到过这个问题了。还有说是硬件本身有问题的,这里不排除此种情况,但是我的系统中却并非如此。最终是在新浪博客还是百度空间中的某位前辈的文章中找到的答案我忘记了。当时忘了记下博客地址了,只是将内容复制出来,存了一个word文档。现在这篇文档已经能够在百度文库中直接检索到了,尊重他人版权,我这里就只发文章在文库中的地址了:

    http://wenku.baidu.com/link?url=YOyixrJXWj0ZunlJGqdUFdLv8wkF1KCXxXcEkHGpaulHwlsXPwjR29GxGBxQ-AhMrwot6oKnSziAdDYZrGayB6ZrLu8XaAHmhIikud3wPNC

     

    他的解决方案就是在BSP editor中修改了两个与bootloader位置相关的选项,将allow_code_at_resetenable_alt_load两个选项的勾选取消了,如下图(点击图片可查看高清大图):

     

    该文章中介绍,当创建不带EPCS控制器的NIOS II系统时,在NIOS II EDS中创建工程时,bsp editor中这两项是勾选上的。当创建了带EPCS控制器的NIOS II系统时,在NIOS II EDS中创建工程时,bsp editor中这两项是没有勾选上的。由此可知,当复位向量为SDRAM时,这两个选项应该勾选上。具体的原因见该文中作者在Altera提供的相关手册中找到原始解释。

    当我在系统中将此两项勾选上后,再次生成bsp,然后编译、下载,处理器就能够正常执行复位了。

     

    小梅哥

    2015526日于北京至芯科技

    展开全文
  • 当处理器的复位电平有效时,产生复位异常,程式跳转到复位异常处执行(异常向量:0x0000,0000);   2、未定义指令(优先级6) 当ARM 处理器或协处理器遇见不能处理的指令时,产生为定义异常。可使用...
  • 本篇博客主要讲授华大半导(STM32、C51等单片机均可适用)复位(以看门狗复位为例)后变量数据保存的方法。 这里将用到__not_init属性,其用于变量声明,可禁止系统启动时变量的初始化,有了__not_init属性,编译器...

    目录

    1、理论

    2、实践


    1、理论

    众所周知,单片机复位后变量数值会自动初始化,以华大半导体HC32L136为例,具有 7 个复位信号来源,每个复位信号都可以让 CPU 重新运行,绝大多数寄存器会被复位到复位值,程序会从复位向量处开始执行。

    • 数字区域上电掉电复位 POR
    • 外部 Reset PAD,低电平为复位信号
    • WDT 复位
    • PCA 复位
    • LVD 低电压复位
    • Cortex-M0+ SYSRESETREQ 软件复位
    • Cortex-M0+ LOCKUP 硬件复位

    每个复位源由相应的复位标志进行指示,复位标志均由硬件置位,需要用户软件清零。

    华大半导体各区域的复位来源如下图所示:

    本篇博客主要讲授华大半导(STM32、C51等单片机均可适用)复位(以看门狗复位为例)后变量数据保存的方法。

    这里将用到__not_init属性,其用于变量声明,可禁止系统启动时变量的初始化,有了__not_init属性,编译器只给指定变量分配空间,不会再初始化。

    __not_init的两种定义方式如下所示:

        方式1:不指定存储位置,由编译器分配
        __no_init 类型 变量名;        ///< 例如:__no_init uint8_t cou_num;
        方式2:指定存储位置
        __no_init 类型 变量名 @地址;  ///< 例如:__no_init uint8_t cou_num @0x20000000;

    2、实践

    实践描述:使用__no_init属性创建一个变量cou_num,其将数据存储在SRAM中,每隔300毫秒自加1并通过串口打印输出数值,当检测到上电复位和按键复位后,变量cou_num数值置为0,在看门狗复位下变量cou_num数值不变。

    第1步:配置串口引脚、串口使能和串口中断,代码如下所示:

    ///< 串口引脚配置
    static void App_PortInit(void)
    {
        stc_gpio_cfg_t stcGpioCfg;
    
        DDL_ZERO_STRUCT(stcGpioCfg);
        ///< 使能GPIO模块时钟
        Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); 
    
        ///< 配置PA02端口为URART1_TX
        stcGpioCfg.enDir = GpioDirOut;
        Gpio_Init(GpioPortA, GpioPin2, &stcGpioCfg);
        Gpio_SetAfMode(GpioPortA, GpioPin2, GpioAf1);            
    }
    
    ///< 串口配置
    static void App_UartCfg(void)
    {
        stc_uart_cfg_t    stcCfg;
    
        DDL_ZERO_STRUCT(stcCfg);
    
        ///< 开启UART1外设时钟
        Sysctrl_SetPeripheralGate(SysctrlPeripheralUart1,TRUE);
    
        ///< UART1初始化
        stcCfg.enRunMode        = UartMskMode3;           ///< 模式3
        stcCfg.enStopBit        = UartMsk1bit;            ///< 1bit停止位
        stcCfg.enMmdorCk        = UartMskEven;            ///< 偶检验
        stcCfg.stcBaud.u32Baud  = 9600;                   ///< 波特率9600  注意误差
        stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;        ///< 通道采样分频配置
        stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();  ///< 获得外设时钟(PCLK)频率值
        Uart_Init(M0P_UART1, &stcCfg);                    ///< 串口初始化
    
        ///< UART1中断使能
        Uart_ClrStatus(M0P_UART1,UartTC);                 ///< 清发送请求
        Uart_EnableIrq(M0P_UART1,UartTxIrq);              ///< 使能串口发送中断
        EnableNvic(UART1_IRQn, IrqLevel3, TRUE);          ///< 系统中断使能
    }
    
    ///< UART1中断函数
    void Uart1_IRQHandler(void)
    {
        ///< UART1数据发送
        if(Uart_GetStatus(M0P_UART1, UartTC))         
        {
            ///< 清中断状态位
            Uart_ClrStatus(M0P_UART1, UartTC);  
        }
    }

    第2步:配置看门狗复位,每隔820毫秒若没有喂狗,则复位,代码如下所示:

    ///< WDT初始化配置
    static void App_WdtInit(void)
    {
        ///< 开启WDT外设时钟
        Sysctrl_SetPeripheralGate(SysctrlPeripheralWdt,TRUE);
        ///< WDT 初始化,喂狗时间:820ms
        Wdt_Init(WdtResetEn, WdtT820ms);
    }

    第3步:使用__no_init属性定义cou_num变量,将数组存储在SRAM寄存器0x20001000中,代码如下所示:

    __no_init uint8_t cou_num @ 0x20001000;

     第4步:添加上电复位源和RESET脚复位源检测,当检测到其中之一个复位的时候,cou_num置为0,代码如下所示:

    int32_t main(void)
    {
        char * data_buf = (char *)malloc(sizeof(char) * 19);
        
        ///< 串口引脚配置
        App_PortInit();
    
        ///< 串口配置
        App_UartCfg();
        
        ///< WDT初始化
        App_WdtInit();
       
        ///< 启动 WDT
        Wdt_Start();
        
        ///< 当上电复位或者RESET脚复位后cou_num为0,看门狗复位数值不变
        if((Reset_GetFlag(ResetFlagMskPor5V) == 1) || (Reset_GetFlag(ResetFlagMskRstb) == 1))
        {
          cou_num = 0;
    
          Reset_ClearFlag(ResetFlagMskPor5V);
          Reset_ClearFlag(ResetFlagMskRstb);
        }
       
        while (1)
        {
            cou_num = cou_num + 1;
            
            delay1ms(300);
            
            ///< 开启喂狗后,将不会产生复位
            //Wdt_Feed(); 
            
            sprintf(data_buf,"numerical value:%d\n",cou_num);
            
            for(int8_t i = 0;i < 19;i++)
            {
              Uart_SendDataIt(M0P_UART1,data_buf[i]); 
              delay1ms(5);
            }
        }
    }
    

    运行效果如下所示:

    可见虽然看门狗每隔820毫秒复位一次,但是cou_num数值不收影响,但是也可以看出cou_num数值中间存在丢失,例如没有打印输出数值3,主要原因是运行到此数时,恰巧看门狗复位,所以串口未来得及打印,但是不影响cou_num计数。

    展开全文
  • 本文通过对微处理器监控芯片MAX818在使用中出现异常复位的实例分析,说明由于电源完整性引起的系统工作不稳定现象。
  • C调试时段异常后不复位方法C调试时段异常后不复位方法段异常复位siglongjmp && sigsetjmp信号处理函数 C调试时段异常后不复位方法 在C语言调试时,经常会遇到非法访问导致段异常复位,为方便调试,可以通过...

    C调试时段异常后不复位方法

    在C语言调试时,经常会遇到非法访问导致段异常复位,为方便调试,可以通过sigsetjmp结合信号处理挂接绕过复位机制。

    段异常复位

    我们都知道访问非法地址会导致程序跑死,那程序为什么会挂呢?
    这是因为访问非法地址后,会触发异常信号(SIGSEGV 信号11),默认的信号处理函数会杀死本进程,进而表现出来就是程序跑挂了。下面是用简单的程序示例:

    #include <stdio.h>
    
    #define DEBUG do {printf("%s<%d> enter!\n", __FUNCTION__, __LINE__); fflush(stdout);} while (0)
    
    static void ErrFunc(void) {
        int *addr = (int *) 0x1234;
        int temp;
    
        DEBUG;
        temp = *addr;
        DEBUG;
    
        return ;
    }
    
    int main() {
        ErrFunc();
        return 0;
    }
    

    程序输出:

    ErrFunc<9> enter!
    Segmentation fault (core dumped)
    

    siglongjmp && sigsetjmp

    DESCRIPTION
           The  functions  described  on this page are used for performing "nonlocal gotos": transferring execution from one function to a predetermined
           location in another function.  The setjmp() function dynamically establishes the target to which  control  will  later  be  transferred,  and
           longjmp() performs the transfer of execution.
    
           The  setjmp() function saves various information about the calling environment (typically, the stack pointer, the instruction pointer, possi‐
           bly the values of other registers and the signal mask) in the buffer env for later use by longjmp().  In this case, setjmp() returns 0.
    
           The longjmp() function uses the information saved in env to transfer control back to the point where  setjmp()  was  called  and  to  restore
           ("rewind") the stack to its state at the time of the setjmp() call.  In addition, and depending on the implementation (see NOTES), the values
           of some other registers and the process signal mask may be restored to their state at the time of the setjmp() call.
    
           Following a successful longjmp(), execution continues as if setjmp() had returned for a second time.  This "fake" return can be distinguished
           from  a  true  setjmp() call because the "fake" return returns the value provided in val.  If the programmer mistakenly passes the value 0 in
           val, the "fake" return will instead return 1.
    
       sigsetjmp() and siglongjmp()
           sigsetjmp() and siglongjmp() also perform nonlocal gotos, but provide predictable handling of the process signal mask.
    
           If, and only if, the savesigs argument provided to sigsetjmp() is nonzero, the process's current signal mask is saved  in  env  and  will  be
           restored if a siglongjmp() is later performed with this env.
    

    简而言之,sigsetjmp的作用就类似于goto,但作用不局限于一个函数内。实际作用时就是如果函数直接往下走,遇到sigsetjmp接口了,那么该接口返回0,此时将环境信息保存在一个变量里,然后程序继续执行;如果函数是走到setlongjmp,则此时程序会跳转到之前保存的环境信息处,而且sigsetjmp接口返回非0值。

    信号处理函数

    Linux下提供sigaction函数用于修改信号处理函数,可以自定义信号处理函数,通过sigaction挂接,这样产生信号时就不是进入系统默认的处理函数,而是进入自定义函数。结合sigsetjmp和siglongjmp即可实现我们的目标----段异常后不复位。
    用简单的代码示例:用数字标明进入顺序

    #include <signal.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <setjmp.h>
    #include <ucontext.h>
    
    
    #define DEBUG do {printf("%s<%d> enter!\n", __FUNCTION__, __LINE__); fflush(stdout);} while (0)
    
    static sigjmp_buf s_sigEnv; /* 保存环境信息 */
    
    static void SignalHandle_Sigsegv(int signal, siginfo_t *info, void *ucontext) { /* 自定义的信号处理函数,只做简单打印和跳转 */
        DEBUG; /* 2 */
    
        printf("sig:%d, error addr:%p\n", signal, info->si_addr);
        siglongjmp(s_sigEnv, 0);
    
        return ;
    }
    
    static void SignalHandleCallBackInit(void) {
        struct sigaction actInfo;
    
        actInfo.sa_sigaction = SignalHandle_Sigsegv; /* 挂接自定义的信号处理函数 */
        actInfo.sa_flags = SA_SIGINFO; /* 传递参数到此函数中 */
        sigaction(SIGSEGV, &actInfo, NULL);
    
        return ;
    }
    
    static void ErrFunc(void) {
        int *addr = (int *) 0x1234;
        int temp;
    
        if (sigsetjmp(s_sigEnv, 0) == 0) {
            DEBUG; /* 1 */
            temp = *addr; /* 发生异常 */
            DEBUG;
        } else {
            DEBUG; /* 3 */
        }
    
        return ;
    }
    
    int main() {
        SignalHandleCallBackInit();
        ErrFunc();
        return 0;
    }
    
    

    运行结果如下:可见确实不会因为段异常而复位,而且函数执行顺序如我们期待。

    ErrFunc<36> enter!
    SignalHandle_Sigsegv<13> enter!
    sig:11, error addr:0x1234
    ErrFunc<40> enter!
    

    至此,即可实现段异常后不复位,当然,还是应该完善后处理函数来寻找及修复段异常原因,此文不表。

    展开全文
  • 连接异常复位问题

    2014-08-20 10:06:50
    2、从服务器的抓包看到的信息是,服务器在收到客户端的登陆指令之后应答了客户端的登陆请求命令后就收到连接复位指令。 导致客户端怎么也没有办法进行正常的业务指令通信。 一般发生这种问题的客户端场景,...
  • mcu复位导致I2C异常

    2020-05-22 15:59:47
    正常mcu上电后检测RTC,之后每秒读一次时间,在做实验的时候使mcu的电压刚好在临界区间,致使mcu在一直重启,偶发导致I2C异常。 原因分析: mcu在进行I2C通信的时候,mcu复位导致I2C从设备进入死锁。从而导致复位mcu...

    I2C总线电平:SCL为高,SDA一直为低。
    软件层一直返回BUS_BUSY。

    什么情况下发生?
    正常mcu上电后检测RTC,之后每秒读一次时间,在做实验的时候使mcu的电压刚好在临界区间,致使mcu在一直重启,偶发导致I2C异常。

    原因分析:
    mcu在进行I2C通信的时候,mcu复位导致I2C从设备进入死锁。从而导致复位mcu也不能恢复正常。

    解决方法:
    1、进行通信的时候检测电压值,快到临界值的时候禁止I2C通讯。
    2、复位从设备。
    3、在mcu上电的时候,SCL发送16个周期时钟脉冲,这样I2C从设备就可以完成被挂起的读操作,从死锁状态中恢复过来。
    如果mcu驱动是内部实现,可以在初始化gpio的时候把SCL pin脚初始化成输出脚,然后软件控制输出高低电平,发送16个周期后再去初始化I2C。
    4、在I2C总线串联一个I2C缓冲器,检测到死锁情况自动恢复异常。

    展开全文
  • 下面通过对微处理器监控芯片MAX818在使用中出现异常复位的实例分析,说明由于电源完整性引起的系统工作不稳定现象。  1 系统描述  图1为μP监控电路。监控芯片MAX818具有电源低压监视、电池管理、RAM片选锁定及...
  • 关注+星标公众号,不错过精彩内容每一块处理器都有复位的功能,不同处理器复位的类型可能有差异,引起复位的原因也可能有多种。STM32的复位功能非常强大,可通过软件、硬件和一些事件触发系统复位...
  • 将重磁异常相位谱主值换算到0~2π范围,依据相邻两点相位谱主值之差决定相位谱真值的校正项,达到相位谱复位
  • 一次,某产品的运行现场出现随机异常复位,问题比较棘手,大家一筹莫展。我脑袋中灵光一闪,为何不增加异常dump信息来协助分析问题呢? 我快速行动起来,发现我们的嵌入式设备异常复位有如下原因: 其中包含了看门...
  • W5500和W5100S都可以通过设置寄存器来复位PHY部分,而不是整体复位芯片。其中W5500是设置PHYCFGR(PHY配置寄存器)的RST位为“0”来复位PHY部分,注意复位后需要重新置为“1”。 而W5100S是通过PHYCR1(PHY Control ...
  • (2)在应用层添加8路VI通道检测,异常再对NVP芯片进行复位 测试后,可满足要求 实现如下: HI_S32 bAllChnNormal = 0; //所有通道是否正常 HI_S32 allChnNormalCnt = 0; //所有通道正常次数 ...
  • STM32 独立看门狗异常复位

    千次阅读 2020-04-01 16:45:31
    程序中使用了定时器来执行... } 发现总是在按键的时候,看门狗异常复位。原因:按键中断函数中有延时操作且时间超过了1s,导致看门狗溢出复位。 解决: 将看门狗溢出定时延长。 IWDG_Config(IWDG_Prescaler_64 ,6250);
  • STM32引起电源和系统异常复位的原因

    千次阅读 2020-03-18 22:30:09
    关注、星标公众号,不错过精彩内容来源:STM32每一块处理器都有复位的功能,不同处理器复位的类型可能有差异,引起复位的原因也可能有多种。今天是第3篇分享...
  • 我的开发环境是 vxworks 6.8, 芯片at91sam9x25, 在bsp里面加了一个vxbus的dma驱动,程序通过vxbIntConnect链接中断后,程序运行到某个位置就复位了,每次重现,不知道该怎么定位这个问题,程序崩溃在其它模块,...
  • 前言本篇主要是介绍一种处理问题的思路,即当我们在做STM32应用开发过程中,遇到芯片异常复位,或者进入了异常处理时,如何通过集成开发环境,如IAR,KEIL等查看相应的ARM内核寄存器,定位出应用软件产生异常的地方...
  • ARM异常中断

    2014-04-02 22:13:23
    一、ARM中异常中断的类型: 异常中断名称 ...当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行。复位异常中断通常用在下面几种情况: 1、系统加电时 2、系统复
  • 54.ARM 异常处理

    2020-05-28 23:14:07
    一.什么异常? 异常我们可以笼统的理解为中断,它的范围更宽泛一点,复位啊,外部中断啊,都属于异常。都是向cpu请求打断正常的程序流程,进入特定程序的一种机制。... 复位电平有效时,产生复位异常,..
  • VCAP电容也能影响复位
  • 复位电路

    千次阅读 2019-02-22 18:02:00
    复位电路  时钟电路我第一篇博客已经说讲过了,今天我们来聊聊复位电路。当然,复位电路博大精深,并不是三言两语就能说清楚的,因此这里也是聊聊复位电路的基础,更深的研究需要在实际的项目中才能深有体会。...
  • ARM的异常处理

    千次阅读 2018-07-17 21:44:50
    1、 复位异常 2、 未定义指令异常 3、 软件中断异常 4、 预取指令异常 5、 数据异常 6、 IRQ(中断) 7、 FIQ(快速中断) 异常,单片机为中断,笼统来讲可以把异常类似的看作中断,本质上两者还是有区别的。...
  • 网上找到一份ILI2511TP 驱动移植到对应的平台上去,打开DMA实现传输。 去掉ilitek_resume 当中的ilitek_reset(ilitek_data->reset_time); 不能拉高复位 bug解决
  • ARM 异常介绍

    千次阅读 2018-03-18 22:49:05
    一、中断概念:CPU 在执行当前程序的过程中因硬件或...然后再返回来执行原来的程序二、ARM 体系异常分类:复位异常(Reset)数据异常(Data Abort)快速中断异常(FIQ)外部中断异常(IRQ)预取异常(Prefetch Abor...
  • 异常处理

    2013-01-19 23:52:33
    参考链接:... ... ARM支持7种类型的异常,它们是: 复位异常 未定义指令异常 软中断指令异常 预取指令异常 数据中止访问异常 中断异常 快速中断异常   AR

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,378
精华内容 10,151
关键字:

复位异常