RL78コード・フラッシュの二面化について

お世話になっております。

現在、RL78のコード・フラッシュ・メモリのプログラム領域を2面化し、ファームアップデートする際に使用していない/古い方のプログラムを書き換え、書き換え処理に失敗しても古い方のプログラムで動作できるようにしたいと考えております。

今回使用するマイコンはR5F100GJ、ブートスワップ機能を使用し、256Kバイトのフラッシュメモリを、00000H~01FFFHまでをブート・クラスタ0、1、02000H~20FFFHまでをA面として利用、21000H~3FFFFHまでをB面として利用するイメージです。

プログラムのコンパイル時に、A面を「フラッシュ領域の戦闘アドレス=2000H/フラッシュ領域分岐テーブルの戦闘アドレス=2000H」、B面を「フラッシュ領域の戦闘アドレス=21000H/フラッシュ領域分岐テーブルの戦闘アドレス=21000H」で作成、書き込む際はブート・クラスタ1領域+書き込みたい面をイレース・ライトすることで実現できるのではと考えていたのですが、B面のコンパイル時に「(E) E3206 RA78K0R error E3206: Segment '@EVECT00' can't allocate to memory - ignored RaccessDTRS2R.mtsp」等のエラーが発生し、drファイルを見直したりしている所です。

そもそも上記のような使用法は可能でしょうか?何か関連のある資料等を教えていただければ大変ありがたいです。

普段あまりdrファイルをさわる機会も少なく、経験不足を感じています。

Top Replies

  • LIBEさん、こんにちは。NoMaYと申します。

    以下の画面コピーのレイアウトにしたいということですよね?出来ますよ。なお、エラーに関してはDRファイルを見せて頂かないと何とも言えないかな、という印象です。ちなみに、@EVECT00はCA78K0R\V1.72\Src\cc78k0r\src\cstarte.asmで定義されているセグメントのことかと思います。

    [追記] 思うに、されようとしている内容ではフラッシュ領域分岐テーブルは不要かも知れません。ブートクラスタ片側領域(アドレス0番地側の半分)とプログラム領域は一体でビルドされて、かつ、一体でアップデートされる、からです。(別のやり方の、ブート領域とフラッシュ領域を分割するやり方では、ブート領域とフラッシュ領域は別々にビルドされますので、ブート領域側からフラッシュ領域側への遷移/呼び出しは、フラッシュ領域側の分岐テーブルを介する必要があったのですけれども、それに対し、こちらのやり方では一体でビルドされるからです。) [ここまで追記]

    ちなみに、注意点なのですが、A面とB面とではプログラム実行時のメモリレイアウトが同じではありませんので、もしも、ファームウェアをアップデートした装置と、諸般の事情でアップデートを1回スキップした装置が、世の中に混在するようになりますと、以降は、プログラムの処理内容としては同じであるけれども、A面書き込み用のものとB面書き込み用のものとで2種類のファームウェアをリリースしていくことになる可能性が無くは無いかも、と思うのです。

    また、その場合に、どの装置が今どちらなのか(A面実行プログラムなのかB面実行プログラムなのか)間違えないようにポカヨケ対策などして、うっかりA面実行プログラムの装置にA面実行プログラムをB面に書き込んでしまうことが無いようにしておくのが良いかな、とも思ったのでした。(書き換え時に転送される書き込みデータがHEXフォーマットとかであればアドレス付きなので素朴にエラーチェック出来るでしょうけれども、バイナリデータとかですと、うっかり事例、が出てきそうな気がしなくも無いかな、と思ったのでした。)

    以下、ハードウェアマニュアルの画面コピーと私の書き込みです。

    A面実行時 = B面書き換え時 ⇒ ただしB面のプログラム自体は2番目の画面コピーの「B面実行時」のレイアウトでビルドします


    B面実行時 = A面書き換え時 ⇒ ただしA面のプログラム自体は1番目の画面コピーの「A面実行時」のレイアウトでビルドします


    ハードウェアマニュアルのブートスワップの説明箇所
    (注: ただし、この考え方は、新しいブートプログラムの書き込みに成功してさえいれば、プログラム本体の書き換えに失敗したとしても、新しいブートプログラムでプログラム本体の書き換えを再度試行すれば良い、という考え方ですので、されようとしていることとは少し事情が違っていますけれども。) (補: ブートプログラムがブートクラスタ片側に収まる案件での説明ですね。)

     

  • NoMaY様、ご回答ありがとうございます!

    思っていた形でのレイアウトが可能ということで、安心できました。ありがとうございます。

    情報が出せていなかったのですが、提示していただいたブートスワップの「新しいブートプログラムの書き込みに成功してさえいれば、プログラム本体の書き換えに失敗したとしても、新しいブートプログラムでプログラム本体の書き換えを再度試行すれば良い、という考え方」で作成されたプログラムを、「失敗時も以前のファームで最低限動けるようにしたい」という趣旨で開発を行っている経緯がございます。

    そのため、現状プロジェクトの中にBoot部(条件によりファームアップデートモードとなり、シリアル通信でファームデータを受け取り、アプリ・ブートクラスタ1を書き換える)のプロジェクトとアプリ部のプロジェクトがあり、NoMaY様の仰られているような「別のやり方」になってしまっているのかな?と考えております。

    boot 側のビルドツールの「プロパティ」→「コンパイル・オプション」→「メモリ・モデル」→「フラッシュ領域の先頭アドレス」/「フラッシュ領域分岐テーブルの戦闘アドレス」をA面でのビルド時に2000H、B面を21000Hに設定しています。

    また、drファイルは以下のようになっています。

    boot側drファイル

    main 側drファイル

    ここで、B面に割り付けようとROMを21000からにしてみたのですが、Boot側と合わないのでエラーになっているのではないかと思うのですが、どう解決したものかと悩んでいます。

    質問のポストで書き忘れていたのですが、開発環境は CS+ for CA, CX V4.07.00 / ビルド・ツール CA78K0R を利用しております。

  • LIBEさん、こんにちは。NoMaYです。

    画面コピーありがとうございました。DRファイルを見ていて、Segment '@EVECT00' に関係するような定義は何も無いなぁ、と思ったのでCA78K0Rのヘルプを検索してみたら、以下のことが分かりました。エラーの原因は、これかなぁ、と思ったのでした。

    (1) ブート領域・フラッシュ領域と分割する場合のフラッシュ領域向けスタートアップルーチン(バイナリ)は分岐テーブルの場所が2000Hである
    (2) 分岐テーブルの場所を変更する場合はヘルプの指示にしたがってスタートアップルーチンをアセンブルする必要がある

    また、そのことで1つ気付いたのですが、現状のブート領域・フラッシュ領域の分割構成を踏襲するのであれば、以下のセクション設定も必要だと思われます。

    (3) B面のフラッシュ領域側プログラムに、ミラー領域、が幾らかは含まれるように配置を構成しないとB面のフラッシュ領域側プログラムでconst等が使えなくなる

    他方で、私の前の投稿のフラッシュ領域分岐テーブルの件と関連しますけれども、まず、そもそも、ブート領域・フラッシュ領域と分割する必要が無いのでは?ということも思いました。(2面化という点だけであればですが。)

    以下、CA78K0Rのヘルプの画面コピーです。




     

  • NoMaY様、調べていただき、ありがとうございます!

    ひとまず既存の構成を踏襲しようと repvec.bat を使った分岐テーブルのリプレイスを試してみたのですが、ra78k0rがインストールされていないようなエラーが出てきており、Pathをどこに通せばいいのか調べて居るような段階です。

    [追記]→このあたりの説明をしている資料がありましたので、挑戦してみます

    そこで、ひとまずBoot/アプリにプロジェクトを分割しない場合で進めようと思います。

    すごく初歩的な質問になってしまうのですが、この時、同じプロジェクト内でブート部のソースとアプリ部のソースを管理する形になるのでしょうか?フラシュ・セルフ・プログラミング実行編でのサンプルが分けられていたので、そういうものなのかなと漠然と思っていました。

  • LIBEさん、こんにちは。NoMaYです。

    > この時、同じプロジェクト内でブート部のソースとアプリ部のソースを管理する形になるのでしょうか?

    そうです。というか、このやり方の場合、(2面化という点だけであれば)ブート部とかアプリ部とかの考え方自体不要なのです。ブート部とアプリ部をまるっと一体にして、以下の点に注意すること以外は、普通にプログラムを作れば良いです。

    ● A面もB面も、0~0FFFHを含むようにし、1000H~1FFFHを含まないように、セグメントを配置する
    ● 2000H以降は、A面とB面で、同じアドレスを使わないようにセグメントを配置する
    ● もしconstなどミラー領域を使用する分が0~0FFFHに収まらなかったら、A面とB面で、同じアドレスを使わないようミラー領域のセグメントを配置する

  • かなり時間が経ってしまいましたが、思っていた処理ができるようになりました!ありがとうございます