문제

I am trying to use IAP (in application programming) to copy the code of a function from one point in memory space to another (I know this doesn't have any use, but this is absolutely crucial for a project that I'm working on). The copying of the code seems to work with out a hitch, but when I call the copied function it always results in hardfaults. The function I'm copying doesn't have any references to other functions or data (It is a simple return function), so there is no problem of relative address errors. I've given my code below along with the output that I get.

#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) {


    }
}

Here is the output:

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

I think I'm doing something wrong in calling the function. Can someone please point out my mistake?

Thanks

도움이 되었습니까?

해결책

You forgot to set the thumb bit in the function address:

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

The compiler knows to set this in most cases, but it not in a direct cast to a function pointer.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top