| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- #include "onechip_include_header.h"
- // 用户数据存储地址——选择Flash末尾区域,避免覆盖程序代码
- // STM32F103RE Flash: 0x08000000 ~ 0x0807FFFF (512KB)
- #define CFG_PARAM_START_ADDR 0x0807F800 // 最后1页(2KB)起始地址
- #define onechip_name "Onechip602"
- #define onechip_pswd "onechip1003"
- #define onechip_IP "192.168.1.10"
- #define onechip_PORT "8003"
- #define default_SN "2603001"
- /**
- * @brief 从指定Flash地址读取32位数据
- */
- uint32_t Flash_ReadWord(uint32_t address)
- {
- return *(__IO uint32_t*)address;
- }
- /**
- * @brief 从指定Flash地址读取16位数据
- */
- uint16_t Flash_ReadHalfWord(uint32_t address)
- {
- return *(__IO uint16_t*)address;
- }
- /**
- * @brief 向Flash写入16位数据(半字)
- * @param address 目标地址(必须为偶数,2字节对齐)
- * @param data 要写入的数据(16位)
- * @retval HAL_OK 成功,否则失败
- */
- HAL_StatusTypeDef Flash_WriteHalfWord(uint32_t address, uint16_t data)
- {
- HAL_StatusTypeDef status = HAL_ERROR;
-
- // 1. 解锁Flash
- HAL_FLASH_Unlock();
-
- // 2. 写入半字数据
- status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, data);
-
- // 3. 锁定Flash
- HAL_FLASH_Lock();
-
- return status;
- }
- /**
- * @brief 向Flash写入32位数据(字)
- * @param address 目标地址(必须为4字节对齐)
- * @param data 要写入的数据(32位)
- */
- HAL_StatusTypeDef Flash_WriteWord(uint32_t address, uint32_t data)
- {
- HAL_StatusTypeDef status = HAL_ERROR;
-
- HAL_FLASH_Unlock();
- status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data);
- HAL_FLASH_Lock();
-
- return status;
- }
- /**
- * @brief 擦除指定Flash页
- * @param page_address 页起始地址(必须是页边界对齐)
- */
- HAL_StatusTypeDef Flash_ErasePage(uint32_t page_address)
- {
- HAL_StatusTypeDef status = HAL_ERROR;
- FLASH_EraseInitTypeDef EraseInitStruct;
- uint32_t PageError = 0;
-
- // 计算页号
- // uint32_t page_num = (page_address - FLASH_BASE) / FLASH_PAGE_SIZE;
-
- HAL_FLASH_Unlock();
-
- EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
- EraseInitStruct.PageAddress = page_address;
- EraseInitStruct.NbPages = 1;
-
- status = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
-
- HAL_FLASH_Lock();
-
- return status;
- }
- /**
- * @brief 向Flash写入多个半字数据(自动处理擦除)
- * @param start_addr 起始地址
- * @param pBuffer 数据缓冲区
- * @param NumToWrite 要写入的半字数量
- */
- void Flash_WriteBuffer(uint32_t start_addr, uint8_t *pBuffer, uint32_t NumToWrite)
- {
- // 1. 擦除目标页
- uint32_t page_start = start_addr - (start_addr % FLASH_PAGE_SIZE);
- Flash_ErasePage(page_start);
-
- // 2. 依次写入每个半字
- for (uint32_t i = 0; i < NumToWrite; i=i+4) {
- Flash_WriteWord(start_addr + i, *(uint32_t *)(pBuffer+i));
- }
- }
- /**
- * @brief 向Flash写入多个半字数据(自动处理擦除)
- * @param start_addr 起始地址
- * @param pBuffer 数据缓冲区
- * @param NumToWrite 要写入的半字数量
- */
- void Flash_ReadBuffer(uint32_t start_addr, uint8_t *pBuffer, uint32_t NumToWrite){
-
- for (uint32_t i = 0; i < NumToWrite; i=i+4) {
- *(uint32_t *)(pBuffer+i) = *(__IO uint32_t*)(start_addr + i);
- }
- }
- /********************************************************************
- * checksum_calc()
- *
- *描述:接收数据checksum计算
- *参数:pdata:要计算的数据
- * len:要计算的数据长度
- *返回:checksum值
- *其他:无
- *--------------------------------------------------------------------
- *记录:
- ********************************************************************/
- uint32_t checksum_calc(uint8_t *pdata, uint8_t len)
- {
- uint8_t *tmp = pdata;
- uint32_t checksum = 0;
- for(uint8_t i = 0; i < len; i++)
- {
- checksum += tmp[i];
- }
- return checksum;
- }
- /********************************************************************
- * checksum_calc()
- *
- *描述:接收数据checksum计算
- *参数:pdata:要计算的数据
- * len:要计算的数据长度
- *返回:checksum值
- *其他:无
- *--------------------------------------------------------------------
- *记录:
- ********************************************************************/
- uint32_t checksum_calc1(uint8_t *wdata, int len)
- {
- uint32_t checksum = 0;
- for(int i = 0; i < len; i++)
- {
- checksum += wdata[i];
- }
- return checksum;
- }
- /********************************************************************
- * cfg_load_default_param()
- *
- *描述:加载默认参数
- *参数:无
- *返回:无
- *其他:无
- *--------------------------------------------------------------------
- *记录:
- ********************************************************************/
- void cfg_load_default_param(void)
- {
- sysinf.lysis_offset = 0;
- sysinf.lysis_overHeat = 3;
- sysinf.lysis_overHeatTime = 10;
- sysinf.lysis_Kp = 5;
- sysinf.lysis_Ki = 0.01;
- sysinf.lysis_Kd = 0;
- sysinf.amplif_Kp = 20;
- sysinf.amplif_Ki = 0.05;
- sysinf.amplif_Kd = 0;
- sysinf.PresetTempVal = 72;
- sysinf.PresetTempTime = 5;
- sysinf.SetTempVal = 68;
- sysinf.holdTemp = 63.5;
- sysinf.PreHeatTime = 1;
- sysinf.readyTemp = 65.5;
- sysinf.adjtemp = -0.5;
- sysinf.log_level = 0;
- sysinf.skip_CheckOrRun = 0;
- sysinf.timeinner = 6000;
- sysinf.swingtime = 100;
- sysinf.swingspeed = 60;
- sysinf.swingtimeRight = 40;
- sysinf.swingtimePause = 100;
- sysinf.runLoopTime = 600;
- sysinf.runLoopSpeed = 80;
- strcpy(sysinf.wifiname, onechip_name);
- strcpy(sysinf.password, onechip_pswd);
- strcpy(sysinf.TCP_IP_Addr, onechip_IP);
- strcpy(sysinf.TCP_IP_PORT, onechip_PORT);
- memset(sysinf.SN, 0 ,sizeof(sysinf.SN));
- strcpy(sysinf.SN, default_SN);
- }
- /********************************************************************
- * cfg_param_verify()
- *
- *描述:配置参数校验
- *参数:无
- *返回:0/1:校验不通过/通过
- *其他:无
- *--------------------------------------------------------------------
- *记录:
- ********************************************************************/
- uint8_t cfg_param_verify(void)
- {
-
- unsigned char pramlen = sizeof(oneChipSysdef) - offsetof(oneChipSysdef, SN);
- uint32_t saveCrc = *(uint32_t *)(CFG_PARAM_START_ADDR + (pramlen-4));
- uint32_t calCrc = checksum_calc((uint8_t *)CFG_PARAM_START_ADDR, (pramlen-4));
- if((saveCrc == calCrc) && (saveCrc != 0xffffffff)) {
- Flash_ReadBuffer(CFG_PARAM_START_ADDR,(uint8_t *)&sysinf.SN, pramlen);
- }
- }
- /********************************************************************
- * cfg_save_cfg_param()
- *
- *描述:保存配置参数
- *参数:无
- *返回:0/1:保存失败/成功
- *其他:无
- *--------------------------------------------------------------------
- *记录:
- ********************************************************************/
- uint8_t cfg_save_cfg_param(void)
- {
- unsigned char pramlen = sizeof(oneChipSysdef) - offsetof(oneChipSysdef, SN);
- sysinf.checksum = (uint32_t)checksum_calc((uint8_t *)&sysinf.SN, (pramlen-4));
- Flash_WriteBuffer(CFG_PARAM_START_ADDR, (uint8_t *)&sysinf.SN, pramlen);
- return cfg_param_verify();
- }
- /********************************************************************
- * cfg_param_init()
- *
- *描述:配置参数初始化
- *参数:无
- *返回:0/1:初始化失败/成功
- *其他:无
- *--------------------------------------------------------------------
- *记录:
- ********************************************************************/
- uint8_t cfg_param_init(void)
- {
- uint8_t rlt = 0;
- uint32_t findSN = 1;
- Flash_ReadBuffer(CFG_PARAM_START_ADDR,(uint8_t *)&sysinf.SN, sizeof(sysinf.SN));
-
- for(unsigned i=0;i<sizeof(sysinf.SN);i++)
- {
- if((sysinf.SN[i]<'0' || sysinf.SN[i]>'9')){
- findSN = 0;
- break;
- }
- }
- if(findSN == 0){
- strcpy(sysinf.SN, default_SN);
- }
- return rlt;
- }
- /**
- * @brief 跳转到应用程序段(执行APP)
- * @param appxaddr : 应用程序的起始地址
- * @retval 无
- */
- void iap_load_app(uint32_t appxaddr)
- {
- if (((*(volatile uint32_t *)appxaddr) & 0x2FFE0000) == 0x20000000) /* 检查栈顶地址是否合法.可以放在内部SRAM共64KB(0x20000000) */
- {
- // uint32_t msp_value = *(volatile uint32_t*)appxaddr;
- // uint32_t reset_vector = *(volatile uint32_t*)(appxaddr + 4);
- // // 1. 检查栈顶地址是否在合法SRAM范围(STM32F103 64KB)
- // if ((msp_value < 0x20000000) || (msp_value > 0x2000FFFF))
- // return;
- // // 2. 检查复位向量是否为有效的Thumb地址(最低位为1)
- // if ((reset_vector & 0x1) == 0)
- // return;
- // // 3. 关闭全局中断
- // __disable_irq();
- // // 4. 关闭所有外设时钟(可选,但推荐)
- // HAL_RCC_DeInit();
- // // 5. 复位HAL库
- // HAL_DeInit();
- // // 6. 清除所有挂起的中断(清除NVIC挂起状态)
- // for (int i = 0; i < 8; i++) {
- // NVIC->ICPR[i] = 0xFFFFFFFF; // 清挂起
- // NVIC->ICER[i] = 0xFFFFFFFF; // 禁用所有中断
- // }
- // // 7. 关闭SysTick(避免其产生中断)
- // SysTick->CTRL = 0;
- // SysTick->LOAD = 0;
- // SysTick->VAL = 0;
- // // 8. 数据与指令同步屏障
- // __DSB();
- // __ISB();
- // // 9. 设置主堆栈指针
- // __set_MSP(msp_value);
- // __DSB();
- // __ISB();
- // //10. 跳转到复位地址(强制Thumb模式)
- // volatile iapfun jump2app = (iapfun)(reset_vector );
- // jump2app();
- /* 用户代码区第二个字为程序开始地址(复位地址) */
- volatile iapfun jump2app = (iapfun) * (volatile uint32_t *)(appxaddr + 4);
- // __disable_irq();
- // HAL_DeInit();
- /* 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) */
- __set_MSP(*(volatile uint32_t *)appxaddr);
-
- /* 跳转到APP */
- jump2app();
- }
- }
- /**
- * @brief IAP写入一页
- * @param appxaddr : 应用程序的起始地址
- * @param appbuf : 应用程序CODE
- * @param appsize : 应用程序大小(字节)
- * @retval 无
- */
- void iap_write_apppage(uint32_t start_addr, uint8_t *pBuffer, uint32_t appsize)
- {
-
- // 1. 擦除目标页
- uint32_t page_start = start_addr - (start_addr % FLASH_PAGE_SIZE);
- if(start_addr % FLASH_PAGE_SIZE){
- return ;
- }
- Flash_ErasePage(start_addr);
-
- // 2. 依次写入每个半字
- for (uint32_t i = 0; i < appsize; i=i+4) {
- Flash_WriteWord(start_addr + i, *(uint32_t *)(pBuffer+i));
- }
- }
- int app_image_copy(uint32_t src,uint32_t dst,uint32_t page_size,uint32_t len)
- {
- uint32_t src_addr = src;
- uint32_t dst_addr = dst;
- uint32_t errorTime = 0;
- uint32_t remain_size = len;
- uint8_t *pBuffer;
- Van_Device_Printf(VAN_LOG_ALLPRINT, "cope app from:%x to:%x size:%x\n\r",src_addr,dst_addr,remain_size);
- while (remain_size > 0) {
-
- Refresh_IWDG();
- iap_write_apppage(dst_addr, (uint8_t *)src_addr, page_size);
- Van_Device_Printf(VAN_LOG_ALLPRINT, "cope app from:%x to:%x size:%x\n\r",src_addr,dst_addr,remain_size);
- /* 验证写入是否正确(可选) */
- for (uint32_t i = 0; i < page_size; i=i+4) {
- if (*(uint32_t *)(dst_addr + i) != *(uint32_t *)(src_addr + i)) {
- errorTime++;
- if(errorTime > FLASH_APP_COPY_EERTIME) {
- /*多长拷贝失败,返回失败*/
- return 0;
- Van_Device_Printf(VAN_LOG_ALLPRINT, "cope error at%x\n\r");
- }
- continue;
- }
- }
- src_addr += page_size;
- dst_addr += page_size;
- errorTime = 0;
- remain_size -= page_size;
- }
- Van_Device_Printf(VAN_LOG_ALLPRINT, "cope end..\n\r");
- return 1;
- }
- uint32_t check_main_App(void){
- if(*(uint32_t *)(FLASH_APP1_ADDR + FLASH_APP_VERSION_OFFSET) == 0xffffffff){
- if(*(uint32_t *)(FLASH_APP2_ADDR + FLASH_APP_VERSION_OFFSET) != 0xffffffff){
- Van_Device_Printf(VAN_LOG_ALLPRINT, "run flag error cope back..\n\r");
- app_image_copy(FLASH_APP2_ADDR,FLASH_APP1_ADDR,FLASH_PAGE_SIZE,FLASH_APP2_SIZE);
- }
- }
- uint32_t mps;
- uint32_t app;
- mps = (*(volatile uint32_t *)FLASH_APP1_ADDR);
- app = *(volatile uint32_t *)(FLASH_APP1_ADDR + 4);
- if ((( mps& 0x2FFE0000) != 0x20000000)||
- ((app < 0x08010000) || (app > 0x08030000))) {
- /*头非法*/
- if(*(uint32_t *)(FLASH_APP2_ADDR + FLASH_APP_VERSION_OFFSET) != 0xffffffff){
- Van_Device_Printf(VAN_LOG_ALLPRINT, "head error cope back..\n\r");
- app_image_copy(FLASH_APP2_ADDR,FLASH_APP1_ADDR,FLASH_PAGE_SIZE,FLASH_APP2_SIZE);
- }
- }
-
- mps = (*(volatile uint32_t *)FLASH_APP1_ADDR);
- app = *(volatile uint32_t *)(FLASH_APP1_ADDR + 4);
- if((*(uint32_t *)(FLASH_APP1_ADDR + FLASH_APP_VERSION_OFFSET) == 0xffffffff)||
- (( mps& 0x2FFE0000) != 0x20000000)||
- ((app < 0x08010000) || (app > 0x08030000))){
- return 0;
- }
- return 1;
- }
|