stm32 bootloader

#include "stm32f10x.h"

#include "Iwdg_hard_dri.h"

#include "Flash_module.h"

#include "Printf.h"

#include <string.h>

#include <stdio.h>



 u8   M3_UPDATA_SUCESS[20] ="SUCCESS_UPDATA_M3APP";


 u8   RtoWbuf[PAGE_SIZE];

 u16  Page_nu;

 u16  Byte_nu;




void MYRCC_DeInit(void)

{


  RCC->APB1RSTR = 0x00000000;//復位結束  

RCC->APB2RSTR = 0x00000000; 

 

  RCC->AHBENR = 0x00000014;  //睡眠模式閃存和SRAM時鐘使能.其他關閉.  

  RCC->APB2ENR = 0x00000000; //外設時鐘關閉.   

  RCC->APB1ENR = 0x00000000;   

RCC->CR |= 0x00000001;     //使能內部高速時鐘HSION  

RCC->CFGR &= 0xF8FF0000;   //復位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]  

RCC->CR &= 0xFEF6FFFF;     //復位HSEON,CSSON,PLLON

RCC->CR &= 0xFFFBFFFF;     //復位HSEBYP    

RCC->CFGR &= 0xFF80FFFF;   //復位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE 

RCC->CIR = 0x00000000;     //關閉所有中斷  

//配置向量表  


}




int   AppProgramRun(void)

{



    u32    AppSpInitVal;           //App程序的SP初值.

    u32    AppJumpAddr;            //APP程序的跳轉地址.即,APP程序的入口.

    void    (*pAppFun)(void);       //定義一個函數指針.用於指向APP程序入口.



    AppSpInitVal = *(u32 *)RUN_M3APP_ADDR_START;             //取APP的SP初值.

    if (AppSpInitVal & 0XFFFF0000 != 0X20000000)    //APP未寫入.不能跳.

    {

   //     FaceEnterDialog (&OpFailDialog);

       return  1;

    }


    AppJumpAddr = *( u32 *)(RUN_M3APP_ADDR_START + 4);        //取程序入口.

    if ((AppJumpAddr & 0Xfff80000) != 0X08000000)   //APP無效.不能跳.

    {

      //  FaceEnterDialog (&OpFailDialog);

        return  2;

    }

    

    MYRCC_DeInit();                                 //恢復NVIC爲復位狀態.使中斷不再發生.  

  //__MSR_MSP(AppSpInitVal);                         //設置SP.

   

__set_MSP(AppSpInitVal);  

    pAppFun = (void (*)(void))AppJumpAddr;          //生成跳轉函數.

    (*pAppFun)();                                  //跳轉.不再返回.


    return 0;


}





void Stm32_Clock_Init(u8 PLL)

{

unsigned char temp=0;   

// MYRCC_DeInit();  //復位並配置向量表

  RCC->CR|=0x00010000;  //外部高速時鐘使能HSEON

while(!(RCC->CR>>17));//等待外部時鐘就緒

RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;

PLL-=2;//抵消2個單位

RCC->CFGR|=PLL<<18;   //設置PLL值 2~16

RCC->CFGR|=1<<16;  //PLLSRC ON 

FLASH->ACR|=0x32;  //FLASH 2個延時週期


RCC->CR|=0x01000000;  //PLLON

while(!(RCC->CR>>25));//等待PLL鎖定

RCC->CFGR|=0x00000002;//PLL作爲系統時鐘  

while(temp!=0x02)     //等待PLL作爲系統時鐘設置成功

{   

temp=RCC->CFGR>>2;

temp&=0x03;

}    

}    



int main(void)

{


u16 buf[2];

u32 BACK_M3ADDR;

u32 RUN_M3ADDR;

u16  i;



MYRCC_DeInit();     

NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x0); //復位向量表

Stm32_Clock_Init(9);       //初始化時鐘  72mhz

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶佔優先級,2位響應優先級





Printf_Debug_Init(UART_Thou);   //初始化調試口串口4


//初始化看門狗4s

IWDG_Init(6,625); 


  printf("now is in bootloader \r\n");






#if 1

if(memcmp((u32*)ARMAPP_upstatus,"UPDATA_M3_APP",strlen("UPDATA_M3_APP")) == 0)

{


// printf("no updatastatus ,go to app\r\n");


//喂狗

IWDG_Feed();


STMFLASH_ReadHalfWord_buf(BACK_M3APP_ADDR_START -4 ,  buf, 2);


Page_nu =  buf[0];

Byte_nu = buf[1];


BACK_M3ADDR = BACK_M3APP_ADDR_START;

RUN_M3ADDR = RUN_M3APP_ADDR_START;




printf(" Page_nu is %d\r\n", Page_nu);

printf(" Byte_nu is %d\r\n", Byte_nu);


if(Page_nu > 0)

{

for(i = 0;i<Page_nu;i++)

{



STMFLASH_ReadByte_buf(BACK_M3ADDR, RtoWbuf,PAGE_SIZE);

STMFLASH_WriteByte_buf(RUN_M3ADDR , RtoWbuf , PAGE_SIZE);


BACK_M3ADDR += PAGE_SIZE;

RUN_M3ADDR += PAGE_SIZE;

}

}


STMFLASH_ReadByte_buf(BACK_M3ADDR, RtoWbuf,Byte_nu);

STMFLASH_WriteByte_buf(RUN_M3ADDR , RtoWbuf ,Byte_nu);




//寫上升級完成標誌位

STMFLASH_WriteByte_buf(ARMAPP_upstatus ,M3_UPDATA_SUCESS , strlen(M3_UPDATA_SUCESS ));


NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x00010000); //設置APP的向量表


AppProgramRun();



}

else

{


//喂狗

IWDG_Feed();

printf("no updatastatus ,go to app\r\n");

NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x00010000); //設置APP的向量表


AppProgramRun();

}


#endif



}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章