国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32F103制作FlashDriver

這篇具有很好參考價值的文章主要介紹了STM32F103制作FlashDriver。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

在汽車行業(yè)控制器軟件刷新流程中,一般會將Flash驅(qū)動單獨進行刷寫,目的是防止程序中一直存在Flash驅(qū)動的話,可能會造成對APP軟件的異常操作,導(dǎo)致應(yīng)用程序無法執(zhí)行。本文介紹STM32F103使用KEIL生成指定FlashDriver地址的hex文件,然后使用HexView命令行提取FlashDriver及Remapping flash地址到ram地址

本文參考github,SummerFalls大神的UDS_S32K144_FlashDriver

芯片內(nèi)存定義

STM32F103RCT6,flash大小256k,一個扇區(qū)2k,SRAM:48KB;

實現(xiàn)過程

FlashDriver生成

段定義

由于我無法直接在Keil中導(dǎo)出指定ram地址的hex文件,所以采用先定義指定flash地址的flash驅(qū)動,后面通過hexview實現(xiàn)地址重映射

keil中的內(nèi)存區(qū)域定義通過分散加載文件(.sct格式)實現(xiàn),如下所示

; *************************************************************
; *** 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)    
  }
  }

此處設(shè)置了兩個段,NVM_Driver_Section_offset用來設(shè)置函數(shù)偏移地址,NVM_Driver_Section用來設(shè)置函數(shù)地址

增加段的宏定義

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

函數(shù)地址偏移量定義

__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文件的前面

此處使用庫函數(shù)中的FLASH_ErasePage和FLASH_ProgramWord函數(shù)。由于提取的函數(shù)最終是以數(shù)組的形式存在,以函數(shù)指針的方式進行調(diào)用,所以函數(shù)中不能存在全局變量或調(diào)用其他的函數(shù)。

需要將原庫函數(shù)中的函數(shù)的調(diào)用函數(shù)使用宏定義的方式進行定義,使用do while語法實現(xiàn)。

擦除函數(shù)
__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函數(shù)使用宏定義進行展開

#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函數(shù)

#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)
寫入函數(shù)
__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;
}

其中用到的函數(shù)也已經(jīng)改為宏定義

編譯后的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)

函數(shù)需要偶數(shù)地址對齊

hexview中顯示:

stm32 flash驅(qū)動,STM32,Autosar筆記,單片機,stm32,flashdriver

手動測試

__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

函數(shù)地址為0x08020009,往前一位開始復(fù)制,186byte,得到擦除函數(shù)

此處數(shù)組+1是因為指令LSB即最低有效位為0時是ARM指令,為1時是Thumb代碼,此處需要+1使其成為Thumb代碼

同理,可得到寫入函數(shù)。

運行擦除函數(shù):
stm32 flash驅(qū)動,STM32,Autosar筆記,單片機,stm32,flashdriver
目的地址內(nèi)容被擦除

運行寫入函數(shù):
stm32 flash驅(qū)動,STM32,Autosar筆記,單片機,stm32,flashdriver
可以看到寫入值正常。

HexView提取指定地址內(nèi)容并重映射

編輯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命令提取指定地址內(nèi)容

使用/remap命令對地址進行remap,重映射地址為0x20001000,block大小為0x1c0

提取的flashdrv如下圖所示:

stm32 flash驅(qū)動,STM32,Autosar筆記,單片機,stm32,flashdriver

總結(jié)

本文介紹了STM32F103 Flashdriver的制作過程,如果編譯器有工具支持直接重映射到ram地址的話,就不需要后面hexview的步驟了,例如S32DS中就有。(keil中可能也有,后面如果研究出來了再補上)文章來源地址http://www.zghlxwxcb.cn/news/detail-624595.html


若你覺得本文對你有幫助,歡迎點贊,關(guān)注,收藏,轉(zhuǎn)發(fā)~~~ 你的鼓勵是對小弟的最大支持~~~ 建了一個WX公眾h,《汽車電子學(xué)習筆記》感興趣可以關(guān)注一下~~~文章都會同步更新~

到了這里,關(guān)于STM32F103制作FlashDriver的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • STM32F103硬件SPI驅(qū)動ADS1256

    STM32F103硬件SPI驅(qū)動ADS1256

    最近實驗室有幾個項目都需要用到高分辨率AD轉(zhuǎn)換,于是就開始了ADS1256的開發(fā)。 新手,焊得丑,見諒(能用就行) 二: 本以為很容易就能做完,結(jié)果被采樣速率的問題困擾了很久。 代碼如下,使用2.5V基準源進行測試,結(jié)果在讀ADS時經(jīng)常出現(xiàn)讀出0xFFFFFF的情況,只能忍住悲傷

    2024年02月12日
    瀏覽(113)
  • 野火STM32F103驅(qū)動GT911觸摸芯片

    野火STM32F103驅(qū)動GT911觸摸芯片

    芯片介紹 GT911 是專為 7”~8”設(shè)計的新一代 5 點電容觸控 方案,擁有 26 個驅(qū)動通道和 14 個感 應(yīng)通道,以滿足更高的 touch 精度要求。 GT911 可同時識別 5 個觸摸點位的 實時準確位置 , 移動軌跡 及 觸摸面積。 并可根據(jù)主控需要,讀取相應(yīng)點數(shù)的觸摸信息。 芯片原理圖 管腳定

    2024年02月06日
    瀏覽(23)
  • STM32F103ZET6 驅(qū)動 OLED

    STM32F103ZET6 驅(qū)動 OLED

    目錄 前言 OLED模塊的基本了解 OLED驅(qū)動程序的開發(fā) 前言 ? 大家好,這是我第一次發(fā)帖,由于,我的技術(shù)并不成熟,程序難免有編寫不規(guī)范的地方,希望讀者能夠指正,也希望這篇帖子能夠讓讀者對OLED模塊有個大致的了解。很高興能與大家交流。 OLED模塊的基本了解 OLED模塊的

    2024年02月14日
    瀏覽(28)
  • 從零開始制作STM32F103RCT6小車(一)

    從零開始制作STM32F103RCT6小車(一)

    ? ? ? ? 僅以此系列給實驗室的學(xué)弟學(xué)妹作為小車制作教程來使用,后續(xù)的內(nèi)容我會在這個暑假陸續(xù)更新出來,本篇的內(nèi)容是新建一個適用于STM32F103RCT6的工程 ? ? ? ? 接下來的操作幾乎是基于STM32F1xx系列的固件庫,這里我給大家列出鏈接 STM32F1xx系列固件庫? ? ? ? ? ? ? ?

    2023年04月08日
    瀏覽(108)
  • STM32F103C8T6制作USB鍵盤

    STM32F103C8T6制作USB鍵盤

    ? ? ? ? 1、原因:電腦每次開機都需要輸入登錄密碼,感覺很麻煩,就想著能不能用單片機做一個USB鍵盤,按一下自動給電腦發(fā)一串密碼實現(xiàn)開機。后來又想,其實不用按鍵也行,用延時,延時到電腦開機再發(fā)送密碼就好了,于是便有了這個制作。 ? ? ? ? 2、 功能:將做好

    2024年01月22日
    瀏覽(20)
  • 基于STM32F103的PWM電機驅(qū)動A4950

    基于STM32F103的PWM電機驅(qū)動A4950

    A4950的峰值輸出電流可達±3.5 A,工作電壓為7.6~40v。 優(yōu)點:相對于L298N模塊控制2個電機正反轉(zhuǎn)僅需要4個I/O口,體積小,發(fā)熱低。 缺點:需要2個PWM引腳才能控制正反轉(zhuǎn),所以控制2個電機需要4PWM引腳,會使用STM32F103芯片一個定時器的全部PWM通道。 A4950模塊是靠輸入2路的PWM占空

    2024年02月04日
    瀏覽(31)
  • STM32F103驅(qū)動HCSR04超聲波測距顯示

    STM32F103驅(qū)動HCSR04超聲波測距顯示

    超聲波模塊在電子DIY作品中實現(xiàn)小車避障測距等方面均應(yīng)用廣泛,在大學(xué)生智能車DIY愛好者中尤為顯眼。 點擊圖片購買 HC-SR04超聲波測距模塊可提供2cm-400cm的非接觸式距離感測功能,測距精度可達3mm,包括發(fā)射器、接收器與控制電路,它是一種壓電式傳感器,利用電致伸縮現(xiàn)

    2024年02月02日
    瀏覽(18)
  • 【正點原子STM32連載】 第四十五章 FLASH模擬EEPROM實驗 摘自【正點原子】STM32F103 戰(zhàn)艦開發(fā)指南V1.2

    【正點原子STM32連載】 第四十五章 FLASH模擬EEPROM實驗 摘自【正點原子】STM32F103 戰(zhàn)艦開發(fā)指南V1.2

    STM32本身沒有自帶EEPROM,但是STM32具有IAP(在應(yīng)用編程)功能,所以我們可以把它的FLASH當成EEPROM來使用。本章,我們將利用STM32內(nèi)部的FLASH來實現(xiàn)第三十六章實驗類似的效果,不過這次我們是將數(shù)據(jù)直接存放在STM32內(nèi)部,而不是存放在NOR FLASH。 本章分為如下幾個小節(jié): 45.1 ST

    2024年02月08日
    瀏覽(24)
  • STM32F103單片機通過SPI全雙工通信協(xié)議與W25Q64(FLASH)進行通信【串行同步通信(數(shù)據(jù)線與時鐘線配合),(一主多從模式)】附相關(guān)驅(qū)動代碼詳解

    STM32F103單片機通過SPI全雙工通信協(xié)議與W25Q64(FLASH)進行通信【串行同步通信(數(shù)據(jù)線與時鐘線配合),(一主多從模式)】附相關(guān)驅(qū)動代碼詳解

    1.W25Qxx系列是一種低成本、小型化、使用簡單的 非易失性存儲器 ,常應(yīng)用于數(shù)據(jù)存儲、字庫存儲、固件程序存儲等場景 2.存儲介質(zhì): Nor Flash(閃存) 3.時鐘頻率:80MHz / 160MHz (Dual SPI) / 320MHz (Quad SPI) 4.存儲容量(24位地址): W25Q40: 4Mbit / 512KByte W25Q80: 8Mbit / 1MByte W25Q16: 16

    2024年04月13日
    瀏覽(46)
  • STM32F103C8T6繼電器驅(qū)動篇

    STM32F103C8T6繼電器驅(qū)動篇

    由于設(shè)計的東西是一個電機,但是stm32端口輸出電流太小,所以采用繼電器控制,通過實際接線測試發(fā)現(xiàn),單片機的IO口驅(qū)動不了繼電器,當繼電器接到IO口上時,端口電壓會將至2.2V左右,更加驅(qū)動不了繼電器了。 所以,為了可以驅(qū)動繼電器,重新設(shè)計了電路,通過三極管來

    2024年02月12日
    瀏覽(41)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包