Flash_module.c



#include "stm32f10x.h"

#include "Flash_module.h"


void STMFLASH_WriteByte_buf(u32 addr , u8 *p , u16 Byte_Num)

{


u16  HalfWord;

u16  byte_nu;

      

byte_nu  = Byte_Num%2; 

Byte_Num = Byte_Num/2;    

       FLASH_Unlock();

       FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

       FLASH_ErasePage(addr);

while(Byte_Num --)

       {     

               HalfWord=*(p);

               HalfWord|=*(p+1)<<8;  

               FLASH_ProgramHalfWord(addr, HalfWord);

               addr += 2;

 p+=2;  

        }  

if( byte_nu>0)

{

HalfWord = *p;  

FLASH_ProgramHalfWord(addr, HalfWord);

 }    

       FLASH_Lock();

}


void STMFLASH_WriteHalfWord_buf(u32 addr , u16 *p , u16 Byte_Num)

{


       u16 HalfWord;

  

       FLASH_Unlock();

       FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

       FLASH_ErasePage(addr);

      while(Byte_Num --)

       {

               HalfWord=*(p++);   

               FLASH_ProgramHalfWord(addr, HalfWord);

               addr += 2;

        }

        FLASH_Lock();

}


void  STMFLASH_ReadByte_buf(u32 ReadAddr, u8 *pBuffer,u16 NumToWrite)

{


u16 i;


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

{

pBuffer[i] = (u8)(*(u32*)ReadAddr);

ReadAddr +=1;

}

}

void  STMFLASH_ReadHalfWord_buf(u32 ReadAddr, u16 *pBuffer,u16 NumToWrite)

{


u16 i;


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

{

pBuffer[i] = (u16)(*(u32*)ReadAddr);

ReadAddr +=2;

}


}


void STMFLASH_ERASEBANK(u32 bankaddr)

{


u16  i = 100;

FLASH_Unlock();

FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

FLASH_ErasePage(bankaddr);

while(i--);  

FLASH_Lock();


}


flash_module.h


#ifndef  __FASH_MODULE__

#define  __FASH_MODULE__



#include "stm32f10x.h"



#define   STM32_FLASH_BASE 0x08000000

#define   STM32_FLASH_SIZE   512   // 单位k

#define  OneKbit  1024



#define   PAGE_SIZE  2048

#define   PAGE_NU    255



#define   BOOTLOADER_ADDR_START  0x08000000



#define  RUN_M3APP_VECTABLE  0x00010000

#define  BOOTLOADER_VECTABLE  0x0



 #define  RUN_M3APP_ADDR_START  0x08010000          //  0x08010 000 --- 0x0802 8FFF

 #define  RUN_M3APP_PAGE_SIZE     ( PAGE_SIZE * 50 )

 #define  RUN_M3DAT_ADDR_START  0x08029000            //0x0802 9000---- 0X0802 B7FF

 #define  RUN_M3DAT_PAGE_SIZE     ( PAGE_SIZE * 5 )



 #define  BACK_M3APP_ADDR_START  0x0802b800          

 #define  BACK_M3APP_PAGE_SIZE     ( PAGE_SIZE * 50 )

 #define  BACK_M3DAT_ADDR_START    0x08044800          

 #define  BACK_M3DAT_PAGE_SIZE     ( PAGE_SIZE * 5 )



 #define  BACK_MCUAPP_ADDR_START  0x08047000          

 #define  BACK_MCUAPP_PAGE_SIZE     ( PAGE_SIZE * 50 )

 #define  BACK_MCUDAT_ADDR_START  0x08060000           

 #define  BACK_MCUDAT_PAGE_SIZE     ( PAGE_SIZE * 5 )



 #define  ARMAPP_upstatus    0x08062800

 #define  ARMAPP_upstatus_PAGE_SIZE     ( PAGE_SIZE *1)


 

 #define  ARMCFG_upstatus    0x08063000 

 #define  ARMCFG_upstatus_PAGE_SIZE     ( PAGE_SIZE *1)



#define   PRODUCT_ID_MAX_SIZE 5 //max size of all product device 

#define   RS485_RECE_MAX       ( PAGE_SIZE *20)



void STMFLASH_WriteByte_buf(u32  , u8 * , u16 );

void STMFLASH_WriteHalfWord_buf(u32  , u16 * , u16 );

void  STMFLASH_ReadByte_buf(u32 , u8 *,u16 );

void  STMFLASH_ReadHalfWord_buf(u32 , u16 *,u16 );

void STMFLASH_ERASEBANK(u32 );



typedef  enum RS485_UPdatetype 

{


ARMAPP,


}RS485_UPdatetype_E; 



typedef struct UpdateFilePacket_Stru

{

    u8   ucDevType; //cmd type define in UplinkCmdType_E

    u32 uiTotalLen; //total len of update file

    u32 uiLenOffset; //total len of update file

    int  uinDataPackNum;

    u8   bufProductID[PRODUCT_ID_MAX_SIZE];//product NO. + SN

    u32  uiFileNameLen; //len of update file name

    u8   pFileName[60]; //update file name

    u8    pDataBuf[RS485_RECE_MAX]; //data of file

}UpdateFilePacket_S;



typedef struct FlashW_buf

{

u8     UPdateW_buf[ PAGE_SIZE];

u16    UPdateW_Pagenu;

u16    UPdateW_Bytenu;


}upFlashW_buf;


#endif









man.c



//系统初始化

STM32APP_Init();


        ........


//初始化看门狗4s

IWDG_Init(6,625); 

//获取复位状态

Ds_GetRest();

        ..........





看下面


void STM32APP_Init(void)

{

MYRCC_DeInit();

NVIC_SetVectorTable (NVIC_VectTab_FLASH, RUN_M3APP_VECTABLE); //设置APP的向量表

Stm32_Clock_Init(Clock_72MHZ);  //72mhz

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级



}



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;     //关闭所有中断  

//配置向量表  


}

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;

}    

}

void IapProgramRun(void)


{


    u32   IapSpInitVal;           //IAP程序的SP初值.

    u32  IapJumpAddr;            //IAP程序的跳转地址.即,IAP程序的入口.

    void    (*pIapFun)(void);       //定义一个函数指针.用于指向APP程序入口.

 

    MYRCC_DeInit();                                 //恢复NVIC为复位状态.使中断不再发生.

    IapSpInitVal = *(u32 *)IAP_ADDR;             //取APP的SP初值.

    IapJumpAddr = *(u32 *)(IAP_ADDR + 4);        //取程序入口.

     __set_MSP (IapSpInitVal);                       //设置SP.

    pIapFun = (void (*)(void))IapJumpAddr;              //生成跳转函数.

    (*pIapFun) ();                                  //跳转.不再返回.



}



升级如下

Write_Data_toFlash(g_sUpdateInfo.pDataBuf ,g_sUpdateInfo.uiTotalLen ,BACK_M3APP_ADDR_START) ;

STMFLASH_WriteByte_buf(ARMAPP_upstatus ,updataM3status , strlen(updataM3status));

    STMFLASH_ReadByte_buf(ARMAPP_upstatus , debugupdata,strlen(updataM3status));

debugupdata[strlen(updataM3status)] = '\0' ;

printf("debugupdata is %s\r\n",debugupdata);

RS485_delay();

NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x0);

IapProgramRun();  //跳转向Bootloader





void  Write_Data_toFlash(u8 *File_RECEBUF ,u32 recelen ,u32 FlashAddr)

{

u8 i;

u16  pagenu;

u16  Bytenu;

u16 upadte_statue[2];

u16 buf[2];

pagenu  =    recelen /PAGE_SIZE ;

Bytenu  =    recelen % PAGE_SIZE;


upadte_statue[0] =  pagenu;

upadte_statue[1] =  Bytenu;


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

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

//喂狗

IWDG_Feed();


WFlash_buf.UPdateW_Pagenu  =  pagenu;

  WFlash_buf.UPdateW_Bytenu  =   Bytenu;



STMFLASH_WriteHalfWord_buf(FlashAddr -4  , upadte_statue , 2 );

        STMFLASH_ReadHalfWord_buf(FlashAddr -4 ,  buf, 2);



printf(" read buf[0] is %d\r\n",buf[0]);

printf(" read buf[1] is %d\r\n",buf[1]);


#if  1

if(pagenu > 0)

{


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

{

memcpy(WFlash_buf.UPdateW_buf,File_RECEBUF, PAGE_SIZE);

STMFLASH_WriteByte_buf(FlashAddr  , WFlash_buf.UPdateW_buf , PAGE_SIZE);


File_RECEBUF +=PAGE_SIZE;

FlashAddr +=PAGE_SIZE;


printf("write paegnu is %d\r\n",i);


}


}


memset(WFlash_buf.UPdateW_buf,0x00,PAGE_SIZE);

memcpy(WFlash_buf.UPdateW_buf,File_RECEBUF, Bytenu);

STMFLASH_WriteByte_buf(FlashAddr  , WFlash_buf.UPdateW_buf , Bytenu);


#endif


}



#include "stm32f10x.h"

#include "Iwdg_hard_dri.h"



//初始化独立看门狗

//prer:分频数:0~7(只有低 3 位有效!)

//分频因子=4*2^prer.但最大值只能是 256!

//rlr:重装载寄存器值:低 11 位有效.

//时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms).

//   prer 4   rlr 625   时间是1s

void IWDG_Init(u8 prer,u16 rlr) 

{

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);   //①使能对寄存器 I 写操作

IWDG_SetPrescaler(prer);   //②设置 IWDG 预分频值:设置 IWDG 预分频值

IWDG_SetReload(rlr);   //②设置 IWDG 重装载值

IWDG_ReloadCounter();   //③按照 IWDG 重装载寄存器的值重装载 IWDG 计数器

IWDG_Enable();   //④使能 IWDG

}

//喂独立看门狗

void IWDG_Feed(void)

{   

IWDG_ReloadCounter();//reload                     

}