2016-07-09 7 views
0

Я хочу скопировать функцию из Flash в RAM и запустить ее.Функция копирования из IAR stm32f2/f4 flash, чтобы запустить и запустить его

Я знаю, что IAR включает в себя тип __ramfunc для функций, позволяет определить функцию в памяти, но я не хочу, чтобы использовать его по 2 причинам:

  • RAM funcs используют оперативную память, что я использую только при инициализации
  • После обновления в 2 раза кода (я делаю систему обновления прошивки) __ramfunc дает мне неправильное местоположение.

В принципе, я хочу объявить функцию как флэш, а затем во время выполнения скопировать ее в память и запустить. У меня есть следующий код:

void (*ptr)(int size); 
    ptr=(void (*)(int size))&CurrentFont; 
    memset((char *) ptr,0xFF,4096); 
    Debugprintf("FLASH FUNC %X",GrabarFirmware); 
    Debugprintf("RAM FUNC %X",ptr); 
    char *ptr1=(char *)ptr,*ptr2=(char *)GrabarFirmware; 
    //Be sure that alignment is right 
    unsigned int p=(int)ptr2; 
    p&=0xFFFFFFFE; 
    ptr2=(char *)p; 
    for(int i=0;i<4096;i++,ptr1++,ptr2++) 
     *ptr1=*ptr2; 

    FLASH_Unlock(); 
    // Clear pending flags (if any) 
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |  FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); 
    ptr(*((unsigned int *)(tempptrb+8))); 

как детали:

  • SIZEOF из функции не работает
  • линкера вернул меня неправильные функции адреса (нечетные адреса). Проверка с помощью инструментов отладки я заметил, что это было неправильно, поэтому я делаю & 0xFFFFFFFE.

После этого кода функция отлично копируется в оперативную память, точно такой же код, но когда я запускаю его с этим:

ptr(*((unsigned int *)(tempptrb+8))); 

я получаю исключение HardFault_Handler. После многих тестов я не смог исправить это исключение hardfault.

Проверка кода asm Я заметил, что вызовы __ramfunc и обычных функций флэш-памяти различны и могут быть причиной получения исключения HardFault.

Это путь, который вызывается, когда определено как вспышка:

4782    ptr(*((unsigned int *)(tempptrb+8))); 
    \ 000000C6 0x6820    LDR  R0,[R4, #+0] 
    \ 000000C8 0x6880    LDR  R0,[R0, #+8] 
    \ 000000CA 0x47A8    BLX  R5 
    4783    //(*ptr)(); 

Теперь, если я взываю это определить код как __ramfunc и непосредственно я называю его:

4786    GrabarFirmware(*((unsigned int *)(tempptrb+8))); 
    \ 0000007A 0x6820    LDR  R0,[R4, #+0] 
    \ 0000007C 0x6880    LDR  R0,[R0, #+8] 
    \ 0000007E 0x.... 0x....  BL  GrabarFirmware 

Причина исключения, вероятно, в том, что я перескакиваю из Flash в ОЗУ и, вероятно, это защита от коры, но при использовании модификатора __ramfunc я делаю то же самое и отлаживаю шаг за шагом, он не перескакивает на функцию в RAM, сразу переходит к исключению, как только я вызываю f соборование.

Способ пропустить это будет «перейти» в оперативную память. Я пробовал смешивать C и ASM в C с функцией asm ("..."), но получать ошибки, и, вероятно, я бы получил исключение hardfault.

Любой отзыв будет приветствоваться.

+0

Почему вы голосуете это негатив? :( – hamboy75

+1

Вы пытались найти решенные вопросы по своей теме? Я нашел их много! Я думаю, [этот] (http://stackoverflow.com/questions/19756974/iap-on-lpc-1768) может помогите вам решить проблему. – imbearr

+0

Можете ли вы создать ответ ... нелегко найти этот пост, потому что не по теме, а не по телу, другому компилятору и разному микро (аналогичное ядро ​​... да) ... просто создайте ответ с ссылкой на другой вопрос, и я приму его в качестве ответа. Спасибо за вашу помощь. – hamboy75

ответ

0

ptr был адресом EVEN, первым делом процессор должен сделать FAULT, вы должны перейти к адресу ODD, чтобы указать, что это 16-битный код Thumb, а не 32-битный код ARM.

проблема была here тоже, но нелегко найти, так как она сделала ссылку на BOARD. Благодаря imbearr для его поиска.

Here in official STM32 форумах вы можете найти более подробную информацию об этом

+0

** (1) ** Полезные комментарии могут быть отмечены соответствующим флагом. ** (2) ** Вы можете отметить этот ответ как правильный. – imbearr