将IAR stm32f2 / f4 flash中的函数复制到ram并运行它

时间:2016-07-09 06:45:49

标签: stm32 iar cortex-m3 stm32f4

我想将一个函数从Flash复制到RAM并运行它。

我知道IAR包含__ramfunc类型的函数,允许你在RAM中定义一个函数,但我不想使用它有两个原因:

  • RAM funcs正在使用我只在初始化时使用的RAM内存
  • 升级2次代码后(我正在进行固件更新系统)__ramfunc给我一个错误的位置。

基本上我想要的是将函数声明为flash,然后在运行时将其复制到内存并运行它。我有下一个代码:

   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不起作用
  • 链接器返回错误的函数地址(奇数地址)。检查调试工具我注意到它是错误的,这就是我做&amp; 0xFFFFFFFE的原因。

在此代码之后,该函数完全复制到RAM,完全相同的代码,但是当我运行它时:

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

我得到一个异常HardFault_Handler。经过大量的测试后,我无法解决这个难以解决的异常问题。

检查asm代码我注意到对__ramfunc和普通flash函数的调用是不同的,也许是获得HardFault异常的原因。

这是在定义为flash时调用的方式:

   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跳到RAM并且它可能是皮质保护但是当使用__ramfunc修饰符时我也正是这样做,并且一步一步调试,它不会跳转到RAM中的函数,一旦调用函数就直接跳转到异常。

跳过这个的方法是对RAM内存的“转向”。我尝试在C中混合使用C和ASM以及asm(“...”)函数,但是会出现错误,并且可能会遇到硬故障异常。

任何提示都会受到欢迎。

1 个答案:

答案 0 :(得分:0)

ptr是EVEN地址,处理器要做的第一件事是FAULT,你必须跳转到一个ODD地址,表明它是16位Thumb代码,而不是32位ARM代码。

这也是问题here,但由于它引用了BOARD,所以不容易找到。感谢imbearr找到它。

Here in official stm32论坛,您可以找到有关此内容的更多信息