2017-05-16 26 views
-1

Windows 7でKeil uVison 4を使用するstm32f105のcプロジェクトで非常に奇妙な動作が見られます。私はデバッガでそれをチェックし、数時間後にエラーを追跡した後に、他のプロジェクトの関数ですでにテストされているエラーから、エラーをローカライズしました。そのように見えたのは:STM32f105 BLT命令はローカル変数を再配置します

uint8_t can_add_filter_mask(can_t* this, uint32_t id, uint32_t id_mask, can_frm_type_t type, can_frm_type_t type_mask) 
{ 
    CAN_FilterInitTypeDef filt; 

    /* Empty filter available? */ 
    if(this->filter_len >= 14) 
    { 
     return FALSE; 
    } 

    /* Select filter number */ 
    if(this->canx == CAN1) 
     filt.CAN_FilterNumber = this->filter_len + 0; 
    else 
     filt.CAN_FilterNumber = this->filter_len + 14; 
    this->filter_len++; 

    ... 
    //filt is read 
    CAN_FilterInit(&filt); 
} 

構造体filtは、いずれのアサイメントの後でも変更されていないようになっていました。その後、私はdissassemblyを変更し、それは次のようだ(私はそれがだとごめんなさいビット長):

108: uint8_t can_add_filter_mask(can_t* this, uint32_t id, uint32_t id_mask, can_frm_type_t type, can_frm_type_t type_mask) 
0x08001B22 BD70  POP  {r4-r6,pc} 
    109: { 
    110: CAN_FilterInitTypeDef filt; 
    111: 
    112:   /* Empty filter available? */ 
0x08001B24 E92D41FF PUSH  {r0-r8,lr} 
0x08001B28 4604  MOV  r4,r0 
0x08001B2A 460D  MOV  r5,r1 
0x08001B2C 4690  MOV  r8,r2 
0x08001B2E 461E  MOV  r6,r3 
0x08001B30 9F0A  LDR  r7,[sp,#0x28] 
    113:   if(this->filter_len >= 14) 
    114:   { 
0x08001B32 7C20  LDRB  r0,[r4,#0x10] 
0x08001B34 280E  CMP  r0,#0x0E 
0x08001B36 DB03  BLT  0x08001B40 
    115:     return FALSE; 
0x08001B38 2000  MOVS  r0,#0x00 
    151: } 
    152: 
    153: /******************************************************************************/ 
    154: void can_clr_filter(can_t* this) 
0x08001B3A B004  ADD  sp,sp,#0x10 
0x08001B3C E8BD81F0 POP  {r4-r8,pc} 
    119:   if(this->canx == CAN1) 
0x08001B40 4970  LDR  r1,[pc,#448] ; @0x08001D04 
0x08001B42 6820  LDR  r0,[r4,#0x00] 
0x08001B44 4288  CMP  r0,r1 
0x08001B46 D103  BNE  0x08001B50 
    120:     filt.CAN_FilterNumber = this->filter_len + 0; 
    121:   else 
0x08001B48 7C20  LDRB  r0,[r4,#0x10] 
0x08001B4A F88D000A STRB  r0,[sp,#0x0A] 
0x08001B4E E004  B  0x08001B5A 
    122:     filt.CAN_FilterNumber = this->filter_len + 14; 
0x08001B50 7C20  LDRB  r0,[r4,#0x10] 
0x08001B52 300E  ADDS  r0,r0,#0x0E 
0x08001B54 B2C0  UXTB  r0,r0 
0x08001B56 F88D000A STRB  r0,[sp,#0x0A] 
    123:   this->filter_len++; 
    124: 
    125:   /* Select mask mode */ 
0x08001B5A 7C20  LDRB  r0,[r4,#0x10] 
0x08001B5C 1C40  ADDS  r0,r0,#1 
0x08001B5E 7420  STRB  r0,[r4,#0x10] 

私は組み立ての専門家で、どちらもARMの専門家ではないんだけど、私はアセンブリ上のビットをプログラミングされています私には悪くはない。私が気付いたのは少し間違っていたことが間には別の関数can_clr_filterの一部であったため、コンパイラがいくつかのコードを再利用していたように見えましたが、最適化はすべてオフになっていました。興味深い部分は、私がfilt.CAN_FilterNumber変数のアドレスをチェックすると、それは0x20002252に対処するためのアドレス0x20002262からライン

0x08001B36 DB03  BLT  0x08001B40 

後に変更されたことでした。だから、すべての変更はメモリ内の他の場所に適用されました!!変数が静的であると宣言した後、問題は消えてしまいました。実際に何が起こったのかは私には分かりません...命令BLTによってローカル変数が別のアドレスに再配置されることはどうですか?または、& filt.CAN_FilterNumberを見て、uVisionデバッガが誤った参照値を表示する可能性がありますか?

+0

「this」が「NULL」ではないことを確認してから、有効なアドレスを指していますか?スタックオーバーフローの危険性はありますか?つまり、現在のタスクのスタック内にどこに場所があり、余裕があるのですか? 'BLT'自体はスタックを使うべきではありませんが、もしあなたがすでに奇妙なことが起こっているかもしれません。 – unwind

+0

@unwind、しました。 'this-> canx'はグローバル変数CAN2と同じアドレスを持っているため、 'this'はすでに完全に初期化されていたため、 'this'は 'NULL'ではありません。スタックは1KB大きいです。それはもちろん問題かもしれません。それを見つける方法? –

+0

@judoka_aclは、スタックオーバーフローを排除するために、いくつかの '0xdeadf00d'ワードのように、割り当てられたスタックメモリの一番下にカナリアの値を置き、次にカナリアが生きているかどうかをチェックします。初期値)。スタックが割り当てられた領域から大きくなると、カナリアの値も上書きされます(原点を見つけることは困難です)。コンパイラの中には、デバッグビルドのための類似の/より良いテクニックを提供し、あらゆる関数呼び出しのまわりでスタックの有効性をチェックするものもありますが、簡単なマニュアルカナリアはプロダクションビルドであっても十分に高速です。 – Ped7g

答えて

0

あなたは何のポストにこのフラグメントから全機能しなかったので、私は推測することができます。

  1. あり、ローカル変数への割り当てのみであるが、それはあなたのプログラムの任意の場所で使用されていない、それはおそらくから削除されます生成されたコード
  2. コンパイラでエラーを検索しないでください。彼らはかなり良いですが、私は何も見つけていません(私は非常にアクティブなコーダーです)。誰かが「これは逆アセンブルリストであり、コンパイラが間違っている」と言ったとき、間違いは質問者のどこかで行われます。あなたのプログラムをデバッグするときは、分解については忘れてください。あなたは時間を無駄にするだけです。
+0

必ずfiltを読んで、私の質問を更新します。あなたのヒントありがとうございます。私はコンパイラのエラーを探していません、私はコンパイラが間違っていると言っています。私は、エラーをローカライズして、奇妙な動作について質問しています。 –

+0

@judoka_aclは完全な関数呼び出しをポストします。特定の状況で機能が機能しても、別の機能では機能するとは限りません。バグは、しばしばもっと複雑になっています。 –

+0

エラーは私が投稿したコードに正確にローカライズされています。あなたが主張するなら、私はそれをあなたに個人的に分かち合うことができますが、私はその問題が残りの機能にないことを1000%確信しています。私は今、デバッガが間違ったアドレスを示しているという考えを考えています。問題はコード内に全くありません。 –

関連する問題