2

Linux環境(Ubuntu、msp430-gcc 4.6.3)でTI Launchpad(msp430g2211)を使用しています。

奇妙な問題があります。固定量を超えるメモリを割り当てようとすると、マイクロコントローラが起動時に停止します。

より正確に言うと、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,

        };

(完全を期すために:

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


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

)。

すべてが機能しますが、25ではなく30(または25を超える任意の数)の要素を使用しようとすると、uCは機能しなくなったように見えます。(コンパイルおよびプログラミング中にエラーは発生しません)

TI Wikiで私はこれを見つけました。これは、私が経験していることを満たしているようです。

Cスタートアップコード中にWDTが起動する

アプリケーションがC言語で記述されている場合のもう1つの最も一般的な問題は、起動時のウォッチドッグタイムアウトです。すべてのMSP430のデフォルトのウォッチドッグタイマーは、起動後にアクティブに設定されます。したがって、アプリケーションコードの開始時に必要がない場合は、WDTをオフにする必要があります。アプリケーションコードが起動時に初期化する必要のある大きな変数 を使用している場合、これにより、起動中にウォッチドッグタイマーがすでに起動し、コードが実行されない可能性があります。

この問題の解決策は、C変数の初期化の前でも呼び出されるコンパイラの低レベルC初期化関数を使用することです。CCSコンパイラでは「int_system_pre_init(void)」と呼ばれ、IARでは関数はint __low_level_init(void)と呼ばれます。戻り値は、C / C ++グローバルデータ初期化を実行するかどうかを決定するために使用されます(C / C ++自動初期化をバイパスするための戻り値0)。この問題の詳細については、MSP430ソフトウェアコーディングテクニックアプリケーションレポートの3.6章「低レベル初期化機能の使用」を参照してください。

そこで、次の関数を追加しようとしました(メモリを割り当てる前にWDTを停止するため)。

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

しかし、問題はまだそこにあります...

私が行ったその他のテスト:-コンパイラのバージョンを変更しました-配列を15個の要素のうちの2つ以上に分割しました-メイン関数または「.init3」、「。init1」、「。init7」でWDTを停止します

何か案が ?ありがとうございました。

編集:提案されたように、私は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コマンドは次のようにも言っています:

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

私はASMの専門家ではありませんが、WDTの説明は適切な場所にあるようです。どこが問題なのかわからない…ありがとうございます。

4

1 に答える 1

0

コンパイラのバグのように聞こえますが、その場合、GCCが生成するasmを見ると、何が問題になっているのかが明らかな場合があります。

あなたがそれを投稿した後、私はasmを調べました、そしてあなたが扱うべきSRAMが128バイトしかないことに気づきました。私はこのuCのアセンブラーに精通していませんが、それを超えているように思えます。カラー配列の割り当てだけでなく、スタックと組み合わせて?

于 2013-01-10T00:02:57.190 に答える