1

IAP (アプリケーション プログラミング) を使用して、関数のコードをメモリ空間のあるポイントから別のポイントにコピーしようとしています (これが役に立たないことはわかっていますが、これは私が取り組んでいるプロジェクトにとって非常に重要です)の上)。コードのコピーは問題なく動作するように見えますが、コピーされた関数を呼び出すと、常にハードフォールトが発生します。私がコピーしている関数は、他の関数やデータへの参照を持たない (単純な戻り関数です) ので、相対アドレス エラーの問題はありません。得られる出力とともに、以下にコードを示します。

#include "mbed.h"
#include "IAP.h"

#define TARGET_SECTOR       14


char code[1024];
IAP     iap;
char val = 0;


typedef int (*function) ();
function blinkfunction;

MPU_Type mpu;


extern "C"
void HardFault_Handler() {
    register unsigned int _msp __asm("msp");
    printf("Hard Fault! %x (%x)\r\n", SCB->HFSR, *((unsigned int *)(_msp + 24)));
    printf("HFSR: 0x%X\n\r", SCB->HFSR);
    printf("MMFAR: 0x%X\tMMFSR: 0x%X\n\r", SCB->MMFAR, SCB->CFSR);
    printf("BFAR: 0x%X\tBFSR: 0x%X\n\r", SCB->BFAR, SCB->CFSR);
    printf(" - %x\r\n", (*(volatile uint32_t*)0xe000ed24));
//    printf("Hard Fault! %x\r\n", SCB->HFSR);

        printf("*********** MPU Settings *************\n\r");
        printf("TYPE: 0x%X\n\r", mpu.TYPE);
        printf("CTRL: 0x%X\n\r", mpu.CTRL);
    exit(-1);
}




int blink() {
    int a = 1, b = 1;
    return a + b;
}



void copy_code_ram() {

    char *charptr;

    charptr = (char *)&blink;
    int i;
    for(i = 0; i <200 ; i++) {
        code[i] = *charptr;
        charptr++;
    }
}    



void print_function(char *ptr, int num) {
    for(; num > 0; num--) {
        printf("0x%X  ", *ptr);
        ptr++;
    }
}


int main() {
    int r;

    printf("blink code:\n");
    print_function((char *)&blink, 100);


    printf("\n\r\n\r\n\r");
    copy_code_ram();

    //Print sector  
    print_function(sector_start_adress[TARGET_SECTOR], 100);
    printf("\n\r\n\r\n\r");

    iap.prepare( TARGET_SECTOR, TARGET_SECTOR);
    iap.erase (TARGET_SECTOR, TARGET_SECTOR);
    iap.prepare( TARGET_SECTOR, TARGET_SECTOR);
    r   = iap.write( code, sector_start_adress[TARGET_SECTOR], 256);

    printf("\n\r\n\r\n\r");
    printf( "copied: SRAM(0x%08X)->Flash(0x%08X) for %d bytes. (result=0x%08X)\r\n", code, sector_start_adress[ TARGET_SECTOR ], 1024, r );
    printf("\n\r\n\r\n\r");

    blinkfunction = (function) (sector_start_adress[TARGET_SECTOR]);

    printf("\n\r\n\r\n\r");
        print_function((char *)blinkfunction, 100);

    r = 0;
    r = blink();
    printf("The return value from blink is %d\n\r", r);

    r = blinkfunction();
    printf("The return value from blinkfunction is %d\n\r", r);

    while(1) {


    }
}

出力は次のとおりです。

Hard Fault! 4000000 (e000)
HFSR: 0x400000000
MMFAR: 0xE000ED34  MMFSR: 0x20000
BFAR: 0xE000ED38   BFSR: 0x20000

関数の呼び出しに何か問題があると思います。誰かが私の間違いを指摘できますか?

ありがとう

4

1 に答える 1

1

thumb関数アドレスにビットを設定するのを忘れました:

blinkfunction = (function) (sector_start_adress[TARGET_SECTOR] | 1);

ほとんどの場合、コンパイラはこれを設定することを認識していますが、関数ポインターへの直接キャストではありません。

于 2013-11-03T20:11:45.920 に答える