This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430系统死机问题

Other Parts Discussed in Thread: MSP430F5359

我用的MCU是MSP430F5359,UCOS ii操作系统,最近老出现系统死机问题,调试时发现每次死机时都是PC指针都是在地址4,MSP430中地址4是无效的CODE地址,检查C代码也看不出什么问题,求教!发现出现这个问题时有一定的规律:系统循环多次(一般是两百以上)地执行某一段代码时容易出现这一问题,把循环次数减少这个问题看似可以解决。

  • 我的编译器是IAR6.3

  • 估计是堆栈溢出导致程序跑飞了。可以尝试增加堆栈大小看看。

  • 增加堆栈前面有试过,没用,也实际统计过,堆栈是够的,我实际设置的堆栈都是在实际使用堆栈的两倍左右,很安全的。而且堆栈溢出的话都是重启,现在是每次死机都是跑飞在地址4的位置。

  • 这个问题可能原因是某些函数内定义了较大的局部数组,比如 "char a[100]",会定义在堆栈区。因此,任务调用此类函数时,可能侵占任务堆栈,导致任务堆栈的任务程序入口地址被修改到非代码区,这样在操作系统切换任务的时候异常,导致系统复位。如下图所示,Send()函数中定义了一个char data[100] = {0},编译运行时可以查看对应的汇编程序(View->Disassembly)。在Send()函数对应的汇编程序中可以看到data[100]数组被定义在堆栈区,语句"suba #0x64, SP".

  • 如果您认为此问题已被解答,请在“这是否解答您的问题” 后,点击“”按钮。 感谢您对TI的大力支持!

  • 每次死机都是停在这里,死机的时候查看堆栈没有溢出现象。有以下疑问:这段地址不是代码区,这段代码是怎么产生的?怎么会进入这段代码?且进入这段非法代码地址为什么系统不重启呢?

  • 按照上述DATASHEET描述000-FFF这段地址是外围设备。

  • 1.死机应该不是因为堆栈溢出,是相应任务划分的堆栈被局部数组侵占,其任务入口地址被异常更改。

    2.如果任务程序的入口地址被异常修改为0x000004, 就会跳转到此外设寄存器段,并且将寄存器数据看作程序指令。看所提供图中的指令“jmp 0x4”,意思是跳转到0x000004处,则会导致循环。

    3.建议找出局部数组,更改为静态数组"char data[100]"->"static char data[100]", 看是否还有相同现象。

    4. 推荐了解uc/os的任务切换底层机制获取更详细信息,推荐书籍:

  • 根据您的提示我检查了一下我的程序,但没发现大的局部数组变量,稍些大一点的我都是定义为全局变量了;

    不过我刚试着改了一下程序好像问题得以解决,但我无法解释其原因,麻烦帮分析一下。

    这是一段通过串口往外发送数据的程序,问题是只要发送的数据量一大,仪器就会死机在地址4,发送的数据小的时候没问题:

    对这段程序我等待发送串口缓冲寄存器空闲时加一UCOS延时函数,就不会死机了,想不清楚是为什么?

    麻烦帮忙分析一下原因!

  • 1. 建议注释vsprintf()函数语句,直接串口不加延时发送tmpBuf1内容,看是否还有死机状况,以定位问题。

    2. 看了你的代码,你遇到的问题跟我之前遇到的一样,也是我在前面答案里解释的情形,在串口打印代码里定义了局部数组。建议看一下你调用的stdio.c系统库函数vsprintf(),看它里面是否定义了局部数组。你可以在文件夹里搜索出stdio.c,查看一下源代码。

    3. 如果通过上面确定问题出在vsprintf()函数,建议对其进行移植,做成本地函数,不直接调用系统函数。

  • 非常感谢!应该是vsprintf()库函数搞的鬼,我查看了库函数的源码比较复杂,没有进行移植,换了一种方式:在调用这个库函数之前关中断,不让进行任务调度,也就不会有堆栈溢出问题了。再次感谢!

  • 如果您认为此问题已被解答,请在“这是否解答您的问题” 后,点击“”按钮。 感谢您对TI的大力支持!

  • 你试试,不修改代码,把优化等级设置为high,看能不能解决你的问题。