Introduction
芯片驗(yàn)證與測試組(VV,Verification & Validation Team)的同事在驗(yàn)證新芯片產(chǎn)品時(shí),需要在手冊完備之前就要開始展開開發(fā)工作,甚至需要根據(jù)驗(yàn)證的結(jié)果對從設(shè)計(jì)文檔合成的初版用戶手冊進(jìn)行調(diào)整。這些早期的開發(fā)工作也會對軟件工具的設(shè)備支持包提出需求,例如Keil集成開發(fā)環(huán)境的pack支持包,但正式給用戶發(fā)布的設(shè)備支持包又需要依賴于完備的用戶手冊。好吧,這其實(shí)是一個“雞蛋問題”(到底是先有雞再生蛋,還是先有蛋再孵小雞)。暫且跳過最初的情況,我們軟件與系統(tǒng)工程組(Software & System Engineering Team)的工程師可以基于已有的相近產(chǎn)品進(jìn)行微調(diào),然后同VV提供的驗(yàn)證情況配合,不斷微調(diào)和迭代趨近最終發(fā)布狀態(tài)。這才是真實(shí)世界的開發(fā)過程。在這個過程中,對描述寄存器布局的SVD文件的更新是最活躍的,可能隨著驗(yàn)證的實(shí)際情況,我們希望不要每次都重頭開始處理所有外設(shè)寄存器的布局,而是不斷根據(jù)每個周期的反饋,進(jìn)行局部更新,以減少重復(fù)的工作量。在這個工作環(huán)境中,在現(xiàn)有SVD文件局部更新某個外設(shè)模塊,將會是一個非常頻繁基本操作。
本文詳細(xì)介紹了如何使用靈動軟件與系統(tǒng)工程組自主開發(fā)的sdk-npi-enablement-tool
工具包,完成SVD文件局部更新的操作過程。
Overview
sdk-npi-enablement-tools
工具包含了一個描述外設(shè)模塊寄存器分布信息的數(shù)據(jù)庫(xlsx文件和yaml文件集合),以及以數(shù)據(jù)庫為對象的一系列服務(wù)的工具,例如,從原始的doc格式的UM文檔中提取寄存器分布信息存放為xlsx記錄的工具類 gen_srctables.py
、從描述外設(shè)模塊寄存器分布的xlsx文件生成SVD文件的工具類 gen_svdfile.py
、從xlsx記錄中生成包含中斷向量表等具體芯片相關(guān)信息頭文件和dma_request.h
文件的gen_sdkfile.py
等。
Operation Steps
以新建的不會在真實(shí)世界中存在的虛擬平臺MM32F0000
項(xiàng)目為例,以現(xiàn)有已經(jīng)發(fā)布的MM32F0020
微控制器的SVD文件為模板,更換其中的UART
模塊為USART
模塊,產(chǎn)生最終的MM32F0000
微控制器項(xiàng)目的SVD文件。
創(chuàng)建芯片配置文件yaml
- 在
sdk-npi-enablement-tools\\tools\\generator\\yaml\\devices
目錄下創(chuàng)建MM32F0000.yaml
文件。這里的MM32F0000.yaml
文件描述了SoC中包含了哪些外設(shè)模塊。
此處以MM32F0020
項(xiàng)目在同級目錄下的配置文件為模板,復(fù)制創(chuàng)建MM32F0000.yaml
的芯片配置文件。其中包含了MM32F0000
芯片中集成的外設(shè)模塊。這些記錄的信息來自于芯片DS手冊中對片上資源介紹的描述,也可以來自于產(chǎn)品經(jīng)理定義新芯片產(chǎn)品的PB文檔,但實(shí)際芯片集成資源的情況仍需以DS為準(zhǔn)。
coretype: m0
subseries:
MM32F0000B:
peripherals:
peripherals:
flash:
pwr:
rcc:
crc:
syscfg:
gpio:
gpioa:
gpiob:
exti:
adc:
adc1:
tim1:
tim3:
tim14:
wwdg:
iwdg:
uart:
uart1:
uart2:
spi:
spi1:
i2c:
i2c1:
dbg:
其中,yaml文件名描述了本產(chǎn)品系列的名字,yaml文件中的subseries
及下級屬性描述了產(chǎn)品系列內(nèi)部子系列具體芯片型號的特有外設(shè),例如在MM32F0270.yaml
文件中,在不同的子系列中,對usb、can等模塊的支持情況就進(jìn)行了細(xì)分。
- 在
sdk-npi-enablement-tools\\database\\ip_reg_desp
目錄下為MM32F0000
創(chuàng)建外設(shè)寄存器映射數(shù)據(jù)記錄。
此處以同級目錄下的MM32F0020
目錄為模板,復(fù)制成MM32F0000
的目錄。其中包含了以xlsx文件存放的各外設(shè)模塊獨(dú)自的寄存器映射地址信息。這些文件記錄的原始數(shù)據(jù)來自于芯片UM手冊中對外設(shè)模塊的描述,也可以來自于芯片設(shè)計(jì)組(芯片架構(gòu))提供的完備的寄存器描述材料。
圖x 描述IP外設(shè)模塊寄存器內(nèi)部偏移的存儲映射的數(shù)據(jù)庫記錄
- 在
sdk-npi-enablement-tools\\resource
目錄下為MM32F0000
芯片創(chuàng)建關(guān)于中斷向量表和外設(shè)基址映射信息的記錄。
此處仍以同級目錄下的MM32F0020
項(xiàng)目為模板,復(fù)制成MM32F0000
項(xiàng)目的目錄。其中包含了baseaddress.xlsx
文件和interrupts.xlsx
文件,分別記錄外設(shè)模塊的基地址和中斷向量表中各中斷向量的名字和排序。這些記錄的原始信息來自于芯片的UM手冊。
圖x 描述芯片集成外設(shè)在內(nèi)存空間中映射的數(shù)據(jù)庫記錄4. 運(yùn)行sdk-npi-enablement-tools\\tools
目錄下的gen_svdfile.py
腳本程序,將在``sdk-npi-enablement-tools\\targetfiles目錄創(chuàng)建一個
mm32f0000`的項(xiàng)目目錄,其中包含本次創(chuàng)建過程生成的SVD文件。
在腳本中修改chiptype的配置值為芯片名,mm32f0000,此處的設(shè)定值需要同MM32F0000.yaml
文件的文件名保持一致。
import os
from generator.gen_regsvd import *
def main():
chiptype = 'mm32f0000' # change here to suit to different chip series
wkdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))
outfiledir = os.path.join(wkdir, 'targetfiles', chiptype) # Easy to manage, the generated file path is the specified path under the specific series of "targetfiles"
# write register definition
regdef = GenReg(chiptype)
regdef.write_svd()
if __name__ == '__main__':
main()
運(yùn)行。成功??梢钥吹?,在targetfiles
新建的mm32f0000目錄下,生成了MM32F0000.svd
文件。
圖x 生成新的SVD文件
運(yùn)行成功。
此時(shí),我們已經(jīng)通過sdk-npi-enablement-tool
得到了一個MM32F0000
芯片項(xiàng)目的SVD文件。這個新生成的文件實(shí)際的內(nèi)容還是現(xiàn)有MM32F0020
項(xiàng)目的,仍需要調(diào)整其中的內(nèi)容。但無論如何,創(chuàng)建新芯片項(xiàng)目SVD文件的框架已經(jīng)搭起來了。接下來,需要解決向其中添加新外設(shè)模塊USART
和刪減外設(shè)模塊UART
的問題。
填充外設(shè)模塊的寄存器映射描述文件xlsx
在上一個環(huán)節(jié)中,我們已經(jīng)通過sdk-npi-enablement-tool
得到了一個MM32F0000
芯片項(xiàng)目的SVD文件,創(chuàng)建新芯片項(xiàng)目SVD文件的框架和操作流已經(jīng)搭起來了?,F(xiàn)在,需要解決刪減外設(shè)模塊UART并向其中添加新外設(shè)模塊USART的問題。
在現(xiàn)有項(xiàng)目中刪除模塊相對容易,直接在上文提到的MM32F0000.yaml文件中刪除不需要的模塊的記錄,然后在baseaddr.xlsx
和interrupts.xlsx
文件中刪除對應(yīng)的記錄即可。如果要做得更徹底,還可以繼續(xù)刪掉sdk-npi-enablement-tool\\database\\ip_reg_desp\\mm32f0000
目錄下描述UART模塊寄存器映射的uart.xlsx文件,但因?yàn)樵谏鲜雠渲梦募幸呀?jīng)刪除了對UART模塊的引用,所以此處的uart.xlsx文件被刪與否都不會再起作用。
在現(xiàn)有項(xiàng)目中添加新外設(shè)同刪除模塊對等,只要在需要引用模塊的地方添加新模塊的記錄即可。例如,這里將UART模塊的名字改為USART(相當(dāng)于刪掉了UART模塊后再添加USART)。
- 在
sdk-npi-enablement-tool\\tools\\generator\\yaml\\devices
目錄下的mm32f0000.yaml
文件中,添加USART
模塊的記錄 - 在
sdk-npi-enablement-tool\\resource\\mm32f0000
目錄下的baseaddress.xlsx
文件中,添加USART模塊在存儲空間中的基地址 - 在
sdk-npi-enablement-tool\\resource\\mm32f0000
目錄下的interrupts.xlsx
文件中,添加USART模塊在中斷向量表中的記錄 - 在
sdk-npi-enablement-tool\\database\\ip_reg_desp\\mm32f0000
目錄下,為USART模塊創(chuàng)建描述寄存器及其位域的表格,這個需要如下的操作,從UM手冊文檔中提取內(nèi)容,才能創(chuàng)建生成。
目前,我有USART
模塊的IP Spec文檔IP_USART_DesignSpec_v0.x.docx
,其中包含了對USART模塊中各寄存器及其位域的地址映射信息。
配置sdk-npi-enablement-tool\\tools
目錄下的gen_srctables.py
腳本:
- 指定輸入文件為包含USART模塊中各寄存器及其位域的地址映射信息的
IP_USART_DesignSpec_v0.x.docx
,指定位于sdk-npi-enablement-tool\\resource\\mm32f0000
目錄下。 - 指定輸出路徑在
sdk-npi-enablement-tool\\database\\ip_reg_desp\\mm32f0000
下,腳本會根據(jù)mm32f0000.yaml
文件中指定的模塊清單,匹配傳入文件中的內(nèi)容,如果在mm32f0000.yaml
文件中登記并在傳入文件中找到相關(guān)模塊的記錄,則會在指定路徑下創(chuàng)建這個模塊的單獨(dú)的xlsx文件。
#!usr/bin/python3
#! encoding utf-8
from generator.gen_tables import GenTable
def main():
RegTable = GenTable('mm32f0000', 'IP_USART_DesignSpec_v0.x.docx') # 需修改兩個參數(shù),第一個芯片系列(需小寫),第二個為文件Word文件名
print('Data extraction finished.')
if __name__ == '__main__':
main()
運(yùn)行程序后,在sdk-npi-enablement-tool\\database\\ip_reg_desp\\mm32f0000
目錄下生成了新的usart.xlsx文件。
此時(shí),因?yàn)橐呀?jīng)更新了yaml文件中的配置信息,重新執(zhí)行上節(jié)中生成SVD文件的操作步驟,即可產(chǎn)生包含USART模塊的全新的SVD文件。
圖x 更新USART前的SVD文件片段其中,關(guān)于寄存器字段的描述是中文的,Keil的SVD解析器僅能識別英文。此處需要進(jìn)行一些微調(diào)。故建議使用英文版手冊作為SVD生成過程的數(shù)據(jù)源,或者一種可行的做法,是直接使用寄存器位域名取代位域的解釋,至少先保證SVD文件能夠正常被SVD文件解析器識別。本例中直接修改USART模塊的數(shù)據(jù)源(寄存器映射表)文件,如圖x所示。
圖x USART模塊的寄存器映射表
重新運(yùn)行gen_svdfile.py
,更新成功。
驗(yàn)證
使用sdk-npi-enablement-tool
工具包生成的SVD文件,不一定能夠被Keil的SVD文件完全識別。為此,在正式交付之前,需要驗(yàn)證SVD文件是否可用。CMSIS-SVD提供了一個工具 svdconv.exe
,可以將SVD文件轉(zhuǎn)換成各種其他源文件,其中最基本的功能,就是驗(yàn)證SVD文件的有效性。
在sdk-npi-enablement-tool\\tools
目錄下找到SVDConv.exe
工具,并在命令行下運(yùn)行,傳入剛生成的mm32f0000.svd文件。
indMotion@PF2LD92H MINGW64 /d/workspace/sdk-npi-enablement-tool/tools
$ svdconv.exe
CMSIS-SVD SVD Consistency Checker / Header File Generator V3.3.42
Copyright (C) 2010-2022 ARM Ltd and ARM Germany GmbH. All rights reserved.
Usage:
SVDConv.exe < SVD file > [Options]
Options:
-o < output path > Output Path, default current directory
-b < log file > Log file for Messages
--generate=header Generate CMSIS header file
--fields=struct Generate struct/union for bitfields
--fields=macro Generate macros for bitfields
--fields=struct-ansic Generate structs for bitfields (ANSI C)
--fields=enum Generate enumerated values for bitfields
--debug-headerfile Add Addresses to Registers comments
--generate=partition Generate CMSIS partition file
-x [Mxxx, INFO, WARNING] Suppress Message, Warnings or Infos
-h, -? Show this help
Examples:
Check only > SVDConv.exe myDevice.svd
Header Generation > SVDConv.exe myDevice.svd --generate=header
MindMotion@PF2LD92H MINGW64 /d/workspace/sdk-npi-enablement-tool/tools
$ svdconv.exe MM32F0000.svd
CMSIS-SVD SVD Consistency Checker / Header File Generator V3.3.42
Copyright (C) 2010-2022 ARM Ltd and ARM Germany GmbH. All rights reserved.
Arguments: "MM32F0000.svd"
...
** INFO M304: MM32F0000.svd (Line 6029)
Interrupt number overwrite: '19 : TIM14' (Line 5715)
Found 26 Error(s) and 0 Warning(s).
這里發(fā)現(xiàn)有26個error。經(jīng)排查發(fā)現(xiàn),是因?yàn)榇嬖谟械募拇嫫鞯刂酚貌煌拿置?/p>
*** ERROR M339: MM32F0000.svd (Line 5128)
Register 'CCMR1_INPUT' (read-write) (@0x00000018:32) has same address or overlaps 'CCMR1_OUTPUT' (read-write) (@0x00000018:32) (Line 5069)
*** ERROR M339: MM32F0000.svd (Line 5128)
Register 'CCMR1_INPUT' (read-write) (@0x00000018:32) has same address or overlaps 'CCMR1_OUTPUT' (read-write) (@0x00000018:32) (Line 5069)
這類問題需要在SVD文件中對應(yīng)寄存器的定義中添加
標(biāo)簽。例如在CCMR_Input中的寫法。注意,在后續(xù)版本的sdk-npi-enablement-tool
中,也將會加入這樣的生成策略,但在目前版本中,需要手動添加,以清理錯誤。
< register >
< name >CCMR1_Input< /name >
< displayName >CCMR1_Input< /displayName >
< description >capture/compare mode register 1 (input mode)< /description >
< alternateRegister >CCMR1_Output< /alternateRegister >
< addressOffset >0x18< /addressOffset >
< size >0x20< /size >
< access >read-write< /access >
< resetValue >0x00000000< /resetValue >
< fields >
< field >
< name >IC2F< /name >
< description >Input capture 2 filter< /description >
< bitOffset >12< /bitOffset >
< bitWidth >4< /bitWidth >
< /field >
另外,還有一些其他細(xì)微的地方需要人工處理,例如,由于sdk-npi-enablement-tool
中腳本使用的正則表達(dá)式?jīng)]有完整呈現(xiàn)出寄存器命名的套路,有一些寄存器命名存在重疊、重復(fù)等等,這些問題在當(dāng)前版本的軟件中,處理能力有限。后續(xù)版本會針對這些情況做一些限定,或者使用更強(qiáng)規(guī)則的正則表達(dá)式對寄存器名進(jìn)行匹配和甄別。
總之,最后清理掉所有的ERROR就算大功告成。
生成芯片頭文件
sdk-npi-enablement-tool
工具包中的gen_sdkfile.py
工具,可用于生成芯片頭文件。實(shí)際上CMSIS-SVD中的SVDConv.exe工具也可以從SVD文件生成CMSIS規(guī)范的頭文件,但我們需要生成頭文件的宏定義要全部大寫,而不是SVDConv.exe工具生成的存在部分小寫字母的宏定義代碼,因此,仍然需要gen_sdkfile.py
工具從sdk-npi-enablement-tool
工具包的數(shù)據(jù)庫中生成描述全部芯片外設(shè)模塊在存儲空間中映射關(guān)系的芯片頭文件。在目前正在開發(fā)的版本中,生成頭文件的機(jī)制將有所改變,屆時(shí)將會基于SVD文件生成頭文件,類似于實(shí)現(xiàn)了一個Python版本的SVDConv.exe。
在sdk-npi-enablement-tool\\tools
目錄下配置腳本文件gen_sdkfile.py
,指定chiptype
的值為mm32f0000,然后,運(yùn)行。
#!usr/bin/python3
#! encoding utf-8
import os
import generator.soc_info
from generator.gen_dma_requests import GenDMARequests
from generator.gen_interrupts import GenInt
from generator.gen_regsvd import GenReg
from generator.gen_baseaddr import GenBase
def main():
chiptype = 'mm32f0000' # change here to suit to different chip series
# output dir.
wkdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))
outfiledir = os.path.join(wkdir, 'targetfiles', chiptype)
# generate interruupt vector for startup file.
interrupts = GenInt(chiptype)
interrupts.get_sVector(outfiledir)
# generate header file for registers.
regdef = GenReg(chiptype)
regdef.write_reg()
if __name__ == '__main__':
main()
運(yùn)行成功后,在sdk-npi-enablement-tool\\targetfiles\\mm32f0000
目錄下生成了新文件MM32F0000\\mm32f0000.h
和interrupt.h
文件,其中,interrupt.h
文件中包含中斷服務(wù)函數(shù)名的清單,這個清單可用于進(jìn)一步創(chuàng)建在不同工具鏈下的啟動代碼。生成的mm32f0000.h
文件,即為可發(fā)布的芯片頭文件。
圖x 新生成的芯片頭文件至此,我們已經(jīng)為新芯片項(xiàng)目MM32F0000
生成了芯片頭文件。
Conclusion
在本文中,記錄了使用sdk-npi-enablement-tool
生成設(shè)備支持包中描述芯片寄存器存儲映射的SVD文件和芯片頭文件的過程。
- 在執(zhí)行操作之前,需要準(zhǔn)備好包含外設(shè)模塊寄存器描述信息的UM文檔的docx版本,
sdk-npi-enablement-tool
中的腳本會解析docx文件,從中提取描述寄存器及其位域的表格,先進(jìn)行數(shù)據(jù)清洗,然后以xlsx文件的格式,將各個外設(shè)模塊的寄存器寄存器映射信息分別保存成獨(dú)立的文件。這些文件同IC設(shè)計(jì)的IP倉庫一一對映,形成外設(shè)模塊寄存器映射的數(shù)據(jù)庫。 - 需要在yaml數(shù)據(jù)庫中創(chuàng)建新芯片的記錄文件,這些文件描述了某一款芯片包含哪些外設(shè)模塊,相當(dāng)于是IC設(shè)計(jì)過程中的SoC集成過程。
- 然后,就可以調(diào)用一系列腳本工作逐步生成需要的文件
- 使用
gen_srctables.py
從原始的doc格式的UM文檔中提取寄存器分布信息存放為xlsx記錄 - 使用
gen_svdfile.py
從描述外設(shè)模塊寄存器分布的xlsx文件生成SVD文件 - 使用
gen_sdkfile.py
從xlsx記錄中生成包含中斷向量表等具體芯片寄存器清單的頭文件
- 使用
sdk-npi-enablement-tool
工具包目前保持在迭代更新當(dāng)中,仍存在一些問題,需要少量的人工介入才能通暢地完成生成文件的過程,但已經(jīng)能夠作為生產(chǎn)力工具對微控制器產(chǎn)品的軟件開發(fā)工作提供完備的技術(shù)服務(wù)。在接下來將要發(fā)布的版本中,將會不斷修復(fù)已知問題,優(yōu)化使用體驗(yàn)。
-
芯片
+關(guān)注
關(guān)注
452文章
50224瀏覽量
420996 -
寄存器
+關(guān)注
關(guān)注
31文章
5295瀏覽量
119838 -
文件
+關(guān)注
關(guān)注
1文章
561瀏覽量
24672 -
SVD
+關(guān)注
關(guān)注
0文章
21瀏覽量
12151 -
Overview
+關(guān)注
關(guān)注
0文章
8瀏覽量
7269
發(fā)布評論請先 登錄
相關(guān)推薦
評論