8 years, 9 months ago.

Can I execute code from SDRAM? / SDRAMに配置したコードを実行したい

I using LPC4088 QSB. I hope execute code from SDRAM, code of SDRAM it will load from SDCard.

It was decided to make a simple demo code to get started . That is copy the code of FlashRom to SDRAM, to run it . However , it HardFault occurs , did not work well .

--

LPC4088 QSB を使って開発を行っています。 SDカードからロードしたプログラムをSDRAMに配置し、そのプログラムを実行したいと考えています。

手始めに、FlashROMに書き込まれた特定の関数をSDRAMにコピーし その関数を呼び出す実験をしていますが、うまく動いていません。

リンカスクリプト

MEMORY
{
  MFlash512 (rx) : ORIGIN = 0x0, LENGTH = 0x20000 /* 128k */
  Hoge(rx) : ORIGIN = 0x20000, LENGTH = 0x20000 /* 128k */
  RamLoc64 (rwx) : ORIGIN = 0x100000E8, LENGTH = 0xFF18 /* 64k */
  RamPeriph32 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 /* 32k */
}

SECTIONS
{
  .test :
  {
    *(.Print*);
  } > Hoge
}

test.cpp

#include <stdio.h>
#include <stdarg.h>

extern "C" __attribute__((section(".Print"))) void Print(const char* format, ...) {
	va_list list;
	va_start(list, format);
	printf(format, list);
	va_end(list);
}

startup.cpp

#include "mbed.h"
#include "sdram.h"
#include "test.h"


int main()
{
  Print("hoge"); // デッドストリップされないよう呼び出す / keep code from the dead strip
  ((int (*)(const char* format, ...))(0x00020001))("fuga\r\n");
  
  sdram_init();
  memcpy((uint8_t*)0xa0100000, (uint8_t*)0x00020000, 0x400);
  ((int (*)(const char* format, ...))(0xa0100001))("piyo\r\n"); // HardFault
}

hoge and fuga in such a code has been output. But, piyo is not output, and HardFault occurs.

It was confirmed the memory using the debugger. Code on the SDRAM(0xa0100000) has been copied(from 0xa0100000).

To run the code of SDRAM is , do I need a procedure ?

--

上記のようなコードで hoge / fuga は出力されますが、 piyo は出力されずに HardFault が発生してしまいます。

デバッガ経由でメモリ上のデータを見る限りは 0x00020000 と 0xa0100000 には同じデータが配置されているように見えています。

SDRAM上のコードを実行するにはなにか手続きなどが必要なのでしょうか?

途中経過の報告です。(まだ動いていません)

sdram_init(); のあとで呼び出す mpu_init() を定義しました。

定数など、実装は https://code.csdn.net/RT-Thread/realboard4088/blob/master/software/rtthread_examples/drivers/drv_mpu.c こちらを参考にしています。

手始めにSDRAMを読み書き禁止にして、memcpy が失敗することを確認しました。

MemManage Fault

void mpu_init(void)
{
    MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;

    MPU->RNR = 0;
    MPU->RBAR = 0xA0000000;
    MPU->RASR = MPU_RASR_ACCESS_PERMISSION(0)
                | MPU_RASR_REGION_SIZE(MPU_REGION_SIZE_32MB)
                | MPU_REGION_ENABLE;

    SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
    MPU->CTRL |= MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk;
}

MPU_RASR_ACCESS_PERMISSION(0) を指定することで、memcpy 時に MemManage Fault が発生するようになりました。 これで MPU の制御はできている気がします。

続けて、こちらを書き込みできる状態にします。そして、RASRの28ビット目のNXフラグを落とした状態で実行可能領域と定義します。

Hard Fault

void mpu_init(void)
{
    MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;

    MPU->RNR = 0;
    MPU->RBAR = 0xA0000000;
    MPU->RASR = MPU_RASR_ACCESS_PERMISSION(MPU_FULL_ACCESS)
                | MPU_RASR_REGION_SIZE(MPU_REGION_SIZE_32MB)
                | MPU_REGION_ENABLE;

    SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
    MPU->CTRL |= MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk;
}

memcpy は通るようになりましたが、相変わらず ((int (*)(const char* format, ...))(0xa0100001))("piyo\r\n"); で Hard Fault が発生しています。

この状況に心当たりのある方、いらっしゃいませんでしょうか。

posted by Kazutomo Niwa 19 Jul 2015

Print の実装がダメだっただけで、

test.cpp

#include <stdio.h>
#include <stdarg.h>

extern "C" __attribute__((section(".Print"))) int Print(const char* format, ...) {
  return 10;
}

のような実装にしたところ SDRAMにコピーしたコードを実行しても10の戻り値を得ることが出来ました。

とりあえず、SDRAM上のコードを実行するという点は実現できているように見えるので解決とします。

posted by Kazutomo Niwa 19 Jul 2015

1 Answer

8 years, 9 months ago.

こんばんは。

LPC4088のUMを見たところ、Chapter 9: EMC, 9.2 Basic configurationに以下の記述がありました。

MPU: Default memory space permissions for the CPU do not allow program execution from the address range that includes the dynamic memory chip selects. These permissions can be changed by programming the MPU (see the ARM Cortex-M4 User Guide referred to in Section 40.1 for details of MPU operation.

Accepted Answer

情報有り難うございます!完全に見落としていました。

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/Cihjddef.html

この辺りを参考にコードを書いていますが、まだ動くようになっていないので動くようになったら改めてコメントします。

posted by Kazutomo Niwa 19 Jul 2015