HEWリンカー設定でのBHEAPMEMの意味とは?

このQ&Aのポイント
  • HEW統合開発環境のリンカー設定で使用される”BHEAPMEM”とは、マイコンのメモリアクセスに関する設定である。
  • 具体的には、リンカーの設定で0x600000のセクションに”BHEAPMEM”という設定をすることで、ローカル変数やグローバル変数、バリアブルの変数がFlashメモリ領域ではなく、0x600000のSRAM領域に置かれるようになる。
  • これにより、マイコンに外部のFlashメモリとSRAMメモリが付いている場合でも、リンカーの設定を適切に行うことで、メモリ領域の使い分けが可能となり、効率的なメモリの利用が実現できる。
回答を見る
  • ベストアンサー

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領域に自動的にコンパイラはデータを置くようになってくれるのでしょうか?

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

  • ベストアンサー
  • bug_bug
  • ベストアンサー率78% (36/46)
回答No.2

> として宣言しているという考え方でよいのでしょうか? 概ね間違いないと思います. 質問時の添付画像ではHEWのGUIを用いて,「リンカに与えるセクション定義ファイル」の設定を行う画像です. ポイントはそれぞれのセクションの開始アドレスは指定してあっても, 終端アドレスは指定していない点です.(指定する必要がない) リンカは記述順に指定セクションの頭から割付を行っていくので 実装してある2MBのSRAMに十分収まっています. 割り付けられたアドレスはリンカの出力ファイルで確認が可能です. (拡張子は .lnkだったような・・・手元に環境が無いため失礼) 分かってしまえば難しい話ではなく, ただソースコードでセクションを指定し, リンク時にメモリアドレスへの割付が行われているだけの話です. ソースコード上ではセクションを指定した以降に変数/定数/関数などなんでも記述が可能ですが, リンカにはそれぞれB***(D***)/C***/P***とした割付の指定を与えてあげなければなりません. ソースコード上ではベースのセクション名(ex.HEAPMEM)を指定し, リンカの入力ファイルにはそれぞれプリフィックスのついたセクション割付(ex.BHEAPMEM)を行っています.

その他の回答 (1)

  • bug_bug
  • ベストアンサー率78% (36/46)
回答No.1

BHEAPMEM とは意味合いとして"B + HEAPMEM"です. セクション名の頭には以下の接頭語を付けメモリ空間への割付を行っています. P : プログラムコード(ROM上に配置) C : 定数(ROM上に配置) D : 変数の初期値(ROM上に配置) R : 初期値付き変数(RAM上に配置) B : 初期値なし変数(RAM上に配置、概ね値0でスタートアップ時に初期化) S : スタック(RAM上に配置) デフォルトのセクションは無名ですので, P/C/D/R/B/Sと名づけられた各Sectionが存在します。 BHEAPMEMと名づけられたエリアは, #pragma section HEAPMEM とディレクティブにてセクション指定した以降に記述される"初期値の無い変数"が自動的に配置されます. > ローカル変数や、グローバル変数や・・・ ソースコード上でのスコープの問題なのでメモリ空間上の割付には関係がありません. BHEAPMEMはライブラリか, もしくはそのプロジェクトでスクラッチで用意した ヒープ管理のコードによって割り付け済みである「貸し出し用のメモリ領域」を示すものでしょう.

techhouse
質問者

お礼

詳細な回答頂きありがとうございます。返事遅れまして大変もしわけありません。 現在使用しているプログラムの複数のソースファイルで”HEAPMEM”という文字で検索をかけてみたところ、下のような記述がありました。 #pragma section HEAPMEM INT8U memBuf[MEM_BLOCK_NUM][MEM_BLOCK_SIZE]; u32 memTbl[MEM_BLOCK_NUM]; #pragma section typedef unsigned char INT8U; typedef u32 u_long; #define MEM_BLOCK_NUM 4816 #define MEM_BLOCK_SIZE 64 このような記述があるので、 この0x600000~0x800000のSRAM領域には、 INT8U memBuf[MEM_BLOCK_NUM][MEM_BLOCK_SIZE]; u32 memTbl[MEM_BLOCK_NUM]; この2つの宣言の配列変数を ”B : 初期値なし変数(RAM上に配置、概ね値0でスタートアップ時に初期化)” として宣言しているという考え方でよいのでしょうか?

関連するQ&A

  • 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_ADDR 0x600000 /* size 512 K Byte (0x80000) */ #define SRAM_BASE 0x600000 /* 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領域に問題が起きないかとか他に調べなければならないことなど、ご教示頂きますよう、どうぞよろしくお願い致します。

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

    現在、動作確認を行っている基板があるのですが、経験が少なく、いろいろとわかる方に聞く日々が続いています。いろいろと教わった結果、メモリ領域の操作方法や、どのようにメモリ領域を使っているのかを把握することがとても重要と考えて来るようになりました。そこで、テストボードで、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言語の関数は内でしょうか?また、丸ごとコピーできるような簡単な書き方はないでしょうか?

  • HEWのtoolchainの設定の確認方法。

    現在、H8Sマイコンのプログラミング環境を今までやっていたPCから別のPCでもできるように自分のPCにHEWをインストールして同じ環境を構築しようとしています。 今までビルドを行っていたPCからプロジェクトを自分のPCにもコピーしてビルドを実行してみたところ、ソースコードも同一なのですが、出力されてきたバイナリファイルの内容に違いが生じてしまいます。 今までのPCと自分のPCにインストールされているHEWのコンパイラのVersionも確認したところ同一であることも確認しました。 hwpファイル等もファイルパスの違いがあるだけだったので、それぞれのPCのHEWのtoolchainの設定を今度は比較したいと思っているのですが、現在のHEWのtoolchainで設定されているオプションなどのテキストはどこかのファイル等で一括で確認することはできませんでしょうか? どうぞ、ご教授いただきますよう、お願い致します。

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

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

  • H8 外部バスのデータアクセス

    H8 外部バスのデータアクセス ルネサスのH8マイコン初心者です。(C言語も初心者です) 外部バスのCS1(0x200000)に512KBのSRAMが繋がっているのですが、 HEWのセクションを変更せず、直接SRAMに対して読み書きしたいと思っています。 バスコントローラは設定済みという前提で以下の(A)~(C)のように 宣言すればデータの読み書きは出来ると思うのですが、 (A)~(C)を配列や構造体として扱いたい場合、どのように宣言すれば 良いのでしょうか? (A) #define SRAM1 (*(volatile unsigned int*)(0x200000)) (B) #define SRAM2 (*(volatile unsigned int*)(0x200002)) (C) #define SRAM3 (*(volatile unsigned int*)(0x200004)) (D) SRAM1 = 1; (E) SRAM2 = 2; (F) SRAM2 = 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)共にスタック領域と同時にヒープ領域も指定がありません。   これらは指定しなくても問題ないものなのでしょうか?   また、熟練者の方は指定しないものなのでしょうか? よろしくおねがいします。

  • 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関数をどのように書いたらよいのでしょうか?

  • HEW統合開発環境でプロジェクトを開くと出てくるエラー

    H8マイコンのプログラミングを行っていたPCが故障してしまい、今までのプロジェクトを新しいパソコンの方に移して、同じプロジェクトを起動したところ、 Toolchain 'Hitachi H8S,H8/300 Standard Toolchain'version '6.2.2.0'is missing from the following project(s) test There is no compatible toolchain. Build functionality will not be available. というエラーが必ず表示されます。 これをOKすると、ビルドボタンが押せない状態なのですが、これはどのような症状なのでしょうか?

  • 組み込みシステム メモリマップ割り当てについて

    職業としてH8マイコンなどを使った 組込みシステムを設計している人に質問です。 (1)変数の作成 変数(型は問わず)を作成する際、割り当てる領域の メモリマップのアドレスを指定して作成する、という話を聞きました。 趣味として組み込みを楽しむ分には気にすることではないらしいですが アドレスを指定する必要性は何でしょうか? (2)メモリマップの未使用領域 とあるプログラムで、ログをCPUのメインメモリではなく データ格納用の外部メモリ(EEPROM)に保存するという 仕様のプログラムがあり、ログを保存するメモリマップが 下記にようになっていました。 0h - 1Fh データA 20h - FFh 未使用 100h - 1000h データB 1001h - 1FFFh 未使用 2000h - 3FFFh データC ¦ 素人考えですが、ログデータならデータとデータの間に 「未使用」の領域を入れる必要はないのでは? 未使用領域の分だけ、多くログデータを保存できるでは? と思っています。 これには何か意図があるのでしょうか? また、ログに限らず(1)の変数やプログラムの使用領域を 割り当てる際も間に未使用領域を作った方が良いのでしょうか? 分かりずらい文章かと思いますが、ご回答宜しくお願い致します。

  • 3点を通る放物線の求め方を教えてください。

    3点を通る放物線の求め方を教えてください。 (x1,y1), (x2,y2), (x3,y3)をこの順番で通り、頂点を(x2,y2)とする放物線を考えます。 3点が直線上になければ、ただ一つの放物線が定まると思います。 x=x2 を対称軸と仮定すれば、 a(x-x2)^2+y-y2=0 が放物線の式になります。 回転を考慮し、c^2+s^2=1 の変数を加えて書きなおせば、 a(cx-sy-cx2+sy2)^2+sx+cy-sx2-cy2=0 となりますが、X=x-x2, Y=y-y2 と置けば、 a(cX-sY)^2+sX+cY=0 となります。 この先、x1, y1 などを代入し、連立方程式にして解けば…と思いましたが上手くいきませんでした。