简体   繁体   English

如果我使用超过25个元素的数组,则msp430g2211(launchpad)在启动时停滞

[英]msp430g2211 (launchpad) stalls at startup if I use an array of more than 25 elements

I'm working with TI Launchpad (msp430g2211) in a Linux environment (Ubuntu, msp430-gcc 4.6.3). 我正在Linux环境(Ubuntu,msp430-gcc 4.6.3)中使用TI Launchpad(msp430g2211)。

I have a strange problem: when I try to allocate more than a fixed quantity of memory the micro-controller stalls at start-up. 我有一个奇怪的问题:当我尝试分配多于固定数量的内存时,微控制器在启动时会停顿。

To be more precise: I have an array of 25 elements in main(), created as follow: 更准确地说:我在main()中有一个由25个元素组成的数组,其创建如下:

color img0[25] = {


            off, cyan, cyan, cyan, off,
            cyan, red, violet, orange, cyan,
            cyan, red, violet, orange, cyan,
            off, cyan, cyan, cyan, off,
            off, off, off, off, off,

        };

(for completeness: (出于完整性考虑:

typedef struct color {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    } color;


static color red = {25, 0, 0}; ...

)

Everything works but If I try to use 30 (or any number greater than 25) elements instead of 25 the uC seems dead. 一切正常,但是如果我尝试使用30个(或大于25的任何数字)而不是25个,则uC似乎已死。 (no errors during compilation and programming) (在编译和编程过程中没有错误)

In TI Wiki I found this, which seems to meet what I'm experiencing: 在TI Wiki中,我发现了这一点,这似乎符合我的经验:

WDT fires during C startup code WDT在C启动代码期间触发

Another most common problem if the application is written in C language is the watchdog timeout during startup. 如果应用程序是用C语言编写的,则另一个最常见的问题是启动过程中的看门狗超时。 Per default watchdog timer on all MSP430 is set to active after startup. 启动后,所有MSP430上的默认看门狗定时器均设置为活动状态。 Therefore it is necessary to turn off the WDT if not needed right at the beggining of the application code. 因此,如果在应用程序代码开始时不需要,则必须关闭WDT。 If the application code is using large variables which are needed to be initialized during startup, this could cause that the watchdog timer already fires during startup and the code will never be run. 如果应用程序代码使用的大型变量需要在启动过程中进行初始化,则可能导致看门狗定时器在启动过程中已经触发,并且该代码将永远无法运行。

The solution for this problem is to use the compiler's low level C initialization function which is called even prior to the initialization of C variables. 解决此问题的方法是使用编译器的低级C初始化函数,该函数甚至在C变量初始化之前就被调用。 In CCS compiler, it is called "int _system_pre_init(void)", while in IAR, the function is called int __low_level_init(void). 在CCS编译器中,它称为“ int _system_pre_init(void)”,而在IAR中,该函数称为int __low_level_init(void)。 The return value is used to determine whether or not C/C++ global data initialization will be performed (return value of 0 to bypass C/C++ auto-initialization). 返回值用于确定是否将执行C / C ++全局数据初始化(返回值为0,以绕过C / C ++自动初始化)。 Refer to the MSP430 Software Coding Techniques Appication Report, chapter 3.6 "Using a Low-Level Initialization Function" for more detailed information regarding this issue. 有关此问题的更多详细信息,请参考《 MSP430软件编码技术应用报告》的第3.6章“使用底层初始化功能”。

So I tried to add the following function (in order to stop the WDT prior to allocating the memory): 因此,我尝试添加以下功能(以便在分配内存之前停止WDT):

__attribute__((naked, section(".init5"))) void __low_level_init()
{
     WDTCTL = WDTPW + WDTHOLD; //Stop WDT
} 

but the problem is still there... 但问题仍然存在...

Other tests I have done: - changed the compiler's version - split the array in two or more of 15 elements - stop the WDT in main function or in ".init3", ".init1", ".init7" 我做过的其他测试:-更改了编译器的版本-将数组分为15个元素中的两个或多个-在主函数或“ .init3”,“。init1”,“。init7”中停止WDT

Any idea ? 任何想法 ? Thank you. 谢谢。

EDIT: As suggested, I analysed the GCC output ASM code (commented with "##" the not working version): 编辑:按照建议,我分析了GCC输出ASM代码(用“ ##”注释不起作用的版本):

    .file   "main.c"
    .arch msp430g2211
    .cpu 430
    .mpy none

    .text
.Ltext0:
    .comm dir,2,2
    .comm colors,2,2
    .section    .init9,"ax",@progbits
    .p2align 1,0
.global main
    .type   main,@function
/***********************
 * Function `main' 
 ***********************/
main:
.LFB0:
    .file 1 "main.c"
    .loc 1 61 0
    mov r1, r4
.LCFI0:
    add #2, r4
.LCFI1:
    add #llo(-100), r1             ## add   #llo(-150), r1
.LCFI2:
    .loc 1 63 0
    mov #23168, &__WDTCTL
    .loc 1 66 0
    mov.b   &__CALBC1_1MHZ, r15
    mov.b   r15, &__BCSCTL1
    .loc 1 67 0
    mov.b   &__CALDCO_1MHZ, r15
    mov.b   r15, &__DCOCTL
    .loc 1 68 0
    mov.b   &__P1DIR, r15
    bis.b   #127, r15
    mov.b   r15, &__P1DIR
    .loc 1 90 0
    mov r4, r15
    add #llo(-102), r15            ## add   #llo(-152), r15
    mov #100, r14                  ## mov   #150, r14
    mov r14, r13
    mov #0, r14
    call    #memset
    mov.b   #llo(-64), -102(r4)        ## mov.b #llo(-64), -152(r4)
    mov.b   #llo(-64), -101(r4)        ## mov.b #llo(-64), -151(r4)
    ...

diff command says also: diff命令也说:

106c106
<   add #llo(-102), r15
---
>   add #llo(-152), r15
187c187
<   cmp #20, r15
---
>   cmp #30, r15
193c193
<   add #llo(-100), r15
---
>   add #llo(-150), r15
541c541
<   .sleb128 -102
---
>   .sleb128 -152
548c548
<   .byte   0x63
---
>   .byte   0x95

I'm not an ASM expert but the WDT instructions seem to be there, in the right place. 我不是ASM专家,但是WDT说明似乎在正确的位置。 I can't understand where is the problem... Thank you. 我不明白问题出在哪里...谢谢。

Sounds like a compiler bug, in which case it might be obvious what is going wrong if you look at the asm GCC generates. 听起来像是编译器错误,在这种情况下,如果您查看GCC生成的asm,可能会发现问题出在哪里。

I had a look at the asm after you posted it, and it occurred to me that you only have 128 bytes of SRAM to work with. 发布后我看了一下asm,发现我只有128字节的SRAM可以使用。 I'm not familiar with the assembler of this uC, but it seems to me that it is exceeded. 我对这个uC的汇编器不熟悉,但是在我看来,它已经超出了。 Not with the allocation of the colour array alone, but in combination with the stack? 不是单独分配颜色阵列,而是与堆栈组合使用?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM