#define FLASH_APP_ADDR 0x08005000
#define STM_PAGE_SIZE 1024
typedef void (*fun)(void); //定义一个函数类型的参数.
fun AppStart;
//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(INT32U addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}
////////////SD卡读,写FLASH,跳转
void SD_ReadWord(void)
{
TurnToSD();//SPI初始化
MMC_SELECT(); //SPI 有效
FirmwareUpdate(); //写FLASH
TIM_Cmd(TIM2, DISABLE); //关串口中断
Jump2App(FLASH_APP_ADDR); //跳转
TIM_Cmd(TIM2, ENABLE); //开中断
MMC_DESELECT(); //SPI 失效
}
/////////任务函数
void vTask_SdCard(void *pvParameters)
{
for(;;)
{
SD_ReadWord();
}
}
/////////////////////主函数
int main(void)
{
prvSetupHardware();
xTaskCreate(vTask_SdCard,( signed char * )"vTask_SdCard",1024,NULL,1,NULL);
vTaskStartScheduler();
}
/////////////跳转函数
void Jump2App(INT32U Addr)
{
if(((*(vu32*)Addr)&0x2FFE0000) == 0x20000000) //检查栈顶地址是否合法.
{
AppStart = (fun)(*(vu32*)(Addr+4)); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)Addr);
AppStart(); //跳转到APP.
}
}
////////读SD 写FLASH
void FirmwareUpdate(void)
{
INT16U PageOffest = 0;
INT16U ByteOffest;
f_mount(0, &Fs);
res = f_open(&file, "CoinCar.bin", FA_OPEN_EXISTING | FA_READ);
if(FR_OK != res) return;
while(1)
{
res = f_read(&file, buffer, STM_PAGE_SIZE, &br);
if (res || br == 0) break;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(FLASH_APP_ADDR + PageOffest);
for(ByteOffest = 0; ByteOffest < STM_PAGE_SIZE; ByteOffest += 2)
{
FLASH_ProgramHalfWord(FLASH_APP_ADDR + PageOffest + ByteOffest, *(u16*)(buffer + ByteOffest));
}
FLASH_Lock();
PageOffest += STM_PAGE_SIZE;
}
f_close(&file);
f_mount(0, 0);
}
|