浅谈嵌入式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)