当前位置: 首页 > news >正文

linux建设一个网站腾讯广告推广怎么做

linux建设一个网站,腾讯广告推广怎么做,自己创建平台型网站,帮做装修设计的网站文章目录前言芯片内存定义实现过程FlashDriver生成段定义擦除函数写入函数编译后的map手动测试HexView提取指定地址内容并重映射总结前言 在汽车行业控制器软件刷新流程中,一般会将Flash驱动单独进行刷写,目的是防止程序中一直存在Flash驱动的话&#x…

文章目录

    • 前言
    • 芯片内存定义
    • 实现过程
      • FlashDriver生成
        • 段定义
        • 擦除函数
        • 写入函数
        • 编译后的map
      • 手动测试
      • HexView提取指定地址内容并重映射
    • 总结

前言

在汽车行业控制器软件刷新流程中,一般会将Flash驱动单独进行刷写,目的是防止程序中一直存在Flash驱动的话,可能会造成对APP软件的异常操作,导致应用程序无法执行。本文介绍STM32F103使用KEIL生成指定FlashDriver地址的hex文件,然后使用HexView命令行提取FlashDriver及Remapping flash地址到ram地址

本文参考github,SummerFalls大神的UDS_S32K144_FlashDriver

芯片内存定义

STM32F103RCT6,flash大小256k,一个扇区2k,SRAM:48KB;

实现过程

FlashDriver生成

段定义

由于我无法直接在Keil中导出指定ram地址的hex文件,所以采用先定义指定flash地址的flash驱动,后面通过hexview实现地址重映射

keil中的内存区域定义通过分散加载文件(.sct格式)实现,如下所示

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x08000000 0x00020000  {    ; load region size_region\ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)}RW_IRAM1 0x20000800 0x0000C000  {  ; RW data.ANY (+RW +ZI)}
}
LR_IROM2 0x08020000 0x00020000  {RW_IROM_flashdrvoffset 0x08020000 0x00000008{; load address = execution address*(.NVM_Driver_Section_offset)    }RW_IROM_flashdrv 0x08020008 0x000007F8{; load address = execution address*(.NVM_Driver_Section)    }}

此处设置了两个段,NVM_Driver_Section_offset用来设置函数偏移地址,NVM_Driver_Section用来设置函数地址

增加段的宏定义

#define NVM_DRIVER_SECTION __attribute__((section (".NVM_Driver_Section")))
#define NVM_DRIVER_SECTION_OFFSET __attribute__((section (".NVM_Driver_Section_offset")))

函数地址偏移量定义

__attribute__((used)) NVM_DRIVER_SECTION_OFFSET static const tFlashDriverAPIInfo gs_FlashDriverAPI  = {(tpfFLASH_DRV_EraseSector)      CAL_OFFSET(FLASH_ErasePage),(tpfFLASH_DRV_Program)          CAL_OFFSET(FLASH_ProgramWord),
};

分两个段,保证地址偏移量在生成的hex文件的前面

此处使用库函数中的FLASH_ErasePage和FLASH_ProgramWord函数。由于提取的函数最终是以数组的形式存在,以函数指针的方式进行调用,所以函数中不能存在全局变量或调用其他的函数。

需要将原库函数中的函数的调用函数使用宏定义的方式进行定义,使用do while语法实现。

擦除函数

__attribute__((used)) NVM_DRIVER_SECTION FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
{FLASH_Status status = FLASH_COMPLETE;FLASH_WaitForLastOperation(EraseTimeout,&status);if(status == FLASH_COMPLETE){ /* if the previous operation is completed, proceed to erase the page */FLASH->CR|= CR_PER_Set;FLASH->AR = Page_Address; FLASH->CR|= CR_STRT_Set;/* Wait for last operation to be completed */FLASH_WaitForLastOperation(EraseTimeout,&status);/* Disable the PER Bit */FLASH->CR &= CR_PER_Reset;}/* Return the Erase Status */return status;
}

上面的FLASH_WaitForLastOperation函数使用宏定义进行展开

#define FLASH_WaitForLastOperation(Timeout,pstatus)\
do{\uint32_t TimeoutCnt =  Timeout;\*pstatus = FLASH_COMPLETE;\FLASH_GetBank1Status(pstatus);\while((*pstatus == FLASH_BUSY) && (TimeoutCnt != 0x00))\{\FLASH_GetBank1Status(pstatus);\TimeoutCnt--;\}\if(TimeoutCnt == 0x00 )\{\*pstatus = FLASH_TIMEOUT;\}\
}while(0)

里面又用到一个FLASH_GetBank1Status函数

#define FLASH_GetBank1Status(pFLASH_Status)\
do{\*pFLASH_Status = FLASH_COMPLETE;\if((FLASH->SR & FLASH_FLAG_BANK1_BSY) == FLASH_FLAG_BSY)\{\*pFLASH_Status = FLASH_BUSY;\}\else\{\if((FLASH->SR & FLASH_FLAG_BANK1_PGERR) != 0)\{\*pFLASH_Status = FLASH_ERROR_PG;\}\else\{\if((FLASH->SR & FLASH_FLAG_BANK1_WRPRTERR) != 0 )\{\*pFLASH_Status = FLASH_ERROR_WRP;\}\else\{\*pFLASH_Status = FLASH_COMPLETE;\}\}\}\
}while(0)

写入函数

__attribute__((used)) NVM_DRIVER_SECTION FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
{FLASH_Status status = FLASH_COMPLETE;__IO uint32_t tmp = 0;FLASH_WaitForLastOperation(ProgramTimeout,&status);if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new first half word */FLASH->CR |= CR_PG_Set;*(__IO uint16_t*)Address = (uint16_t)Data;/* Wait for last operation to be completed */FLASH_WaitForLastOperation(ProgramTimeout,&status);if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new second half word */tmp = Address + 2;*(__IO uint16_t*) tmp = Data >> 16;/* Wait for last operation to be completed */FLASH_WaitForLastOperation(ProgramTimeout,&status);/* Disable the PG Bit */FLASH->CR &= CR_PG_Reset;}else{/* Disable the PG Bit */FLASH->CR &= CR_PG_Reset;}}         /* Return the Program Status */return status;
}

其中用到的函数也已经改为宏定义

编译后的map

    gs_FlashDriverAPI                        0x08020000   Data           8  main.o(.NVM_Driver_Section_offset)FLASH_ErasePage                          0x08020009   Thumb Code   186  stm32f10x_flash.o(.NVM_Driver_Section)FLASH_ProgramWord                        0x080200c3   Thumb Code   250  stm32f10x_flash.o(.NVM_Driver_Section)

函数需要偶数地址对齐

hexview中显示:

手动测试

__align(4) uint8_t flash_erase_buf[]={0x30,0xB5, 0x6C, 0x49, 0x04, 0x46, 0x4F, 0xF4,0x30, 0x22, 0xCD, 0x68, 0x04, 0x20, 0x13, 0x46, 0xED, 0x07, 0x09, 0xD1, 0xCB, 0x68, 0x5B, 0x07,0x01, 0xD5, 0x02, 0x20, 0x30, 0xBD, 0xCB, 0x68, 0xDB, 0x06, 0x18, 0xD5, 0x03, 0x20, 0x30, 0xBD,0xCD, 0x68, 0x04, 0x20, 0xED, 0x07, 0x02, 0xD0, 0x5B, 0x1E, 0xF9, 0xD1, 0x1C, 0xE0, 0xCD, 0x68,0x6D, 0x07, 0x01, 0xD5, 0x02, 0x20, 0x06, 0xE0, 0xCD, 0x68, 0xED, 0x06, 0x03, 0xD5, 0x03, 0x20,0x01, 0x2B, 0x11, 0xD0, 0x30, 0xBD, 0x01, 0x2B, 0x0E, 0xD0, 0x04, 0x28, 0xFA, 0xD1, 0x0B, 0x69,0x43, 0xF0, 0x02, 0x03, 0x0B, 0x61, 0x4C, 0x61, 0x0B, 0x69, 0x43, 0xF0, 0x40, 0x03, 0x0B, 0x61,0xCB, 0x68, 0xDB, 0x07, 0x0C, 0xD1, 0x01, 0xE0, 0x05, 0x20, 0x30, 0xBD, 0xCA, 0x68, 0x52, 0x07,0x01, 0xD5, 0x02, 0x20, 0x17, 0xE0, 0xCA, 0x68, 0xD2, 0x06, 0x14, 0xD5, 0x03, 0x20, 0x12, 0xE0,0xCB, 0x68, 0x04, 0x20, 0xDB, 0x07, 0x02, 0xD0, 0x52, 0x1E, 0xF9, 0xD1, 0x0A, 0xE0, 0xCB, 0x68,0x5B, 0x07, 0x01, 0xD5, 0x02, 0x20, 0x03, 0xE0, 0xCB, 0x68, 0xDB, 0x06, 0x00, 0xD5, 0x03, 0x20,0x01, 0x2A, 0x00, 0xD1, 0x05, 0x20, 0x0A, 0x69, 0x41, 0xF6, 0xFD, 0x73, 0x1A, 0x40, 0x0A, 0x61,0x30, 0xBD
};__align(4) uint8_t flash_write_buf[]={0xF8, 0xB5, 0x00, 0x92, 0x3C, 0x4A, 0x06, 0x46, 0x04, 0x20, 0xC3, 0x02,0xD4, 0x68, 0x1D, 0x46, 0xE4, 0x07, 0x09, 0xD1, 0xD4, 0x68, 0x64, 0x07, 0x01, 0xD5, 0x02, 0x20,0xF8, 0xBD, 0xD4, 0x68, 0xE4, 0x06, 0x18, 0xD5, 0x03, 0x20, 0xF8, 0xBD, 0xD4, 0x68, 0x04, 0x20,0xE4, 0x07, 0x02, 0xD0, 0x6D, 0x1E, 0xF9, 0xD1, 0x1B, 0xE0, 0xD4, 0x68, 0x64, 0x07, 0x01, 0xD5,0x02, 0x20, 0x06, 0xE0, 0xD4, 0x68, 0xE4, 0x06, 0x03, 0xD5, 0x03, 0x20, 0x01, 0x2D, 0x10, 0xD0,0xF8, 0xBD, 0x01, 0x2D, 0x0D, 0xD0, 0x04, 0x28, 0xFA, 0xD1, 0x14, 0x69, 0x44, 0xF0, 0x01, 0x04,0x14, 0x61, 0x31, 0x80, 0xD5, 0x68, 0x1C, 0x46, 0xEF, 0x07, 0x41, 0xF6, 0xFE, 0x75, 0x09, 0xD1,0x01, 0xE0, 0x05, 0x20, 0xF8, 0xBD, 0xD4, 0x68, 0x64, 0x07, 0x21, 0xD4, 0xD4, 0x68, 0xE4, 0x06,0x23, 0xD4, 0x13, 0xE0, 0xD7, 0x68, 0x04, 0x20, 0xFF, 0x07, 0x02, 0xD0, 0x64, 0x1E, 0xF9, 0xD1,0x2F, 0xE0, 0xD7, 0x68, 0x7F, 0x07, 0x01, 0xD5, 0x02, 0x20, 0x03, 0xE0, 0xD7, 0x68, 0xFF, 0x06,0x00, 0xD5, 0x03, 0x20, 0x01, 0x2C, 0x24, 0xD0, 0x04, 0x28, 0x23, 0xD1, 0xB6, 0x1C, 0x09, 0x0C,0x00, 0x96, 0x31, 0x80, 0xD1, 0x68, 0xC9, 0x07, 0x09, 0xD1, 0xD1, 0x68, 0x49, 0x07, 0x01, 0xD5,0x02, 0x20, 0x17, 0xE0, 0xD1, 0x68, 0xC9, 0x06, 0x14, 0xD5, 0x03, 0x20, 0x12, 0xE0, 0xD1, 0x68,0x04, 0x20, 0xC9, 0x07, 0x02, 0xD0, 0x5B, 0x1E, 0xF9, 0xD1, 0x0A, 0xE0, 0xD1, 0x68, 0x49, 0x07,0x01, 0xD5, 0x02, 0x20, 0x03, 0xE0, 0xD1, 0x68, 0xC9, 0x06, 0x00, 0xD5, 0x03, 0x20, 0x01, 0x2B,0x00, 0xD1, 0x05, 0x20, 0x11, 0x69, 0x29, 0x40, 0x11, 0x61, 0xF8, 0xBD, 0x00, 0x20, 0x02, 0x40,};typedef void (*flash_erase_handler)(uint32_t u32addr);
typedef void (*flash_write_handler)(uint32_t u32addr, uint32_t u32data);flash_erase_handler flash_erase = (flash_erase_handler)(flash_erase_buf + 1); 
flash_write_handler flash_write = (flash_write_handler)(flash_write_buf + 1);#define Test_addr 0x08030000

函数地址为0x08020009,往前一位开始复制,186byte,得到擦除函数

此处数组+1是因为指令LSB即最低有效位为0时是ARM指令,为1时是Thumb代码,此处需要+1使其成为Thumb代码

同理,可得到写入函数。

运行擦除函数:

目的地址内容被擦除

运行写入函数:

可以看到写入值正常。

HexView提取指定地址内容并重映射

编辑bat脚本如下

.\HexTools\hexview.exe /G /s .\RVMDK\Output\Project.hex /AR:0x8020000-0x80201bf  /xi:16 -o FlashDrv.hex /e:errorfile 
.\HexTools\hexview.exe /G /s FlashDrv.hex /remap:0x8020000-0x80201bf,0x20001000,0x1c0,0x1c0  /xi:16 -o FlashDrv.hex /e:errorfile 

使用/AR命令提取指定地址内容

使用/remap命令对地址进行remap,重映射地址为0x20001000,block大小为0x1c0

提取的flashdrv如下图所示:

总结

本文介绍了STM32F103 Flashdriver的制作过程,如果编译器有工具支持直接重映射到ram地址的话,就不需要后面hexview的步骤了,例如S32DS中就有。(keil中可能也有,后面如果研究出来了再补上)


若你觉得本文对你有帮助,欢迎点赞,关注,收藏,转发~~~ 你的鼓励是对小弟的最大支持~~~ 建了一个WX公众h,《汽车电子学习笔记》感兴趣可以关注一下~~~文章都会同步更新~
http://www.hrbkazy.com/news/12180.html

相关文章:

  • 网站服务器建设商近10天的时政新闻
  • 网站建设物理架构建站工具有哪些
  • 如何做好网站建设销售seo排名谁教的好
  • wordpress菜单下拉宁波seo网络优化公司
  • idc网站建设seo关键词快速排名介绍
  • 怎么看一个网站有没有做301云建站
  • 网站建设seo视频东莞网络营销网络推广系统
  • 丹东企业做网站企业网络宣传推广方案
  • 卧龙区建网站济宁百度竞价推广
  • 政府网站信息发布建设方案优化网站怎么做
  • 哪家网站优化公司好百度站长工具seo查询
  • 做淫秽网站有事情吗百度网址大全 简单版
  • 南山网站建设深圳信科营销策略有哪几种
  • 石家庄做网站的口碑好怎么样推广最有效最快速
  • 内销网站怎么做seo外链是什么意思
  • 优质网站建设在哪里西安网络seo公司
  • 长沙 外贸网站建设介绍网络营销的短文
  • 为什么后台编辑内容和网站上面显示的内容不一致短视频营销
  • 石家庄网站建设哪家好电子商务网站建设教程
  • 怎么做网站填内容哪里有正规的电商培训班
  • 色91Av做爰网站国内搜索引擎排名2022
  • 百度小程序代理深圳优化公司排名
  • 蓝色科技企业网站模板关键词排名优化易下拉技术
  • 高端企业网站建设制作搜索引擎优化管理实验报告
  • 服装网站建设开题报告枸橼酸西地那非片多长时间见效
  • 微信跳转链接生成器免费爱站网站seo查询工具
  • wordpress 获取ip北京seo顾问推推蛙
  • 浅谈旅游网站的规划与建设黄页网站推广app咋做广告
  • 常州网站建设怎么样教育机构加盟
  • 网站标题更换一个免费的网站