1

関数をフラッシュから RAM にコピーして実行したいと考えています。

IAR には、RAM で関数を定義できる関数用の __ramfunc タイプが含まれていることは知っていますが、次の 2 つの理由から使用したくありません。

  • RAM関数は、初期化時にのみ使用するRAMメモリを使用しています
  • コードを 2 回アップグレードした後 (私はファームウェア更新システムを実行しています)、__ramfunc が間違った場所を示しています。

基本的に私が欲しいのは、関数をフラッシュとして宣言し、実行時にそれをメモリにコピーして実行することです。私は次のコードを持っています:

   void (*ptr)(int size);
   ptr=(void (*)(int size))&CurrentFont;
   memset((char *) ptr,0xFF,4096);
   Debugprintf("FLASH FUNC %X",GrabarFirmware);
   Debugprintf("RAM FUNC %X",ptr);
   char *ptr1=(char *)ptr,*ptr2=(char *)GrabarFirmware;
   //Be sure that alignment is right 
   unsigned int p=(int )ptr2;
   p&=0xFFFFFFFE;
   ptr2=(char *)p;
   for(int i=0;i<4096;i++,ptr1++,ptr2++)
      *ptr1=*ptr2;

   FLASH_Unlock();
   // Clear pending flags (if any)
   FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |      FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
   ptr(*((unsigned int *)(tempptrb+8)));

詳細として:

  • 関数の sizeof が機能しない
  • リンカーが間違った関数アドレス (奇数アドレス) を返しました。デバッグ ツールで確認すると、それが間違っていることに気付きました。これが &0xFFFFFFFE を実行する理由です。

このコードの後、関数はRAMに完全にコピーされますが、まったく同じコードですが、これで実行すると:

   ptr(*((unsigned int *)(tempptrb+8)));

例外 HardFault_Handler が発生します。多くのテストの後、このハードフォールト例外を修正できませんでした。

asm コードを確認すると、__ramfunc と通常のフラッシュ関数の呼び出しが異なり、おそらく HardFault 例外が発生する理由であることに気付きました。

これは、flash として定義されている場合に呼び出される方法です。

   4782             ptr(*((unsigned int *)(tempptrb+8)));
   \   000000C6   0x6820             LDR      R0,[R4, #+0]
   \   000000C8   0x6880             LDR      R0,[R0, #+8]
   \   000000CA   0x47A8             BLX      R5
   4783             //(*ptr)();

直接呼び出すと、コードを __ramfunc として定義し、直接呼び出します。

   4786             GrabarFirmware(*((unsigned int *)(tempptrb+8)));
   \   0000007A   0x6820             LDR      R0,[R4, #+0]
   \   0000007C   0x6880             LDR      R0,[R0, #+8]
   \   0000007E   0x.... 0x....      BL       GrabarFirmware

例外の理由は、おそらくフラッシュから RAM にジャンプしているためであり、おそらくそれは皮質保護ですが、__ramfunc 修飾子を使用している場合もまったく同じであり、段階的にデバッグすると、関数にジャンプしません。 RAM、関数を呼び出すとすぐに例外に直接ジャンプします。

これをスキップする方法は、RAM メモリへの「goto」です。asm("...") 関数を使用して C と ASM in C を混在させようとしましたが、エラーが発生し、おそらくハードフォールト例外が発生します。

どんなヒントでも大歓迎です。

4

1 に答える 1