• ベストアンサー
  • すぐに回答を!

H8マイコンのメモリセクションの変更を行いたい

以前私はこのような質問をこのサイトでさせて頂きました。 HEWのビルドで出てきたビルドエラーについて#8678205 #okwave #q8678205 http://okwave.jp/qa/q8678205.html この質問の中で (エラー内容) ** L2321 (E) Section "S" overlaps section "R" Optimizing Linkage Editor Abort ERROR: Process failed with return code: 1 このエラー内容が、Rセクション(初期化領域)の容量がSセクション(スタック領域)にオーバーしているということがわかり、Rセクションの容量を減らすからSセクションの容量を減らして、Rセクションに割り当てる解決方というのを知りました。 実際に開発環境のHEWのtoolchainのセクション設定の項目で変更してビルドが完了し、mapファイルでも設定した通りのアドレスにセクションが設定できることを確認しました。 そのため、初期ではSセクションのスタックは0x200(512)Byteだったのですが、0x1E0(480)Byteと小さくしてしまったのですが、スタック領域を小さくするというのは少し不安を感じています。 他にRAM領域がないかを確認したところ、H8/2368マイコンの外部にCYPRESS社製のSRAM CY62148EV30LL-45ZSX1 TSOPII(32P3Y-H) 512kbyteのメモリをアドレス0x600000番地スタートで接続していることがわかりました。 512kbyteも容量があり、Rセクションはマップで見ても3.2kbyte程度なので、Rセクションだけこのメモリ領域に移したいと考えています。 ただ、 元々このメモリには次のようなメモリセクションが設定されています。 0x00600000 , BHEAPMEM 0x00670000 , BJURNEL このBHEAPMEMとBJURNELという文字をソースコード内で検索してみても全く使用されていない文字で検索できませんでした。 ソースコード内の0x600000番地についての記述では次のような (memmap.h) #define SRAM_BASE_ADDR0x600000 /* size 512 K Byte (0x80000) */ #define SRAM_BASE0x600000 /* size 512 K Byte (0x80000) */ (task.c) void * my_malloc(size_t size) { void * p; OS_ENTER_CRITICAL(); p = (void *)malloc(size); if(p == NULL || ((u32)p < (u32)SRAM_BASE_ADDR || (u32)p > ((u32)SRAM_BASE_ADDR + (u32)0x800000))) { printf("malloc error\n\r"); task_reset(); } OS_EXIT_CRITICAL(); return (void *)p; } 現在のメモリセクションマップはこのようになっています。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x00670000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B,R 0x00FFBE00 , S これを、次のように変えたいと思っています。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x0066F000 , R 0x00670000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B 0x00FFBE00 , S 実際にこのようなメモリセクションに変更することは可能なのか、また、実際に変更した場合にBHEAPMEM領域に問題が起きないかとか他に調べなければならないことなど、ご教示頂きますよう、どうぞよろしくお願い致します。

共感・応援の気持ちを伝えよう!

  • 回答数4
  • 閲覧数1639
  • ありがとう数16

質問者が選んだベストアンサー

  • ベストアンサー
  • 回答No.4

結果から言えば、外部RAM中にセクションを割り当てることは大変危険ですね。 必要分の連続したメモリが確保できず、メモリアロケーションに失敗するのでしょう。 OS_EXIT_CRITICAL()実行前のポインタチェックでの挙動ですから、単純にそう考えるべきで、永遠にWDTの餌食になりそうな気がします。 この方法は諦めた方が良さそうです。 というか・・・ 外部RAMを使用しないセクション割当てで正常に動作するなら、そもそも心配は杞憂なのでは? Stack不足や変数のアドレス割付け異常なら、最初から正常に動作しないような気がします。 何度も言いますが、どんなシステムかも不明なので想像でしか話ができず、”気がします”を多発することになってしまいますが・・・

共感・感謝の気持ちを伝えよう!

質問者からのお礼

回答頂きありがとうございます。返事が遅くなり申し訳ありません。 この度は詳細な内容を教えて頂き、お世話になっております。 現在Rセクションの位置を別の場所に移す修正の際に動作できない現象に関しましては一旦あきらめたいと思います。B,Rセクションの位置を分離しての修正でうまくいきませんが、スタックセクションを縮小というのは避けたいとは思っています。 また、新規に相談投稿しました際にはぜひよろしくお願い致します。

関連するQ&A

  • H8 マイコン セクションの設定について

    最近H8/3694Fを使ってマイコンの勉強をしております。 HEWを使ってコンパイルするときのセクションの設定に ついて質問があります。 プログラム・セクションの設定を一通り終え、ビルドすると 「L2321 (E) section "S" overlaps sction "P"」 とエラーメッセージが出てしまいました。 色々調べてみるとSはスタック領域、Pはプログラム領域 でこれに重なりができてしまっているようなのですが、 これ以上どうしてよいのかわからず困っています。 おそらくセクション設定を変更すればよいと思っていますが プログラム領域にどれくらい、スタック領域にどれくらい を配置すればいいというのはどうやって求めればよいのでしょう? HEWのメモリマップを表示させて見る方法があるようですが 見てもいまいちわかりませんでした。 使用環境:OS:WindowsXP、HEW4.04.01.001 以上、追記補足いたします。詳しい方教えていただけないでしょうか

  • あるメモリ番地からあるメモリ番地へそっくりコピーする方法

    現在、動作確認を行っている基板があるのですが、経験が少なく、いろいろとわかる方に聞く日々が続いています。いろいろと教わった結果、メモリ領域の操作方法や、どのようにメモリ領域を使っているのかを把握することがとても重要と考えて来るようになりました。そこで、テストボードで、CPUにつながったメモリの番地を聞いてみたところ、開発で使用している”memmap.h”というファイルがあると教わりました。それを閲覧してみると次のようにかかれていました。 #include "comm.h" #include "event.h" #include "ethernet/dhcp.h" /* FALSE Memory Map */ #define FLASH_BASE 0x200000 #define FLASH_FONT_ADDR FLASH_BASE #define FLASH_AUDIO_ADDR FLASH_BASE + 0x0B0000 #define FLASH_NUMBER_ADDR FLASH_BASE + 0x1F0000 #define FLASH_ENV_ADDR FLASH_BASE + 0x1F8000 /* SRAM Memory Map */ #define SRAM_BASE 0x400000 #define SARM_TCP_PVC_BUF (BYTE *)(SRAM_BASE + 0x008000) //8 #define SRAM_NUMBER_BUF (BYTE *)(SRAM_BASE + 0x010000) //8 #define SRAM_ENV_BUF (BYTE *)(SRAM_BASE + 0x018000) //8 #define SRAM_FLASH_BUF (BYTE *)(SRAM_BASE + 0x020000) //8 #define SRAM_NET_BUF (BYTE *)(SRAM_BASE + 0x030000) //1 #define SRAM_AUDIO_BUF (BYTE *)(SRAM_BASE + 0x040000) //2 #define SRAM_MISC_USE (BYTE *)(SRAM_BASE + 0x060000) //8 #define SRAM_STACK_BUF (BYTE *)(SRAM_BASE + 0x069000) //8 #define SRAM_JURNEL_BUF (BYTE *)(SRAM_BASE + 0x070000) #define SRAM_JURNEL_BUF2 (BYTE *)(SRAM_BASE + 0x078000) それで、0x400000番地からのSRAMは常に基板の電源を切っても電池で守られているためデータは消えないのですが、ここにパスワード関連の410000番地からのSRAM_NUMBER_BUFでいったんデータを登録したら、FLASH領域のSRAM_NUMBER_BUF(3F0000番地から)に丸ごとコピーしているそうなのですが、そのように丸ごとコピーできるC言語の関数は内でしょうか?また、丸ごとコピーできるような簡単な書き方はないでしょうか?

  • printfで0x600000番地の次の0x600001番地の値を出力したい。

    H8マイコンの0x600000番地につながるSRAMメモリの内容を見たくて、 #define SRAM_BASE_ADDR 0x600000 #define SRAM_TEST_ADDR *((volatile u8 *)SRAM_BASE_ADDR) printf("data:%X addr:%p\n\r", SRAM_TEST_ADDR,(void*)&SRAM_TEST_ADDR); このような形でアドレス0x600000番地のデータをprintf関数で出力してUARTで確認していたのですが、次の0x600001番地のデータをみたい場合はprintf関数をどのように書いたらよいのでしょうか?

その他の回答 (3)

  • 回答No.3

No.2です。 プログラムやヘッダ中に、BJURNELの先頭アドレスを定義している箇所はありませんか? それらを変更せず、BJURNELのセクション番地だけを変更するのが暴走の原因(R領域を破壊する)なのでは? >R(初期化セクション)は外部メモリ空間のメモリとかに配置するのは問題があるということでしょうか? 一般的に、外部RAMには未初期化領域(B)を配置します。 何故なら、外部RAMはバックアップ(ボタン電池で常時給電する)が可能なので、値を保持しておきたい変数は外部RAMに配置します。 よって”未初期化領域”と呼ぶのです。 未初期化領域をCPU内部RAMに配置しても、CPUへの電源供給断で消去されてしまいますよね。 よって未初期化領域・初期化領域の両方をCPU内部RAMに配置すると、その違いは初期値を与えるか否かだけになってしまいます。(ちなみに、初期化領域に与える初期値が入っているセクションがC$DSECです) 外部RAMを使用する、またバックアップするかどうかはシステムの目的次第です。 以上より、通常は初期化領域(R)をCPU内部RAM、未初期化領域(B)を外部RAMに配置するのが正しいと言えます。 しかし、お使いの外部RAMがバックアップされていなければ意味がないので、バックアップされていない場合は、どちらでも良いということになります。 また、外部SRAMがプログラム中でどのように使われているかが不明なので、安易に外部RAMにセクションを配置して良いのかどうかまではわかりません。 余談ですが、HEWの場合、グローバル変数の宣言方法によって割り当てられる領域が変化します。 int a ; ←未初期化領域(B)へ割り当てられる int b = 0 ; ←初期化領域(R)へ割り当てられる 例えば、未初期化領域の容量が極端に小さい場合、変数に(無意味な)初期値を与えて、初期化領域に配置転換するという手法もあります。 極端な話、全ての変数に初期値を与えれば未初期化領域は不要、ということにもなります。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

回答頂きありがとうございます。 Rセクションを外部メモリ領域の670000番地に変更してみた件に関しまして、修正作業を進めてわかったことを書かせて頂きます。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x00670000 , R 0x00671000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B 0x00FFBE00 , S BJURNELは0x00671000番地に変更しているため、それに関わるソースコード中のデータ書き込みの番地に関して調べてみたところ、 ”BJURNEL” という文字は使われておらず検索されなかったのですが、 代わりにこのような記述がありました。 #define SRAM_SAVE_STATUS(BYTE *)(SRAM_BASE + 0x06fe00) #define SRAM_JURNEL_BUF(BYTE *)(SRAM_BASE + 0x070000) #define SRAM_JURNEL_BUF2(BYTE *)(SRAM_BASE + 0x078000) #define SRAM_JURNEL_ADDR(SRAM_BASE + 0x070000) たぶん”SRAM_JURNEL_BUF”はイベントログの保存番地を指定する際に使用しているものだと思いRセクションを0x670000に置いたことで+0x1000しなければいけないと思い次のように修正しました。 #define SRAM_SAVE_STATUS(BYTE *)(SRAM_BASE + 0x06fe00) #define SRAM_JURNEL_BUF(BYTE *)(SRAM_BASE + 0x071000) #define SRAM_JURNEL_BUF2(BYTE *)(SRAM_BASE + 0x079000) #define SRAM_JURNEL_ADDR(SRAM_BASE + 0x071000) 他に番地変更に伴う修正が必要な箇所は見当たらない感じでしたので、これでコンパイルをかけて完了できました。 しかしこのファームウェアをダウンロードして実行するとやはり暴走したような現象が出る状況です。 BITRAN社製のICEデバッガDR-01でmain関数の最初のところブレークポイントをかけて見たところ、数秒ごとにmain関数の最初のブレークポイントに戻ってくるような現象が出ていることがわかりました。 なので、どこかでウォッチドックRESETが発生している感じです。 どこでウォッチドックが発生しているかを特定しているかを確認してみたところ、 task.cのソースコードファイル内の void * my_malloc(size_t size)関数のtask_reset();という関数を実行していることがわかりました。 void * my_malloc(size_t size) { void * p; OS_ENTER_CRITICAL(); p = (void *)malloc(size); //if(p == NULL || ((u32)p < (u32)SRAM_BASE_ADDR || (u32)p > ((u32)SRAM_BASE_ADDR + (u32)0x70000))) if(p == NULL || ((u32)p < (u32)SRAM_BASE_ADDR || (u32)p > ((u32)SRAM_BASE_ADDR + (u32)0x800000))) { printf("malloc error\n\r"); task_reset(); } OS_EXIT_CRITICAL(); return (void *)p; } 以前ご指摘頂いた if(p == NULL || ((u32)p < (u32)SRAM_BASE_ADDR || (u32)p > ((u32)SRAM_BASE_ADDR + (u32)0x800000))) この条件に合致したことでtask_reset();を実行したようです。 なお、task_reset();でブレークポイントをかけた際に”p”の値をウォッチしたところ、 値が0xFCFCFCDC となっていました。 なお、この関数は次のように void task_reset() { int i; #ifndef WATCH_FUNC WDT.WRITE.RSTCSR = 0x5A40; WDT.WRITE.TCSR = 0xA565; WDT.WRITE.RSTCSR = 0xA500; #else WDT.WRITE.RSTCSR = 0x5A40; WDT.WRITE.TCSR = 0xA565; WDT.WRITE.RSTCSR = 0xA500; OS_ENTER_CRITICAL(); #endif while(1); } 最後にwhile(1);で永久ループに入れてウォッチドックを待つような仕掛けになっていました。 他に調べてみたところで、現在このソースコードプロジェクトではuC/OSというOSを使用しているのですが、main関数からスタートすると、OSが管理する機能別のタスクを作成する処理をはじめるのですが、 各タスクにブレークポイントを設定しても、そこにブレークポイントがかからず、ここまで到達できていない状況でした。 この同一のソースコードで再度、スタックメモリを削減して、以前と同じセクション配置の設定にしてコンパイルして実行すると、問題なく動作する違いが確認できました。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x00670000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B,R 0x00FFBEB0 , S このときは void * my_malloc(size_t size)関数で、task_reset();を実行することはないことも確認できました。 自分としてはuC/OSの仕様として何かあるのかなとか思ったりするのですが、何か他に調べた方が良いことなどありましたらご教示頂きますよう、よろしくお願い致します。

  • 回答No.2

以前、回答した者です。 外部RAMは、task.c中で動的に必要分を確保されるようなので、この外部RAMにセクションを配置すると危険なのでは? これはリンクマップを見てもわかりませんよ。 関数my_mallocの引数(=必要メモリサイズ)が、外部RAMサイズより常に十分小さければ問題ないかもしれませんが、この質問だけでは分かりかねますね。 関数my_mallocが、いつ、どこから、どのタイミングで呼ばれるのかもわかりません。 関数OS_ENTER_CRITICALも何者でしょう? if(p == NULL || ((u32)p < (u32)SRAM_BASE_ADDR || (u32)p > ((u32)SRAM_BASE_ADDR + (u32)0x800000))) これは if(p == NULL || ((u32)p < (u32)SRAM_BASE_ADDR || (u32)p > ((u32)SRAM_BASE_ADDR + (u32)0x80000))) のタイプミスかな?

共感・感謝の気持ちを伝えよう!

質問者からのお礼

回答頂きありがとうございます。前回は大変お世話になりました。 まず、”OS_ENTER_CRITICAL”についてですが、このソースコードプロジェクト内部ではuC/OSというOSでマルチタスク処理のコードを追加しており、それに関係するコードだと思われます。 実際に次のようなメモリセクションに設定してコンパイルを行って見ました。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x00670000 , R 0x00671000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B 0x00FFBE00 , S 最初はRセクションを0x0066F000からととっていたのですが、RBHEAPMEM領域を縮めるのは少し怖いとおもいこれは避けて、BJURNEL領域はプログラム動作のイベント発生時に出力するログデータを残す場所で、本来の動作処理のデータではないので、こちらを縮めることにしました。 コンパイルが成功したので、このファームウェアをICEデバッガ書き込み機で書き込んで動作させてみたのですが、本来LCD画面に表示されるはずの画像が表示されませんでした。 同一のソースコードでメモリセクションのスタック領域を縮める方法で Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x00670000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B,R 0x00FFBEB0 , S これでコンパイルが成功したファームウェアを動作させたところこちらは今のところ問題なく動作することがわかりました。 R(初期化セクション)は外部メモリ空間のメモリとかに配置するのは問題があるということでしょうか? CS3の領域に512kbyteのCypress社製のSRAMをのせています。 他に確認した方が良いことなどご教示頂きますよう、よろしくお願い致します。

  • 回答No.1
  • tsunji
  • ベストアンサー率20% (196/958)

マップの変更は可能です。 ただし、SRAMにつながっている信号線、CS、RD、LWR、HWRや、 アドレス/データバスがSRAMを使えるような設定に初期化されているかも 確認する必要がありますね。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

回答頂きありがとうございます。 実際に次のようなメモリセクション設定でコンパイルを行い完了できました。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x00670000 , R 0x00671000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B 0x00FFBE00 , S このファームウェアをマイコンにダウンロードして実行してみたのですが、オープニングにLCD画面に表示されるはずの画面が表示されませんでした。暴走しているように感じました。まだ詳細は調べていません。 とりあえず、同一のソースコードでスタック領域を減らす方法で次のメモリセクション設定を行いコンパイルを完了させてみました。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x00670000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B,R 0x00FFBEB0 , S これでコンパイルはできて、実際にダウンロードして実行したところ動作通りLCD画面に画像を表示して動いていることを確認しました。 R(初期化セクション)は外部メモリ空間のメモリとかに配置するのは問題があるということでしょうか? SRAMにつながる信号線は (マイコン側) xCS3ーーーーーーー>xCS(入力) xHWRーーーーーーー>xWE xRDーーーーーーーー>xOE 電源投入時に、Rセクションの初期化でSRAMにアクセスができずに暴走していると考えられますでしょうか? どうぞ、ご教示の程よろしくお願い致します。

関連するQ&A

  • メモリのセクションに関して

    こんばんは。 表題の通り、セクション領域に関して3点ほどご質問が御座います。 (1)グローバル変数は、  ・0でない初期化を行う→.dataセクション  ・0で初期化、または、初期化なし→.bssセクション  上記のようにメモリに配置されると思いますが、  上記をstatic宣言した場合でも結果は同じでしょうか?  (static宣言したグローバル変数) (2)スタック、ヒープそれぞれが属するセクションは、それぞれ専用の  スタックセクション、ヒープセクションという名のセクションがあるという認識であっていますでしょうか?  (.dataでもなく、.bssでもなく、.textでもなく、.rodataでもなく。。。) (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか? どうかご教授をお願い致します。

  • H8マイコン スタック領域について

    スタック領域について教えて下さい。 [動作環境]  開発環境:ルネサス HEW Version 4.08  マイコン:ルネサス H8/1653  コンパイラ:H8SX,H8S,H8ファミリ用C/C++コンパイラパッケージ V7.00 HEWにて新規作成しますと、セクション定義にスタック領域(S)のアドレスと stacksct.h 内に スタック領域のサイズ #pragma stacksize 0x200 が自動で生成されると思います。 しかし、入手したH8/1653用のサンプルには #pragma stacksize のような サイズ指定がありませんでした。 [サンプル] (1)セクション定義やスタック領域のサイズ指定が無い (2)サブコマンドファイル(xxxx.sub)内でアドレスは設定されているが サイズの設定が無い。 -- サブコマンドファイル(xxxx.sub)-- START  CStart/00000000; START  P,C,D/00000400; START  B,R/00FF2000; START S/00FFC000; [質問]  質問1   (1)のスタック領域はどこに配置されるのでしょうか?  質問2   (2)のスタック領域は 00FFC000 を基準にどう確保   されるのでしょうか? (a)の方向へ確保?(b)の方向へ確保?          00F00000 (a)         ↑       00FFC000 (設定アドレス)         ↓       00FFFFFF (b)        質問3   (1)、(2)共にスタック領域と同時にヒープ領域も指定がありません。   これらは指定しなくても問題ないものなのでしょうか?   また、熟練者の方は指定しないものなのでしょうか? よろしくおねがいします。

  • HEW統合開発環境のリンカー設定で”BHEAPMEM”という設定の意味は?

    今、H8S2368用のHEWで動かしていたサンプルプログラムをもらって、動かそうと思っていたときに、このマイコンには、FlashメモリとSRAMメモリが外部についていたので、どのようにアクセスしているのかなと思い調べていたのですが、 リンカーの設定でこの部分をどうやって使用しているのかというのがわかるということを教えてもらいました。 ちなみにFLASHメモリはサイプレス社の”CY62148EV30LL-45ZSX1TSOPII(32P3Y-H)” SRAMはSPANSION社製の”S29GL032N(03,04)”というのがつながっていて、 0x200000~0x40000 これがFLAHSHメモリの領域 0x600000~0x800000 これがSRAMメモリの領域となっています。 このリンカーの設定で0x600000のセクションに”BHEAPMEM”という設定をしているのですが、これはどういう意味の設定になるのでしょうか。 この”BHEAPMEM”という設定をすれば、ローカル変数や、グローバル変数や、バリアブルの変数などはFlashメモリ領域ではなく、0x600000のSRAM領域に自動的にコンパイラはデータを置くようになってくれるのでしょうか?

  • new と malloc によるメモリの動的確保について

    初めて投稿させて頂きます。よろしくお願い致します。 現在、以下のような、2次元配列による動的なメモリの確保を意図して、コードをC/C++にて記述しています。 (コンパイラはMINGW32のg++ 3.4.5) //mallocによるメモリ動的確保 data = (char **)malloc(num * sizeof(char*)); for(i=0; i<rowNum; i++){ data[i] = (char *)malloc(sizeof(char)*256); } //newによるメモリ動的確保 data = new char*[rowNum]; for(i=0; i<rowNum; i++){ data[i] = new char; } C++で書くのならば、 「mallocによるメモリ確保は辞め、newによるメモリ確保をしなさい」 という指摘が、書籍でもwebでもありましたので、 両方書き、両者を比べているのですが、理由がイマイチ分かりません。 10万行ほどのテキストデータで実験させてみたのですが、 mallocによる記述の方が、動作が数秒速いようなのです。 それで、new やmalloc で実際何をやっているのか、コードを見ようと思ったのですが、 newでは、 void* operator new(std::size_t) throw (std::bad_alloc); void* operator new[](std::size_t) throw (std::bad_alloc); void* operator new(std::size_t, const std::nothrow_t&) throw(); void* operator new[](std::size_t, const std::nothrow_t&) throw(); inline void* operator new(std::size_t, void* __p) throw() { return __p; } inline void* operator new[](std::size_t, void* __p) throw() { return __p; } というnewファイルの記述で行き詰まり、 malloc は malloc_allocator.hというファイルで行き詰りました。 以上を踏まえて、 1)そもそも、上記のメモリ動的確保記述はスマートな書き方なのか 2)実際に、newやmallocは、どういった手法でメモリ領域を確保しているのか 以上の2点について、ご教授下さい。よろしくお願い致します。

  • HEWのビルドで出てきたビルドエラーについて

    現在H8S/2368マイコンのプログラミングをやっています。 プログラム修正を行っていて、ビルドを行ったところ、次のようなビルドエラーがHEWから出てきました。 (エラー内容) ** L2321 (E) Section "S" overlaps section "R" Optimizing Linkage Editor Abort ERROR: Process failed with return code: 1 このエラーのため実行バイナリファイルが作成できません。 Debugフォルダに作られるmapファイルを見たところ -----(中略)------------------------------------ $VECT118 000001d8 000001db 4 0 PResetPRG 00000400 0000041f 20 2 PIntPRG 00000420 000004ab 8c 2 P 00000800 00060af7 602f8 2 C 00060af8 00066de1 62ea 2 C$DSEC 00066de2 00066ded c 2 C$BSEC 00066dee 00066df5 8 2 D 00066df6 0006789b aa6 2 BHEAPMEM 00600000 0066fdff 6fe00 2 BJURNEL 00670000 00670007 8 2 BPROGERASE 00ff4000 00ff43ff 400 2 B 00ff4400 00ffb365 6f66 2 R 00ffb366 00ffbe0b aa6 2 S 00ffbe00 00ffbfff 200 2 *** Total Section Size *** RAMDATA SECTION: 00077e14 Byte(s) ROMDATA SECTION: 00006ed8 Byte(s) PROGRAM SECTION: 000603a4 Byte(s) 確かに、Rセクションの終了アドレス 0x00ffbe0b が Sセクションの開始アドレス 0x00ffbe00 を超えてしまっているようなのですが、これはなぜなのでしょうか? この現象はプログラム容量がもうフルの状態を表していると言うことでしょうか? また、疑問なのですが、”PROGRAM SECTION: 000603a4 Byte(s)”と表示は現在のプログラム容量の値ということでしょうか? 現在このマイコンを下のサイトで調べてみると http://japan.renesas.com/products/mpumcu/h8s/h8s2300/h8s2368/index.jsp 型番はHD64F2368VTE34Vを使用しているのですが、それならばプログラムメモリは512kbyteあり、現在、394.148kbyteしか使っていないので、まだ余裕があると思うのですが、解決する方法はないのかご教示頂きますようお願い致します。

  • C言語におけるローカル変数が使用するメモリについて

    例のようなC言語のプログラムを動かした場合、 確保されるメモリ領域はどうなるのでしょうか。 例 #include <stdio.h> int main(void) { int a = 0; } このとき、変数aはint型なのでスタック領域に4バイトのメモリが確保されると理解しています。 と同時にaという変数名と確保されたスタック領域の番地を紐づけるようなメモリがどこかに確保されるのではないかと思ってるのですが、この理解で正しいでしょうか。 またその場合は変数aの番地はどの領域に確保されるのでしょうか。 ご教示お願いいたします。

  • mmap()した領域の領域確保

    mmapで特定のデバイスのIOメモリを仮想空間に割り付けて, その領域に対してユーザーからデータを書き込むことを考えています. ユーザープログラム側でその領域上に,ある構造体の双方向リスト を作りたいのですが,ユーザー空間の特定のアドレス範囲から空き メモリ領域を動的に確保する方法はないでしょうか void *vm_malloc(start_address, end_adress, nbyte); とすると"仮想アドレスstart_address~end_adressの範囲から空き領域を探し出し, nbyteバイトの領域を確保する"みたいなイメージです 一連の流れとしては,struct hogeをIOメモリに書き込む場合,  ・mmap()でIOメモリを仮想空間にマップ  ・struct hoge* addr = vm_malloc();でマップされた領域からsizeof(struct hoge)だけ領域を確保  ・*addr = .....;  ・vm_malloc, データの書き込みの繰り返し  ・fsync() のようなことをしたいと考えています.

  • 動的なメモリ領域の確保

    double型変数5個分のメモリをmalloc関数により確保し,その確保した要素のアドレスを表示するように,プログラムを作る問題で、 (注)に「 %pで表示するためには,double型へのポインタ(double *)をvoid型へのポインタ(void *)にキャストする必要がある.」と書かれていたのですが、どういうことでしょうか? 以下のようでいいのでしょうか? #include<stdio.h> #include<stdlib.h> #define COUNT 5           // 動的に確保するメモリ領域数を示すマクロ定数の定義 int main(void) {  // 動的に確保するメモリ領域のアドレスを保持するポインタ変数の宣言  double * pointer;  int i;                  // for文で使用する変数の宣言  // int型変数5個分のメモリ領域を確保  pointer = (double *)malloc(sizeof(double) * COUNT);  if(pointer == NULL) {        // メモリ領域の確保が失敗した場合   printf("メモリ領域を確保できませんでした.\n");   exit(1);                // プログラムの終了  }  for(i = 0; i < COUNT; i++)   printf("%d番目のアドレスは%pです.\n", i + 1, pointer + i);  free(pointer);            // 確保したメモリ領域の解放  return 0; }

  • c言語を用いて画像の透明度をあげる方法を教えてください。

    c言語を用いて画像の透明度をあげる方法を教えてください。 下プログラムの画像処理ができません。 #include <stdio.h> #include <stdlib.h> #include <memory.h> #include "mybmpi.h" /*メイン関数*/ int main(void) { int width, height; int x, y; BYTE *buffer_f; /*入力画像(前景)用メモリのポインタ*/ BYTE *buffer_b; /*入力画像(背景)用メモリのポインタ*/ BYTE *Rbuffer_f, *Gbuffer_f, *Bbuffer_f; /*入力(前景)用*/ BYTE *Rbuffer_b, *Gbuffer_b, *Bbuffer_b; /*入力(背景)用*/ BYTE *Rbuffer2, *Gbuffer2, *Bbuffer2; /*出力用*/ double tmp_pix; double ratio=0.5; /*どの割合で混ぜるか ratio : 1-ratio */ /*前景画像ファイルを開く*/ buffer_f = LoadBitmap("front.bmp", &width, &height); if(buffer_f==NULL) { /*ファイルが開けなかったので終了*/ return 0; } /*背景画像ファイルを開く*/ buffer_b = LoadBitmap("back.bmp", &width, &height); if(buffer_b==NULL) { /*ファイルが開けなかったので終了*/ return 0; } /*RGBを色平面に分解*/ Rbuffer_f = (BYTE*)malloc( width*height ); /*メモリ確保*/ Gbuffer_f = (BYTE*)malloc( width*height ); Bbuffer_f = (BYTE*)malloc( width*height ); RGB2Plane(buffer_f, Rbuffer_f, Gbuffer_f, Bbuffer_f, width, height); Rbuffer_b = (BYTE*)malloc( width*height ); /*メモリ確保*/ Gbuffer_b = (BYTE*)malloc( width*height ); Bbuffer_b = (BYTE*)malloc( width*height ); RGB2Plane(buffer_b, Rbuffer_b, Gbuffer_b, Bbuffer_b, width, height); /*出力用*/ Rbuffer2 = (BYTE*)malloc( width*height ); /*メモリ確保*/ Gbuffer2 = (BYTE*)malloc( width*height ); Bbuffer2 = (BYTE*)malloc( width*height ); /*****************画像処理をここで行う********************/ for(y=0; y<height; y++){ for(x=0; x<width; x++){ /*この部分がわかりません*/ /*前景画像と背景画像を ratio : 1-ratio で合成する方法?*/ /*R,G,Bそれぞれについて同じ処理をする*/ } } /*******************ここまで******************************/ /*書き込み処理*/ Plane2RGB(buffer_f, Rbuffer2, Gbuffer2, Bbuffer2, width, height); /*bufferは入力のものを転用する*/ SaveBitmap("result.bmp", buffer_f, width, height); /*メモリを解放する*/ free( buffer_f ); free( buffer_b ); free( Rbuffe

  • メモリ領域確保に関して

    C言語を始めて3ヶ月の初心者です。 下記のような定義で、領域確保をしたいのですが、 うまい方法がわかりません。 ご存知の方いらっしゃいましたら、 御知恵をお貸し下さいませんでしょうか? <test.h> ================================== #define SIZE_A (5) /* 親構造体 */ typedef struct { int testInt; testSmallStructT *testSmall; // 7バイト構造体の配列 char *testChar; // SIZE_A分の領域*配列数 } testBigStructT; /* 7バイト構造体 */ typedef struct { char str1[3]; char str2[4]; } testSmallStructT; /* メンバ変数 */ testBigStructT gTest[10]; ================================== ここで、あらかじめ全体の領域サイズを算出して、 mallocにてエリア確保を行う方法を求めてます。 また、多数にmallocを使用するとメモリ確保失敗時に、 それまで確保したエリアの開放を行わなくてはいけなくなる懸念から、 できるだけ使用しないようにしたいのです。 メンバ変数gTestを10の配列で持ち、構造体testBigStructTの、 要素testSmallとtestCharを可変の配列として扱いたくポインタ定義をしており、 更に、testCharにSIZE_A(5byte)の領域を確保しようとしております。 最終的には、下記のような使い方をしたいのですが、 メモリ確保の方法がわかりません。 =================================== (EX:) strcpy(gTest[0].testSmall[0].str1,"aaa"); strcpy(gTest[3].testSmall[2].str2,"bbb"); strcpy(gTest[6].testChar[3],"cccc"); =================================== 開放は下記の記述で問題ないと思っております。 free(gTest); 大変申し訳御座いませんが、 ご指摘・ご指導願いませんでしょうか? どうか宜しくお願い致します。