2

In Application Programming モジュールの開発方法についてのアイデアを探しています。

Androidシステム用のSTM32F2xx接続ボックスを「C」で開発しました。本質的に、これは単なるマルチデバイスから Bluetooth への情報ブリッジです。現在、物理的な接続を必要とせずに、Bluetoothシリアルポートから将来このボックスをアップグレードするための「アプリケーションプログラミング」モジュールを提供する方法を考えています。

私にとって、フラッシュへの読み取りまたは書き込みは問題ではありませんが、プロセッサがプログラムを実行する方法、プログラムを異なるフラッシュの場所に分割する方法、およびフラッシュ メモリの具体的なアドレスにジャンプする方法を理解する必要があります。この情報はどこで検索できますか?

4

1 に答える 1

4

コメントしようと思ったのですが、初心者なのでできません。だから私は答えてみます、優しくしてください。

私が IAP に使用する方法は次のとおりです。

  • 新しいファームウェアを安全な場所 ​​(eeprom、ext flash など) にロードします。
  • たとえば、そのハッシュに対してファームウェアの整合性を確認します
  • 内部 CPU フラッシュをフラッシュ プログラミングするためのルーチンを SRAM にコピーします。
  • すべての割り込みを無効にする
  • FLASH プログラミング ルーチンを呼び出します。
  • ソフトウェア リセット要求をトリガーして、新しいファームウェアを起動します。

CPUのファームウェア全体をアップグレードすると、上記の方法が機能するようになりました。また、フラッシュ プログラミング中に割り込みが必要ないと仮定します。フラッシュプログラミング中に割り込みが必要な場合は、もう少し複雑です。すべての割り込み関連コードを SRAM にもコピーするために、フラッシュ プログラミング ルーチンを呼び出す前に、いくつかの追加の手順を実行する必要があります。

  • 新しいファームウェアを安全な場所 ​​(eeprom、ext flash など) にロードします。
  • たとえば、そのハッシュに対してファームウェアの整合性を確認します
  • 内部 CPU フラッシュをフラッシュ プログラミングするためのルーチンを SRAM にコピーします。
  • すべての割り込みを無効にする
  • ベクトルを収めるのに十分な RAM を割り当てます。
  • ベクターをそのアドレスにコピーする
  • フラッシュ プログラミング中に必要な割り込みを有効にします。
  • FLASH プログラミング ルーチンを呼び出します。
  • ソフトウェア リセット要求をトリガーして、新しいファームウェアを起動します。

1つの重要なこと

この方法には非常にトリッキーな部分があります。これは、SRAM にあるコード間の呼び出しです。コンパイラは、関数の名前を 0x0800000 メモリ ロケーション (フラッシュ) のアドレスに関連付けます。たとえば、関数void flash_byte(uint32_t address, uint8_t byte);はフラッシュのどこかに存在します。この関数を ram にコピーするときは、0x20001000 と言って、関数呼び出しを具体的にする必要があります。フラッシュ全体を消去して再書き込みしようとすると、フラッシュから関数を呼び出せないことを忘れないでください。私が使用する方法は、関数ポインターを介した呼び出しです。例:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

/*
 * Function pointers
 */
typedef void (*flash_write_ft) (void);
typedef void (*flash_sub_call_ft) (uint32_t lala);

flash_write_ft      flash_write_pointer = (flash_write_ft)0;
flash_sub_call_ft   flash_sub_call_pointer = (flash_sub_call_ft)0;

/*
 *  Helper functions
 */
size_t get_function_size (uint32_t *address) {
    size_t s=0;
    // ...
    // s = calculate size;
    return s;
}

int copy_function (uint32_t *from, uint32_t *to, size_t s) {
    // ...
    return 0;   // OK!!
}

/*
 * Flash programming functions
 */
void flash_sub_call (uint32_t lala) {
    // lala tata
}

void flash_write (void) {
    uint32_t foo;
    // ...
    flash_sub_call_pointer (foo);   // call via pointer here
    // ...
}

int main(void) {
    size_t s;
    uint32_t *add;

    // Get firmware, check integrity etc...

    // copy to ram
    s = get_function_size ((uint32_t*)&flash_sub_call);
    add = (uint32_t*)malloc (s);
    copy_function ((uint32_t*)&flash_sub_call, add, s);
    flash_sub_call_pointer = (flash_sub_call_ft)add;

    s = get_function_size ((uint32_t*)&flash_write);
    add = (uint32_t*)malloc (s);
    copy_function ((uint32_t*)&flash_write, add, s);
    flash_write_pointer = (flash_sub_call_ft)add;

    // IAP
    flash_write_pointer ();

    return EXIT_SUCCESS;
}

この例では、すべての関数呼び出しは RAM を指すポインターを介して行われるため、それらを RAM にコピーすると機能します。

追加情報:

1)フラッシュプログラミングマニュアル 2) Cortex-m3 プログラミングマニュアル

于 2015-04-19T09:24:22.633 に答える