女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

自研MCU芯片閃存驅動的實現:OpenOCD詳細過程記錄與操作指南

安芯 ? 來源:jf_29981791 ? 作者:jf_29981791 ? 2025-05-08 10:51 ? 次閱讀

嵌入式系統開發領域,MCU(微控制單元)芯片在眾多智能設備中發揮著核心的控制作用,其性能優化與功能拓展一直是技術發展的重要方向。OpenOCD(Open On-Chip Debugger)作為一個功能強大的開源調試工具,廣泛應用于嵌入式系統開發中,為系統調試與程序燒錄提供了重要支持。

隨著自研MCU芯片項目的不斷推進,如何實現其與OpenOCD的無縫對接成為關鍵問題之一。而閃存驅動作為連接MCU與外部存儲、實現數據高效存儲與讀取的核心組件,其與OpenOCD的適配對于提升整個系統開發效率具有重要意義。

本文檔系統性地記錄了國科安芯自研MCU芯片AS32A601添加閃存驅動至OpenOCD工具的完整過程。通過深入研究OpenOCD的架構與工作原理,結合芯片的技術手冊,詳細闡述了驅動編寫、調試與驗證的各個步驟。旨在為后續類似項目開發提供詳實的參考與借鑒,助力嵌入式開發人員高效實現MCU芯片與OpenOCD的適配,加速產品研發與技術迭代進程。

OpenOCD編譯環境搭建

注:本節所有內容是基于Windows系統開發,如使用其他操作系統請自行參考。

安裝MSYS2

  • 安裝MSYS2需要進入到MSYS2官網下載安裝包,進入官網后如圖點擊msys2-x86_64-20240727.exe鏈接下載安裝包。

安裝步驟:

  • 雙擊運行安裝程序,出現如圖所示信息單擊下一步:

  • 選擇軟件安裝路徑后單擊下一步:

  • 出現如圖界面單擊下一步:

  • 等待安裝(可能比較慢請耐心等待):

  • 如果在安裝過程中出現卡在50%一直不動等情況,可以單擊取消

添加環境

  1. 打開我的電腦,進到安裝目錄找到mingw64文件夾,點擊進去找到bin文件夾點擊進去復制路徑。
  2. 設置環境變量:將上面復制的路徑添加到環境變量中。

  • 更換鏡像源:更換國內鏡像源,此處參考阿里鏡像源上關于msys2的方式進行更換
  1. 編輯 /etc/pacman.d/mirrorlist.mingw32 ,在文件開頭添加:Server = https://mirrors.aliyun.com/msys2/mingw/i686
  2. 編輯 /etc/pacman.d/mirrorlist.mingw64 ,在文件開頭添加:Server = https://mirrors.aliyun.com/msys2/mingw/x86_64
  3. 編輯 /etc/pacman.d/mirrorlist.msys ,在文件開頭添加:Server = https://mirrors.aliyun.com/msys2/msys/$arch
  4. 編輯 /etc/pacman.d/mirrorlist.ucrt64 ,在文件開頭添加:Server = https://mirrors.aliyun.com/msys2/mingw/ucrt64

安裝依賴環境

點擊相應的命令行軟件打開命令行窗口,這里選擇“MSYS2 MINGW64”。

  1. 更新MSYS2,使用以下指令更新系統文件。直至無更新內容為止。
  2. 安裝依賴環境 不同的操作系統對安裝的環境有些許的差異要求,一般而言不同的軟件依賴包有差異的一般為64bit的標識為“x86_64”,而32bit系統一般為“i686”。
  3. 64bit操作命令(使用時直接復制粘貼即可):
  4. 32bit操作命令(使用時直接復制粘貼即可):

OpenOCD源碼獲取和編譯流程

下載OpenOCD

  1. 打開MSYS2 MINGW64命令行窗口,跳轉到要克隆的地址,使用 git clone 命令將最新的OpenOCD源碼克隆至本地。(此處給出一個git clone命令操作示例,如需下載其他版本的源碼,請自行修改克隆地址) git clone https://github.com/riscv-collab/riscv-openocd.git

注:后續所有輸入指令操作,都是在MSYS2 MINGW64命令行窗口中操作,需要將路徑跳轉到克隆源碼地址下,如圖所示。

  1. 在MSYS2 MINGW64命令行窗口,使用cd命令將路徑跳轉到剛克隆的源碼地址下,輸入./bootstrap 命令克隆OpenOCD的依賴文件,如下圖所示。

配置OpenOCD

  1. 使用以下指令配置OpenOCD,這里選擇“--enable-jlink”配置,其他配置(只要安裝了相應的依賴)會默認開啟:
  2. 配置過程需要一些依賴包,如果配置過程中提示依賴包版本不足或沒有安裝,需要先安裝依賴包。 根據提示,使用pacman -Ss + 搜索依賴包名,即可找到依賴包。 使用pacman -S + 安裝依賴包名,即可完成依賴包的安裝。
  3. 安裝依賴包完成后,繼續執行第一步操作,直至配置完成。

OpenOCD添加驅動

文件總覽

以AS32I601為例,在整個自研芯片集成過程中,需要編寫并測試如下設備支持文件:

  1. 閃存驅動程序文件(as32i601.c)
  2. 內置閃存驅動程序列表文件(drivers.c)
  3. 編譯腳本文件(Makefile.am)
  4. 運行腳本文件(as32i601.cfg)

目前,文件實現了編程功能,其他功能可后續補充,不影響實際功能使用。

設備支持文件存放結構如下:

  1. openocdsrcflashnoras32i601.c
  2. openocdsrcflashnordrivers.c
  3. openocdsrcflashnorMakefile.am
  4. openocdtcltargetas32i601.cfg

文件詳解

閃存驅動程序文件(as32i601.c)

由于本芯片特性,燒錄過程無法通過RAM運行片上代碼的形式進行代碼燒錄,因此選用了OpenOCD直接操作qspi寄存器的形式完成flash代碼燒錄,根據文件中flash_driver結構體所示,該文件需要完成flash_bank_command、erase、write、probe函數編寫,其他函數可采用官方庫文件函數和參考其他芯片驅動文件即可。

flash_driver結構體,該結構體定義了OpenOCD閃存驅動程序所需的所有回調。

conststructflash_driveras32i601_flash = { .name = "as32i601", .commands = as32i601_command_handlers, .flash_bank_command = as32i601_flash_bank_command, .erase = as32i601_erase, .protect = as32i601_protect, .write = as32i601_write, .read = default_flash_read, .probe = as32i601_probe, .auto_probe = as32i601_probe, .erase_check = default_flash_blank_check, .info = get_as32i601_info, .free_driver_priv = default_flash_free_driver_priv, };

第一行,as32i601_flash為閃存驅動程序名稱,這個名稱需要放到內置閃存驅動程序列表文件(drivers.c)中。 第二行,as32i601為定義的閃存名字,此名稱會在運行腳本文件(as32i601.cfg)中用到。 第四行,flash_bank_command為通過腳本文件傳入的信息,用于獲取芯片信息,如芯片地址等。 第五行,erase為擦除函數,該函數傳入擦除的起始塊和終止塊,需要在此函數中實現擦除功能。 第六行,write為寫入函數,該函數傳入寫入的起始地址、寫入的數據和寫入的大小,需要在此函數中實現寫入功能。

flash_bank_command實現函數為as32i601_flash_bank_command,可以在此函數中獲取閃存庫命令。

FLASH_BANK_COMMAND_HANDLER(as32i601_flash_bank_command) { if (CMD_ARGC < 7) return ERROR_COMMAND_SYNTAX_ERROR; bank->driver_priv = malloc(sizeof(as32i601_priv)); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], priv->ctrlAddress); LOG_INFO("as32i601 probe: 0x%x ctrlAddress", priv->ctrlAddress); priv->probed = 0; return ERROR_OK; }

第六行,為as32i601_priv結構體申請一段內存。 第七行,通過命令行獲取控制器基地址,并賦值給priv->ctrlAddress。

erase實現函數為as32i601_erase,此函數中實現擦除功能。

intas32i601_erase(struct flash_bank *bank, unsignedint first, unsignedint last) { structtarget *target = bank->target; if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } LOG_INFO("as32i601_erase"); // flash memory mass erase as32i601_flashStop(bank); for(unsignedint sector = first; sector <= last; sector += 0x400) { as32i601_Write_Reg(bank, QSPI_CR, 0x00000031); as32i601_Write_Reg(bank, QSPI_CCR, 0x00000106); as32i601_WaitNotBusy(bank); as32i601_Write_Reg(bank, QSPI_CCR, 0x000025d8); as32i601_Write_Reg(bank, QSPI_AR, bank->sectors[sector].offset); as32i601_WaitNotBusy(bank); as32i601_read_flashstatus(bank); bank->sectors[sector].is_erased = 1; } return ERROR_OK; }

第十五行,0x400為實際芯片扇區大小除以行大小所得到的值。因為此版本的OpenOCD會將bin文件大小按照所設置的扇區大小對齊,所以此文件將扇區參數設置為行大小。 第十七到二十四行為扇區擦除操作,這里不過多進行講解,as32i601_Write_Reg函數是通過OpenOCD底層函數target_write_memory封裝而來,可以根據自己需求進行自定義封裝。

write實現函數為as32i601_write,此函數中實現bin文件寫入功能。

staticintas32i601_write(struct flash_bank *bank, constuint8_t *buffer,uint32_t offset, uint32_t count) { structtarget *target = bank->target; if(target->state != TARGET_HALTED){ LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } if(offset & 0x03){ LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-byte alignment", offset); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } if(count & 0x3){ LOG_ERROR("size 0x%" PRIx32 " breaks required 4-byte alignment", count); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } as32i601_flashStop(bank); uint32_t addr = offset; LOG_INFO("as32i601 probe: %d count, 0%d addr", count, addr); while(count >= 256) { as32i601_Write_Reg(bank, QSPI_CR, 0x00000031); as32i601_Write_Reg(bank, QSPI_CCR, 0x00000106); as32i601_WaitNotBusy(bank); as32i601_Write_Reg(bank, QSPI_CCR, 0x00802502); as32i601_Write_Reg(bank, QSPI_AR, addr); as32i601_Write_Reg(bank, QSPI_DLR, 256-1); // flash memory word programfor(uint32_t address = 0; address < 256; address += 4) { constuint8_t *t_buffer = buffer + address; uint32_t value = buf_get_u32(t_buffer, 0, 32); as32i601_Write_Reg(bank, QSPI_DR, value); } buffer += 256; as32i601_WaitNotBusy(bank); as32i601_read_flashstatus(bank); LOG_INFO("as32i601 probe: %d count", count); addr = addr + 0x100; count = count - 0x100; } LOG_INFO("as32i601 flash write success"); return ERROR_OK; }

第五行到第十六行,為判斷當時cpu狀態和傳入參數是否正確。 第三十八行,為將八位數組轉換為32位數據,此函數為OpenOCD底層函數。 第二十三行到第四十九行,為寫入操作,這里不過多進行講解。

probe實現函數為as32i601_probe,通過此函數設定flash信息。

staticintas32i601_probe(struct flash_bank *bank) { LOG_INFO("as32i601 qspi_probe"); if(!priv->probed){ bank->num_sectors = bank->size/(256); uint32_t offset = 0; bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); for (unsignedint i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = offset; bank->sectors[i].size = 256; offset += bank->sectors[i].size; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } priv->probed = 1; } return ERROR_OK; }

第六行,通過bin文件大小計算出所用扇區數量,因為此版本的OpenOCD會將bin文件大小按照所設置的扇區大小對齊,所以此文件將扇區參數設置為行大小。 第九行到第十五行,初始化扇區信息。

內置閃存驅動程序列表文件(drivers.c)

此文件列表中定義了所有閃存,需要將芯片信息加入其中。 (注:不同版本的OpenOCD此處可能略有差異,需要根據實際情況進行修改)

externconststructflash_driveras32i601_flash;staticconststructflash_driver * constflash_drivers[] = { &aduc702x_flash, &aducm360_flash, ... &as32i601_flash, ... &xmc4xxx_flash, &w600_flash, &rsl10_flash, NULL, };

第一行和第七行,根據格式添加信息,此處為as32i601_flash。

編譯腳本文件(Makefile.am)

此文件為編譯腳本文件,添加驅動文件路徑。

NOR_DRIVERS = %D%/aduc702x.c %D%/aducm360.c ... %D%/str9xpec.c %D%/swm050.c %D%/as32i601.c ... %D%/xmc1xxx.c %D%/xmc4xxx.c

第七行,根據格式添加閃存驅動程序文件(as32i601.c)。

運行腳本文件(as32i601.cfg)

此文件為運行腳本文件,包含芯片配置信息。

adapter driver jlink adapter speed 1000 transport select jtag reset_config srst_nogate set _CHIPNAME riscv jtag newtap **_CHIPNAME cpu -irlen 5 -expected-id 0x10002FFFset _TARGETNAME **_CHIPNAME.cpu target create **_TARGETNAME.0 riscv -chain-position **_TARGETNAME **_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 0x80000 -work-area-backup 1set _FLASHNAME **_CHIPNAME.flash flash bank **_FLASHNAME as32i601 0x100000000x0100000000 **_TARGETNAME.00x42100800 init halt

第一行,為適配器驅動,此處為jlink。 第三行,為適配器傳輸速度,此處為1000。 第五行,為傳輸方式,此處為jtag。 第七行,為復位配置。 第九行,為芯片類型,此處為riscv。 第十行,設置IR寄存器長度和ID號。 第十五行,設置sram的物理地址和長度(以自定義芯片為例)。 第十八行,設置閃存名稱(此名稱和閃存驅動程序文件中的name名稱對應)、閃存地址、大小和控制寄存器基地址(以自定義芯片為例)。

編譯OpenOCD

  1. 使用如下指令編譯OpenOCD

注:若編譯過程中出現如圖所示錯誤,說明calloc函數所使用的頭文件與實際代碼使用版本不匹配,需要將頭文件修改為正確的版本。

  1. 編譯錯誤失敗原因分析:void *__cdecl calloc(size_t _NumOfElements,size_t _SizeOfElements);
  2. 本地庫環境修改
  3. mingw下載
  4. 打開MinGW官網,點擊此處下載安裝包
  5. 雙擊進行軟件安裝
  6. 等待安裝完成
  7. 編譯器安裝
  8. 勾選“mingw32-gcc”
  9. 點擊“Apply Changes”
  10. 點擊“Apply”
  11. 等待更新完成
  12. 添加環境變量 打開系統環境變量設置窗口,如圖所示,將安裝路徑“C:MinGWbin和C:MinGWinclude”填入環境變量。(若安裝在其他路徑,可自行修改添加)
  13. 編譯完成后,為后續使用方便,可以將相應文件復制出來完成對OpenOCD的打包壓縮。

閃存驅動使用流程與驗證

注:本章所有輸入指令操作,都是在cmd窗口中進行。

閃存下載

打開cmd窗口,使用如下命令,將bin文件下載到芯片中。(注:文件路徑可使用絕對路徑也可使用相對路徑,在相應環境中進行修改即可) ./openocd/bin/openocd.exe -f ./openocd/target/as32i601.cfg -c "program ./SV32C601_Software/demo/gpio/GPIO_IO_test/OBJ/bin/gpio_io_test.bin 0x10000000" -c "shutdown" 命令執行后,會彈出一個窗口,等待窗口自動執行完成后結束。(此處包含了運行調試信息,若無需此信息,可自行在閃存驅動程序文件將對應代碼注釋即可)

運行界面如圖所示:

閃存讀取

打開cmd窗口,使用如下命令,連接OpenOCD并讀取閃存,判斷是否下載正確。

./openocd/bin/openocd.exe -f ./openocd/target/as32i601.cfg telnet localhost 4444 halt mdw 0x1000000040

第一行:在cmd窗口輸入此命令,連接OpenOCD,OpenOCD會監聽4444端口。 第三行:在一個新的窗口輸入此命令,會連接telnet端口。 第五行:在telnet窗口輸入此命令,操作為停止cpu。 第七行:在telnet窗口輸入此命令,讀取0x10000000地址的數據,讀取寬度為40個字。

將讀取的數據和bin文件進行對比,如果一致,則說明驅動程序執行正確,二進制文件下載成功。(注:此處需要多讀取幾個地址,以確保整個bin文件下載正確)

運行界面如圖所示: OpenOCD連接界面:

讀取內存界面:

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 芯片
    +關注

    關注

    459

    文章

    52013

    瀏覽量

    434572
  • mcu
    mcu
    +關注

    關注

    146

    文章

    17768

    瀏覽量

    359073
  • 閃存
    +關注

    關注

    16

    文章

    1832

    瀏覽量

    115665
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    發力智能化下半場,比亞迪自動駕駛芯片或年底流片

    計劃智能駕駛專用芯片,項目由比亞迪半導體團隊主導,目前在與芯片設計公司對接,并開始招募BSP技術團隊。據了解,BSP(板級支持包)是介于主板硬件和
    的頭像 發表于 07-20 07:54 ?2595次閱讀

    瑞薩電子推出采用RISC-V CPU內核的通用32位MCU

    2024 年 3 月 26 日,中國北京訊 - 全球半導體解決方案供應商瑞薩電子(TSE:6723)今日宣布率先在業內推出基于內部CPU內核構建的通用32位RISC-V微控制器(MCU
    發表于 03-30 22:08

    《電子發燒友電子設計周報》聚焦硬科技領域核心價值 第10期:2025.05.6--2025.05.9

    A7@1.5GHz+雙網口+雙CAN-FD)工業開發板——開發環境搭建 3、在構建自動布線工具之前我會告訴自己的13件事 4、MCU芯片閃存
    發表于 05-09 19:26

    Rokid芯片搶先看

    又一AI芯片浮出杭州西溪:阿里之后,Rokid芯片也曝光了
    發表于 06-05 13:00

    蘋果射頻芯片?OPPONPU芯片芯片的國產替代需要跨越三個誤區!

    了解,而且現在芯片的復雜度越來越高,需求也是越來越多。大廠商把復雜的需求告訴IC設計公司,不如自己通過芯片,將已積累很深的軟件算法上的優勢,通過硬件科技的方式來
    發表于 01-02 08:00

    閃存頁面擦除操作永遠不會完成的原因?怎么解決?

    認為這可能是我的特定 MCU 的硬件故障。然而,讓我懷疑的是,當 MCU 在嘗試在固件中執行閃存操作之前被重置和停止時,批量擦除和/或頁面擦除、閃存
    發表于 12-26 07:21

    華為Mate 40系列采用的“閃存”來自長江存儲

    本月初的時候,有報道稱華為Mate40系列疑似采用了華為閃存的消息,由此也引發了一些爭論。
    的頭像 發表于 11-21 10:03 ?4517次閱讀

    樹莓派不講武德,雙核MCU Pico,STM32哭暈在廁所!

    樹莓派不講武德,雙核MCU Pico,STM32哭暈在廁所!重磅,樹莓派再出Pico雙核MCU
    發表于 10-28 20:20 ?14次下載
    樹莓派不講武德,<b class='flag-5'>自</b><b class='flag-5'>研</b>雙核<b class='flag-5'>MCU</b> Pico,STM32哭暈在廁所!

    openocd驅動程序

    openocd驅動程序,可應用于STlink,DAPlink等仿真器
    發表于 09-26 14:51 ?1次下載

    OPPO放棄芯片,終止哲庫業務

    有消息稱“OPPO放棄芯片”的消息開始流傳。細心的網友發現,OPPO的影像芯片“馬里亞納
    的頭像 發表于 06-02 17:14 ?2298次閱讀

    小米芯片公司增資至19.2億

    小米芯片的投入決心不會動搖。
    的頭像 發表于 06-07 09:35 ?1603次閱讀

    蘋果Wi-Fi芯片之路充滿挑戰

    據悉,蘋果在5G調制解調器芯片上投入了大量資金,如今希望在Wi-Fi芯片上取得突破。然而
    的頭像 發表于 12-26 14:46 ?926次閱讀

    比亞迪最快于11月實現算法量產,推進智駕芯片進程

    10月21日市場傳出消息,比亞迪正計劃整合其新技術院下的智能駕駛團隊,目標是在今年11月實現智能駕駛算法的量產,并持續推進智能駕駛
    的頭像 發表于 10-22 15:57 ?1235次閱讀

    基于 IAR Embedded Workbench 的 MCU 芯片軟件函數與變量內存布局優化精控方法

    的函數和變量指定section放置方法與操作流程,兼具過程記錄詳細說明,旨在打造一份實用的參考指南,助力開發者精準掌控程序的內存分布與執行
    的頭像 發表于 04-30 16:38 ?144次閱讀
    基于 IAR Embedded Workbench 的<b class='flag-5'>自</b><b class='flag-5'>研</b> <b class='flag-5'>MCU</b> <b class='flag-5'>芯片</b>軟件函數與變量內存布局優化精控方法

    RISC-V JTAG:開啟MCU 芯片調試之旅

    在當今電子科技飛速發展的時代, MCU 芯片成為眾多企業追求技術突破與創新的關鍵領域。而芯片的調試過程則是確保其性能與可靠性的重要環節。本文以國科安芯
    的頭像 發表于 05-07 17:57 ?338次閱讀
    RISC-V JTAG:開啟<b class='flag-5'>MCU</b> <b class='flag-5'>芯片</b>調試之旅