浅谈嵌入式MCU软件开发之将应用程序代码重定向到系统栈(stack)上运行的实现原理和方法详解
内容提要

小端内核, 栈(stack)向下(低地址)生长,比如ARM Cotrex-M系列CPU内核;
大端内核, 栈(stack)向上(高地址)生长,比如PowerPC e200z系列CPU内核;


有初始化值局部变量的初始化由C语言调用内置库函数(编译和链接过程决定),比如memset()自动实现;
无初始化值的局部变量,其初始值为stack原有的值,是随机的。

/* define a macro to use attribute to achieve 8 byte alignment */#define ALIGN_8B __attribute__((aligned(8)))
typedef uint32_t (*ram_fuc)(uint32_t, uint32_t );
typedef struct{ uint8_t code[0x256]; /* Structure required to copy code to ram memory */ /* Size of this structure needs to be at least (but best) the size of the FnCmdInRam_ */} FnCmdInRamStruct;
uint32_t ALIGN_8B Math_Func(uint32_t a, uint32_t b){ uint32_t result = 0; result = (a *b 10) * (a b) *(a - b);
return result;}int main(void){ /* Write your code here */
uint32_t aa = 100; uint32_t bb = 36;
uint32_t cc = 0;
/* Create a copy of the function codes in RAM routine on stack */ FnCmdInRamStruct ALIGN_8B FnCmdInRam = *(FnCmdInRamStruct *)((uint32_t)Math_Func-1);
/* run the function via a function pointer */ cc = ((ram_fuc)((uint32_t)&FnCmdInRam 1))(aa,bb);
if(cc>100) { aa = Math_Func(bb,cc); } else { aa = Math_Func(cc,cc); }
for(;;) { if(exit_code != 0) { break; } } return exit_code;}/* Create a copy of the function codes in RAM routine on stack */FnCmdInRamStruct ALIGN_8B FnCmdInRam = *(FnCmdInRamStruct *)((uint32_t)Math_Func-1);
/* run the function via a function pointer */cc = ((ram_fuc)((uint32_t)&FnCmdInRam 1))(aa,bb);
#include 'MPC5644A.h'typedef unsigned char BOOL;typedef signed char INT8;typedef unsigned char UINT8;typedef volatile signed char VINT8;typedef volatile unsigned char VUINT8;typedef signed short INT16;typedef unsigned short UINT16;typedef volatile signed short VINT16;typedef volatile unsigned short VUINT16;typedef signed long INT32;typedef unsigned long UINT32;typedef volatile signed long VINT32;typedef volatile unsigned long VUINT32;#define FLASH_A_FMC 0xC3F88000#define FLASH_B_FMC 0xC3F8C000#define FLASH_PFB_CR 0x0000001CU /* PFBIU Configuration Register for port 0 */#define FLASH_PFB_CR_BFEN 0x00000001U /* PFBIU Line Read Buffers Enable *//* Read and write macros */#define WRITE8(address, value) (*(VUINT8*)(address) = (value))#define READ8(address) ((UINT8)(*(VUINT8*)(address)))#define SET8(address, value) (*(VUINT8*)(address) |= (value))#define CLEAR8(address, value) (*(VUINT8*)(address) &= ~(value))#define WRITE16(address, value) (*(VUINT16*)(address) = (value))#define READ16(address) ((UINT16)(*(VUINT16*)(address)))#define SET16(address, value) (*(VUINT16*)(address) |= (value))#define CLEAR16(address, value) (*(VUINT16*)(address) &= ~(value))#define WRITE32(address, value) (*(VUINT32*)(address) = (value))#define READ32(address) ((UINT32)(*(VUINT32*)(address)))#define SET32(address, value) (*(VUINT32*)(address) |= (value))#define CLEAR32(address, value) (*(VUINT32*)(address) &= ~(value))/*************************************************************** Disable Flash Cache ****************************************************************/void DisableFlashControllerCache(UINT32 *origin_pflash_pfcr1,UINT32 *origin_pflash_pfcr2);/****************************************************************** Restore configuration register of FCM *******************************************************************/void RestoreFlashControllerCache(UINT32 pflash_pfcr1,UINT32 pflash_pfcr2);/* function pointer definition of the relocated function prototype */typedef UINT32 (*ram_fuc_DisableFlashControllerCache)(UINT32 *, UINT32 * );typedef UINT32 (*ram_fuc_RestoreFlashControllerCache)(UINT32, UINT32 );typedef struct{UINT8 code[0x256]; /* Structure required to copy code to ram memory *//* Size of this structure needs to be at least (but best) the size of the FnCmdInRam_ */} FnCmdInRamStruct;/*************************************************************** Disable Flash Cache ****************************************************************/void DisableFlashControllerCache(UINT32 *origin_pflash_pfcr1,UINT32 *origin_pflash_pfcr2){/* disable the CPU core global interrupt to avoid Flash access during the configuration */asm('wrteei 0');/* Read the values of PFB_CR*/*origin_pflash_pfcr1 = READ32(FLASH_A_FMC FLASH_PFB_CR);*origin_pflash_pfcr2 = READ32(FLASH_B_FMC FLASH_PFB_CR);/* Disable Caches */CLEAR32(FLASH_A_FMC FLASH_PFB_CR, FLASH_PFB_CR_BFEN);CLEAR32(FLASH_B_FMC FLASH_PFB_CR, FLASH_PFB_CR_BFEN);/* re-enable the CPU core global interrupt */asm('wrteei 1');}/****************************************************************** Restore configuration register of FCM *******************************************************************/void RestoreFlashControllerCache(UINT32 pflash_pfcr1,UINT32 pflash_pfcr2){/* disable the CPU core global interrupt to avoid Flash access during the configuration */asm('wrteei 0');WRITE32(FLASH_A_FMC FLASH_PFB_CR, pflash_pfcr1);WRITE32(FLASH_B_FMC FLASH_PFB_CR, pflash_pfcr2);/* re-enable the CPU core global interrupt */asm('wrteei 1');}/*****************************************************************Main function******************************************************************/void main(void){UINT32 pflash_pfcr1, pflash_pfcr2;/* structure used for stack RAM code run */FnCmdInRamStruct FnCmdInRam;/* Create a copy of the function codes in RAM routine on stack */FnCmdInRam = *(FnCmdInRamStruct *)((UINT32)DisableFlashControllerCache);((ram_fuc_DisableFlashControllerCache)(&FnCmdInRam))(&pflash_pfcr1,&pflash_pfcr2);/* Create a copy of the function codes in RAM routine on stack */FnCmdInRam = *(FnCmdInRamStruct *)((UINT32)RestoreFlashControllerCache);((ram_fuc_RestoreFlashControllerCache)(&FnCmdInRam))(pflash_pfcr1,pflash_pfcr2);while(1){;}}

赞 (0)
