本ドキュメントは Flash 上で動作するプロジェクトにおいて、選択した関数を RAM から実行する方法を説明します。
MEMORY
{
flash_rchw : org = 0x00FA0000, len = 0x4
cpu0_reset_vec : org = 0x00FA0000+0x10, len = 0x4
cpu1_reset_vec : org = 0x00FA0000+0x14, len = 0x4
cpu2_reset_vec : org = 0x00FA0000+0x04, len = 0x4
m_my_flash : org = 0x01000000, len = 4K // optional - this is dedicated section for the RAM function rom image
m_text : org = 0x01001000, len = 5628K // default section for code
m_my_ram : org = 0x40000000, len = 4K // optional - specific section where a RAM routine(s) should be copied into
m_data : org = 0x40001000, len = 764K // default section for data/stack/heap
}SECTIONS
{
...
.MyRamCode :
{
MY_RAM_START = .; // this symbol is optional
KEEP (*(.MyRamCode)) // KEEP - avoid dead stripping if an object is not referenced
MY_RAM_END = .; // this symbol is optional
} > m_my_ram AT>m_my_flash // the section above is linked into m_my_ram and Rom image is stored into m_my_flashSECTIONS
{
...
.MyRamCode :
{
MY_RAM_START = .; // this symbol are optional
KEEP (*(.MyRamCode)) // KEEP - avoid dead stripping if an object is not referenced
MY_RAM_END = .; // this symbol are optional
} > m_data AT>m_text // the section is linked into default data memory area and its rom image is placed into the default code memory
__attribute__ ((section(".MyRamCode"))) // place the function below into .MyRamCode section
int test_RAM(int arg1) __attribute__ ((longcall)); // declare the function as "far"リンカーシンボル(.MyRamCode RAMおよびROMのアドレスとサイズ)を作成し、コピーダウンが実装されているモジュールにインポートすることができます。
__MY_RAM_ADR = ADDR (.MyRamCode);
__MY_RAM_SIZE = SIZEOF (.MyRamCode);
__MY_RAM_ROM_ADR = LOADADDR (.MyRamCode);参考実装例は次のようになります。
#include
extern unsigned long __MY_RAM_ADR;
extern unsigned long __MY_RAM_ROM_ADR;
extern unsigned long __MY_RAM_SIZE;
__attribute__ ((section(".MyRamCode"))) // place the function below into .MyRamCode section
int test_RAM(int arg1) __attribute__ ((longcall)); // declare the function as "far"
...
void main(void)
{
int counter = 0;
memcpy(&__MY_RAM_ADR , &__MY_RAM_ROM_ADR, &__MY_RAM_SIZE); // copy the function from flash to RAM
counter = test_RAM(counter); // call the function
...
} お役に立てれば幸いです!
Stan
Duke すでに存在しています。累積版の最新版は https://community.nxp.com/docs/DOC-341653 からインストールできます。
それは素晴らしいです!
この問題の公式パッチをお待ちしております。
Alexander さん、NXP S32DS サポートチームの皆さま、アップデートありがとうございます。
cmpe200gcc‑181 は S32 Design Studio for Power Architecture 2017.R1 – Update 2 に同梱されているコンパイラで修正されています。
親愛なる公爵様!
ありがとうございます。私の MPC5746C ボードでは現在問題なく動作しています。以前、m_text を 0x00FE0400 に移動した際はブートに失敗しました。
フォルケルトと同様に、
ecrti.o だけを修正すれば十分でした(私の場合)。
コードをトレースできれば、どの部分に問題があるのかがわかります。
前述したように、もしそのコードが 4 バイト境界に整列していない場合は――
おそらく、同じ手順でコードを修正できるはずです。
または、逆アセンブルされたコードに問題点を投稿してください。
幸運を祈ります。
親愛なる公爵様!
ありがとうございました。これは助けになりそうです!(MPC5745Rを使用して)
よろしくお願いします。Folkert
同じ問題に遭遇しましたが、解決されましたか。
私の回避策は `ELe200/src_gcc/libgcc/config/rs6000/eabivle-ci.S` を編集し、`__init` 関数に `se_nop` を挿入して VLE では暗黙でない 4 バイト境界を強制する方法でした(BookE では自動で挿入されます)。
/* Head of __init function used for static constructors. */
#ifdef __VLE__
.section ".init","axv"
#else
.section ".init","ax"
#endif
.align 2
FUNC_START(__init)
#ifdef __VLE__
e_stwu 1,-16(1)
se_mflr 0
se_nop
e_stw 0,20(1)
#else
stwu 1,-16(1)
mflr 0
stw 0,20(1)
#endif
この回避策を適用するにはコンパイラを再ビルドする必要があります。
敬具
エルカー
皆さん、こんにちは。
この問題を報告していただき、ありがとうございます!
本件は e200 GCC リンカーの不具合(ID: CMPE200GCC‑181)であり、現在コンパイラチームが調査中です。
これは ARM gcc (S32DS for ARM) で正常に動作します。
進捗状況については、随時お知らせいたします。
ありがとうございます!
Stan
問題は解決されましたか。ご指摘のとおりかもしれません。これを回避するにはどうすればよいでしょうか。
S32 Studio for PowerPC v1.2 でも同じ問題が発生しました。さらに簡単に再現する方法を以下に示します。
- 新しいプロジェクト >> MPC5674F
- ライブラリ NewLib Nano を選択
- main.c に RAM 関数を追加しました。
- .ramfuncs を追加- input セクションを .dataセクションにマッピング(初期化時にコピーされます)
main.c:
#include "derivative.h" /* include peripheral declarations */
extern void xcptn_xmpl(void);
int counter = 0;
#define RAMFUNC __attribute__ ((longcall, section(".ramfuncs")))
RAMFUNC void ramcall(void) {
counter+=2;
}
int main(void) {
xcptn_xmpl ();
for(;;) {
counter++;
ramcall();
}
}
56xx_flash.ld
....
.data :
{
*(.data)
*(.data.*)
*(.ramfuncs)
} > m_data AT>m_text
...
メインエントリポイントで逆アセンブリが生成されました (main >> __eabi >> __init)
00004438 <__init>:
4438: 18 21 06 f0 e_stwu r1,-16(r1)
443c: 00 80 se_mflr r0
443e: 54 01 00 14 e_stw r0,20(r1)
4442: 00 00 se_illegal
4444: 79 ff fc ad e_bl 40f0
4448: 79 ff fd b9 e_bl 4200 <__do_global_ctors_aux>
444c: 50 01 00 14 e_lwz r0,20(r1)
4450: 00 90 se_mtlr r0
4452: 20 f1 se_addi r1,16
4454: 00 04 se_blr
4456: 50 01 18 21 e_lwz r0,0(r1)
ロングコールが init トランポリンでアラインメント不良を引き起こすことが確認されています。この問題は Debug/Release(Flash)ターゲットの双方で再現し、Debug_RAM ではコードが既に RAM 上にあるため発生しません。
お役に立てれば幸いです。