teratail header banner
teratail header banner
質問するログイン新規登録

質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.30%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1953閲覧

ブートローダーらアプリへジャンプするプログラム

Mr.kyousuke

総合スコア13

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2022/12/13 08:19

0

1

RXマイコンを使ってプログラムを書いています。
ブートローダーのプログラムとアプリのプログラムの2つがあります。
ブートローダーのプログラムを起動して動かし、以下のapp_boot関数を動作させて
アプリケーションのプログラムにジャンプしたいのですが、上手くいかず、
ブートローダーのプログラムの中にいます。

アドレス空間↓
RAM
アドレス サイズ 機能
0x08000000 0x100000(1MB) ブートローダ ①
0x08100000 0x700000(7MB) アプリケーション ②

内蔵ROM(コードフラッシュメモリ)
アドレス サイズ 機能
0xFFC00000 0x200000(2MB) アプリケーション ③
0xFFF00000 0x100000(1MB) ブートローダ ④

動作詳細↓
④のアドレスでブートローダーを起動し、ブートローダーを①にコピーして
①にジャンプします。アプリケーションを③に書き込んで、app_boot関数を実行します。
②にジャンプするはずが、何故かできません。
以下でどこが悪いか教授いただけると助かります。

#define APP_VECTOR_START (0x08100000)

//--------------------------------------------------------------------------
// アプリへジャンプ
//--------------------------------------------------------------------------
void app_boot( int argc, char *argv[] )
{

void (*jmp_program)(void) = (void (*)(void))APP_VECTOR_START; // アプリプログラムをRAMへコピー memcpy((void *)0x08100000, (void *)0xFFC00000, 0x200000); //0xFFC00000から2MB分 0x08100000にコピー // 割込み禁止 vdis_psw(); /* Jump to the application */ jmp_program();

}

OS:NORTi
コンパイラ:CCRX
環境:e2studio

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tmp

2022/12/13 14:09 編集

ジャンプができないと、どのように確認したのですか? また、どのような状態になるのですか?
Mr.kyousuke

2022/12/13 14:16

質問ありがとうございます。 e2studioのデバッカ機能で確認しています。 停止をすると、プログラムカウンタで0x08000000代の中を動いています。 0x08100000代のプログラム処理に移行しません。
Mr.kyousuke

2022/12/13 14:28

下記にいろいろ書かれています。↓ https://community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/5560/c (void *)(*(uintptr_t*)APP_VECTOR_START); 上記の意味がよくわかりませんが、変更後の方がいいのかな。。 変更前: void (*jmp_program)(void) = (void (*)(void))APP_VECTOR_START; ↓ 変更後: void (*jmp_program)(void) = (void *)(*(uintptr_t*)APP_VECTOR_START);
thkana

2022/12/13 23:57

app_boot()関数に到達しているのかとか、 APP_VECTOR_STARTの値は適切なのかとか、 RAM領域においてアプリケーションはちゃんと動くのかとか、 ジャンプする以前に確認すべき事柄は確認されているのですか?
Mr.kyousuke

2022/12/14 00:40

app_boot()関数に到達してからターミナルに文字を表示し、 到達していることを確認しています。 割込み禁止にすると、割込みを使っているターミナルの文字表示がされません。 0x08100000から始まるアプリケーションのみのプログラムをデバッカで動作させたとき、動いています。これはスタートアップルーチン、CPUの初期化を含んでいます。 ブートプログラムとアプリケーションを両方動かすとき、 ブートプログラムで、固定ベクタ・テーブル(0xFFFFFF80〜0xFFFFFFFF番地)の定義、CPUの初期化をしています。クロック、RAM、端子などしてから動作させています。 固定ベクタ・テーブルはブートプログラムのものを使うので、アプリケーションプログラムでは、固定ベクタ・テーブルの定義、CPUの初期化はしていません。プログラム・ステータス・ワード、割り込み用スタックポインタ、ユーザースタックポインタを再度、設定して動作させています。
thkana

2022/12/14 10:53

デバッガがあるのなら、app_boot()関数にブレークをかけて一行ずつ(できれば機械語1命令ずつ)追ってみたらなにかわかるのではないですか?
tmp

2022/12/14 14:37

RXマイコンを使ったことはないですが、 APP_VECTOR_STARTという名称から、アプリケーション ②の先頭に、関数?のアドレステーブルがあるのではないですか? void (*jmp_program)(void) = (void *)(*(uintptr_t*)APP_VECTOR_START);という変更で テーブルの最初の1つを取り出して、jmp_programにセットしてうまく動きませんか? 前のままだと、コードではないところにジャンプしてしまっておかしくなっていたのではないですか? 0x08100000にコードではなく、アプリの開始のアドレスはっていませんか?
Mr.kyousuke

2022/12/14 14:52

>void (*jmp_program)(void) = (void *)(*(uintptr_t*)APP_VECTOR_START);という変更で 動いていません。
tmp

2022/12/14 23:24

RXマイコンでは、しりませんが、他のルネサスのCPUでは #pragma ext_func app_prg 0 などテーブルを作るのに指定するものもありました。 アプリケーション②でpragmaで指定する命令はありませんか?
thkana

2022/12/15 00:04

そういえば大事なことを明確にしてなかったっけ。 APP_VECTOR_STARTのアドレスから格納されているはずのものはなんですか? ジャンプ先が書かれたテーブル? それともなにかの実行ルーチン? (昔、ジャンプ命令の羅列、なんてのも見たこともあるけれど)
tmp

2022/12/15 03:35

ジャンプ命令(相対ジャンプ)の羅列の方が配置移動させやすいですからね。確認したら、コンパイラが吐き出すのは相対ジャンプの羅列でした。(RXは、しらん) テーブルからわざわざ読み出してるから、そういったものがあるのかと勘違いしました。
guest

回答2

0

ベストアンサー

とりあえず、e2StudioのRXシミュレータで、リンカ設定とかするの面倒だったのでRAMはコンパイラおまかせで

C

1char buf[1024]; 2volatile int sum=0; 3volatile int s; 4int ret(void){ 5 volatile int i; 6 for( i=0; i<10; i++){ 7 sum+=i; 8 } 9 return sum; 10} 11//-------------------------------------------------------------------------- 12// アプリへジャンプ 13//-------------------------------------------------------------------------- 14void app_boot( ){ 15 int x=10; 16 int (*jmp_program)(void) = (int (*)(void))buf; 17 memcpy(buf, ret, 1024); //ret関数のコードをbufの領域に転送 18 /* Jump to the application */ 19 s=jmp_program(); // bufのアドレスで呼び出す 20 s+=x; 21}

としてみたら、コンパイルすると

Asm

126 int ret(void){ 2 ret: 3fff80620: sub #4, r0 428 for( i=0; i<10; i++){ 5fff80622: mov.l #0, [r0] 629 sum+=i; 7fff80625: mov.l #0xc0c, r14 828 for( i=0; i<10; i++){ 9fff8062b: mov.l [r0], r1 10fff8062d: cmp #9, r1 11fff8062f: bgt.b 0xfff80640 <ret+32> 1229 sum+=i; 13fff80631: mov.l [r0], r1 14fff80633: add [r14].l, r1 15fff80636: mov.l r1, [r14] 16fff80638: mov.l [r0], r1 17fff8063a: add #1, r1 18fff8063c: mov.l r1, [r0] 19fff8063e: bra.b 0xfff8062b <ret+11> 2031 return sum; 21fff80640: mov.l [r14], r1 2232 } 23fff80642: rtsd #4 2436 void app_boot( ){ 25 app_boot: 26fff80644: mov.l #0x400, r3 2739 memcpy(buf, ret, 1024); 28fff80648: mov.l #0xfff80620, r2 29fff8064e: mov.l #0x404, r1 30fff80654: bsr.a 0xfff8066d <memcpy> 3141 s=jmp_program(); 32fff80658: bsr.a 0x404 <buf> 33fff8065c: mov.l #0xc04, r14 34fff80662: mov.l r1, [r14] 3542 s+=x; 36fff80664: mov.l [r14], r15 37fff80666: add #10, r15 38fff80668: mov.l r15, [r14] 39fff8066a: rts

という機械語を吐いて、デバッガで追うとbufのアドレスに飛んで、sに55が入るなぁ、というところまでは見ました。

RAM領域にジャンプする仕組み自体は動いていそうで、そうだとするとそれ以外のナニカに間違いがあることを疑います。

投稿2022/12/14 14:04

thkana

総合スコア7735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Mr.kyousuke

2022/12/15 03:23

解決はしてないのですが、一先ず他のところを探ってみます。
guest

0

コピー先が0x08100000になってますよ

memcpy((void *)0x08100000, (void *)0xFFC00000, 0x200000); //0xFFC00000から2MB分 0x08100000にコピー

追記
すみません。まちがってなかったです。
この回答はスルーしてください。

投稿2022/12/13 12:50

編集2022/12/13 12:51
TaroToyotomi

総合スコア1461

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問