1. 问题背景
KW45是继KW38的下一代BLE芯片,符合 BLE5.3标准,最多可同时支持24个安全连接。在KW系列中KW45首次采用三核架构:一个96MHz的CM33应用核、一个处理Radio相关任务的CM3内核和一个专门处理加密安全称为EdgeLock(类似HSM)M0+核。其中CM3内核用于处理BLE controller相关的任务, CM33内核可以更专注于处理BLE Host层,GATT层和应用相关的任务,除此之外CM3内核还拥有独立的Flash和SRAM资源,不占用芯片本身内置的1M Flash和128K RAM,从而可以将CM33主核上的内存资源和处理资源释放给用户应用空间。EdgeLock类似HSM的功能,提供常见AES/ECC/RSA等对称非对称加解密的硬件加速、密钥存储操作和安全生命周期管理,最大限度地减少了主核工作量。
尽管架构更复杂,但因为后两者的软件是由芯片厂商提供,无需用户开发,所以并没有额外增加多少工作量,其和以前KW3X系列一个最大不同是,CM3的软件也称为NBU需要用户自行烧录(这也就是为何常有客户反馈自己做的板子运行无线相关的例子运行时总是卡在一个地方的原因),之所以这块没有固化在芯片内内部有两方面考虑,一方面方便用户更新支持到更新的BLE feature,例如说channel sounding,而一方面方便用户可以对官方提供的NBU Image 进行个性化的签名,防止未认证的恶意代码启动,从而增加系统安全等级。所以这里就需要工具完成密钥的生成,image的加密,加密image的烧录过程,为方便用户,原厂提供了一套开源的SPSDK脚本方便用户使用,但牵涉到环境搭建,尤其有很多Key的生成,对新手来说有些挑战,本文第4章节会给出一个step by step的教程,方便开发者更系统的去看每一个步骤在做什么,需要修改什么,先解决怎么做的问题,至于为什么这么做,每个Key的作用需要用户结合RM手册去查看。同时随着信息安全越来越受到重视,很多产品量产后会考虑临时禁止调试口,在需要时通过特定的方式再去使能,对应到KW45就是debug authentication,RM文档更多从原理性介绍,给出的是JTAG操作伪指令,至于如何在SPSDK中实现未有提及,本文会在第5章节重点介绍相关实操。
2. SPSDK概览
SPSDK的全称是Secure Provisioning SDK,它是一个统一、可靠且易于使用的Python SDK 库,适用于NXP MCU 产品组合,客户帮助客户快速完成从原型设计到生产部署的整个过程。该库允许用户与设备连接和通信、配置设备、准备、下载和上传数据(包括安全操作)。
在SPSDK包中,提供了以下两种方式供用户使用:
应用程序:用户可以使用 Python虚拟环境命令行或者Jupyter Notebook(推荐方式)调用各个应用程序;
API接口:以Python 库的形式提供,方便用户或者工具厂商增加自定义功能和自定义安全部署;
3. 准备工作:
安装Python3.7,建议使用3.7-3.11版本,不支持Python2.x;
安装SPSDK,可以直接在cmd中完成;
安装jupyter
d: cdD:YU_IOTKW45_3SPSDK D:YU_IOTKW45_3SPSDK>python-mvenvspsdk_pyenv D:YU_IOTKW45_3SPSDK>spsdk_pyenvScriptsactivate D:YU_IOTKW45_3SPSDK>python-mpipinstall--upgradepip D:YU_IOTKW45_3SPSDK>pipinstallspsdk D:YU_IOTKW45_3SPSDK>spsdk--help D:YU_IOTKW45_3SPSDK>pip3installjupyter #以上spsdk和jupyter的安装需在Python虚拟环境启动后进行,否则安装无效;
下载spsdk源文件或者AN13883的附件,两者大同小异,此笔记以后者为示例。
spsdk源文件:https://spsdk.readthedocs.io/en/latest/spsdk.html
AN13883源文件:
4. 在ISP下载KW45 Radio firmware过程
OEM公私钥和证书文件的生成
SB3文件的生成
image烧录过程
D:YU_IOTKW45_3SPSDK>spsdk_pyenvScriptsactivate (spsdk_pyenv)D:YU_IOTKW45_3SPSDK>cdD:YU_IOTKW45_3SPSDKAN13883SWAN_SPSDK (spsdk_pyenv)D:YU_IOTKW45_3SPSDKAN13883SWAN_SPSDK>jupyter-lab
此后,会有一个Jupyter的网页交互产生,如下图,然后就是傻瓜式的step by step执行脚本。
详细步骤如下:
4.1. RoTKs 和ISK的生成
此过程会生成4对RoTKs (Root of Trust Keys) 和1对ISK (Image Signing Certificate), ISK是可选的,会在生成SB3文件时选择是否使用。
#generateprivatekeybasedonsecp384r1curve-ROTK0 ROTK0_PRIVATE_KEY_PATH=WORKSPACE+"ec_pk_secp384r1_cert0.pem" ROTK0_PUBLIC_KEY_PATH=WORKSPACE+"ec_pk_secp384r1_cert0.pub" %!nxpcrypto$VERBOSITYkeygenerate-ksecp384r1$ROTK0_PRIVATE_KEY_PATH--force assert_exit_code==0 #verifythatkeysweregenerated assertos.path.exists(ROTK0_PRIVATE_KEY_PATH) assertos.path.exists(ROTK0_PUBLIC_KEY_PATH) .....
4.2. X509证书生成的yml模板生成
#obtainatemplateforrootcertROTK0 ROOT0_CERT_CONFIG_PATH=WORKSPACE+"cert0_template.yml" %!nxpcrypto$VERBOSITYcertget-cfg-template$ROOT0_CERT_CONFIG_PATH--force assert_exit_code==0
证书模板如下,包括issue,subject,证书序列号、有效期、签发使用的私钥,对应公钥等信息,更多证书格式信息可以参考https://github.com/pyca/cryptography,cryptography/src/cryptography/x509/oid.py
issuer: COMMON_NAME: NXP COUNTRY_NAME: CZ LOCALITY_NAME: Roznov pod Radhostem STATE_OR_PROVINCE_NAME: Morava STREET_ADDRESS: 1.maje 1009 ORGANIZATION_NAME: SPSDK Team # ============================================== # Subject identification fields # ============================================== # All available option can be found within class NameOID in # cryptography/src/cryptography/x509/oid.py at https://github.com/pyca/cryptography subject: COMMON_NAME: NXP - SPSDK COUNTRY_NAME: CZ LOCALITY_NAME: Roznov pod Radhostem STATE_OR_PROVINCE_NAME: Morava STREET_ADDRESS: 1.maje 1009 ORGANIZATION_NAME: SPSDK Team POSTAL_CODE: 756 61 # ============================================== # The certificate settings # ============================================== # Path, where issuer private key is stored issuer_private_key: issuer_key.pem # Path, where subject public key is stored subject_public_key: subject_key.pub # Serial number of certificate serial_number: 12346578 # Validity duration in days duration: 3650 # ============================================== # Certificate basic extensions # ============================================== extensions: BASIC_CONSTRAINTS: # Delegate certificate as a signing authority to create an intermediate certificates. ca: false # Valid values true|false # Integer length of the path of certificate signature from a given certificate, back to the root certificate path_length: 0
4.3. 正式证书生成
#Generaterootcertificates0 %!nxpcrypto$VERBOSITYcertgenerate-c$ROOT0_CERT_CONFIG_PATH-o$ROOT_0_CERT_PATH--force assert_exit_code==0 #Generaterootcertificates1 %!nxpcrypto$VERBOSITYcertgenerate-c$ROOT1_CERT_CONFIG_PATH-o$ROOT_1_CERT_PATH--force assert_exit_code==0 #Generaterootcertificates2 %!nxpcrypto$VERBOSITYcertgenerate-c$ROOT2_CERT_CONFIG_PATH-o$ROOT_2_CERT_PATH--force assert_exit_code==0 #Generaterootcertificates3 %!nxpcrypto$VERBOSITYcertgenerate-c$ROOT3_CERT_CONFIG_PATH-o$ROOT_3_CERT_PATH--force assert_exit_code==0 #GenerateISKcertificate %!nxpcrypto$VERBOSITYcertgenerate-c$ISK_CERT_CONFIG_PATH-o$ISK_CERT_PATH--force assert_exit_code==0
如下是cert0的内容,但是因为其是base64编码,不方便查看,如果有兴趣可以通过Openssl去读取证书的信息和yml文件对照。
opensslx509-incacert.pem-noout-text #openssl在Git安装后可以直接使用
4.4 对称密钥SB3KDK生成
该Key用于加密SB3 key block,会被program到fuse,后续无法再次修改,该生成步骤也可以放在前面去执行。
importos,binascii SB3KDK_KEY_PATH=WORKSPACE+"sb3kdk.txt" withopen(SB3KDK_KEY_PATH,"wb")asf: f.write(binascii.b2a_hex(os.urandom(32))) assertos.path.exists(SB3KDK_KEY_PATH)
4.5. SB3配置文件生成
该步骤会使用到SPSDK的npximage.exe应用程序
WORKSPACE="workspace/"#changethistopathtoyourworkspace VERBOSITY="-v"#verbosityofcommands,mightbe-vor-vvfordebugorblankfornoadditionalinfo SB31_TEMPLATE_PATH=WORKSPACE+"sb31_config.yml" %!nxpimage$VERBOSITYsb31get-template-fkw45xx-o$SB31_TEMPLATE_PATH assert_exit_code==0 assertos.path.exists(SB31_TEMPLATE_PATH)
需要注意的是:
需要手动注释掉binaryCertificateBlock: my_isk_cert.bin,否则会后面SB3正式生成时会报错。
useIsk: false意味着没有使用ISK,需要修改配置文件
#binaryCertificateBlock:my_isk_cert.bin commands: -erase: address:'0x48800000' size:'0x30000' -load: address:'0x48800000' file:kw45b41_nbu_ble_hosted_04.xip containerConfigurationWord:0 containerKeyBlobEncryptionKey:workspace/sb3kdk.txt containerOutputFile:sb3.sb3 description:384_none_nbu_only family:kw45xx firmwareVersion:0 isNxpContainer:false iskSignProvider:type=file;file_path=my_isk_prv_key.pem kdkAccessRights:3 mainRootCertId:0 mainRootCertPrivateKeyFile:workspace/ec_pk_secp384r1_cert0.pem rootCertificate0File:workspace/ec_secp384r1_cert0.pem rootCertificate1File:workspace/ec_secp384r1_cert1.pem rootCertificate2File:workspace/ec_secp384r1_cert2.pem rootCertificate3File:workspace/ec_secp384r1_cert3.pem rootCertificateEllipticCurve:secp384r1 signingCertificateConstraint:0 useIsk:false
4.6 SB3文件的生成
上面已经生成了证书和key,按照sb31_config.yml 的配置生成
%!nxpimage$VERBOSITYsb31export$SB31_TEMPLATE_PATH assert_exit_code==0 assertos.path.exists(WORKSPACE+SB31_FILE_PATH) INFOSB3KDK:9e1432fc4869435ee6f396dccba9595933c8d1d2ad40385927f3a8b9f58162d7 INFORoTKTH:5e03e6649294d19fa31b19e17895184dc16149e5c2748bc394db46249a6ef29ca1f14dcd67169d7744c5c1a9025b981a
4.7 SB3KDK和ROTKH的烧录(研发阶段可跳到此步骤)
在NXP demo板芯片内已经预烧录了SB3KDK和ROTKTH,所以可以直接跳到这个步骤。
把J25连到2-3,按住SW4,重新上电
修改串口号,尝试连接
#choosecomport UART_CONNECTION="-pcom14" %!blhost$UART_CONNECTIONget-propertycurrent-version assert_exit_code==0
fuses with keys/RoTKTH
此过程是不可逆的,强烈建议在研发阶段使用NXP提供的默认SB3KDK和ROTKTH;
#Increasevoltageforfuseburning %!blhost$UART_CONNECTIONset-property0x161 #programSB3KDK(CUST_PROD_OEMFW_ENC_SK) #putvalueSB3KDKgeneratedbynxpimage #%!blhost$UART_CONNECTIONfuse-program0x20[["SubstitutethiscommentbytheSB3KDKgeneratedkeyoutputinsectionSB3.1generation.Examplebelow."]] #exampleline:%!blhost$UART_CONNECTIONfuse-program0x20[[7aa7ef9813b3561257b8837dab26225301df3511217f2733c71dadcd447722d1]] %!blhost$UART_CONNECTIONfuse-program0x20[[7aa7ef9813b3561257b8837dab26225301df3511217f2733c71dadcd447722d1]] #programRoTKTH(CUST_PROD_OEMFW_AUTH_PUK) #putvalueRoTKTHgeneratedbynxpimage #%!blhost$UART_CONNECTIONfuse-program0x1F[["SubstitutethiscommentbytheRoTKTHgeneratedkeyoutputinsectionSB3.1generation.Examplebelow."]] #exampleline:%!blhost$UART_CONNECTIONfuse-program0x1F[[650d8097079ff27a3e8a2da14781b922fd8295b6c00bfa067f00e87f1a16b8b304bf710d45cbd591e2e24be83183922c]] %!blhost$UART_CONNECTIONfuse-program0x1F[[650d8097079ff27a3e8a2da14781b922fd8295b6c00bfa067f00e87f1a16b8b304bf710d45cbd591e2e24be83183922c]] #ProgramTZM_ENfuse,thisfusewasmissedduringmanufacturingoffirstKW45samples.WithoutTZM_ENfuseset,theS3MUAsemaphoreisnotworkingproperlyandaftergettingofownership,thewriteaccesstoTRregistercausingBUSFault.IfS3MUAsemaphoreisnotusedduringcommunicationwithS3MUA(e.g.onlyonethreadiscommunicatingwithS3MUA(EdgeLock)),thenTZM_ENfusecanremain0. %!blhost$UART_CONNECTIONfuse-program0xD[[01]] #Setvoltagetonormalvalue %!blhost$UART_CONNECTIONset-property0x160
4.8 SB3文件烧录
此步骤需要在ISP模式下执行,即把J25连到2-3,按住SW4,重新上电
#uploadsSB3.1 SB31_FILE_FINAL=WORKSPACE+SB31_FILE_PATH assertos.path.exists(SB31_FILE_FINAL) %!blhost$UART_CONNECTIONreceive-sb-file$SB31_FILE_FINAL assert_exit_code==0
至此,生成加密签名文件的工作结束。
5. Debug authentication实现步骤
在做Debug authentication之前,需要大概了解下KW45启动的过程,如下图,在启动后,会先去检查用户是否使能dual image启动,如果是就去运行最新版本,如果不是就会先去Boot image base address处去查看是否有有效的PC和SP,对于KW45来说如果未使能dual image这个地址就是0x00。如果PC和SP有效就会先去对用户应用程序验签,如果失败,就会回到ISP模式,如果用户应用程序验签通过,ROM就会继续对NBU进行验签,如果验签通过才会真正进入到客户正常应用程序。而Debug authentication是贯穿在上面整个过程中的,需要在每一个步骤都能进行debug。前文提到,Debug authentication的目的是在量产禁止JTAG仿真器接口后,通过证书认证方式再去打开Debug口的访问权限,所以如果想去使能这个功能就需要做些额外的操作,譬如说将lifecycle推进到OEM secure world,生成debug authentication的证书,输入命令等,如下分别讲述。
5.1 关闭JTAG调试功能,
OEM Open->OEM Secure World Close模式
实现方式有两种:第一种借助于单独的blhost程序,第二种使用SPSDK中的app实现
::Increasevoltageforfuseburning ..inlhost.exe-pCOM14set-property0x161 ::programSB3KDK(CUST_PROD_OEMFW_ENC_SK) ..inlhost.exe-pCOM14--fuse-program0x20"{{7aa7ef9813b3561257b8837dab26225301df3511217f2733c71dadcd447722d1}}" ::programRoTKTH(CUST_PROD_OEMFW_AUTH_PUK) ..inlhost.exe-pCOM14--fuse-program0x1F"{{650d8097079ff27a3e8a2da14781b922fd8295b6c00bfa067f00e87f1a16b8b304bf710d45cbd591e2e24be83183922c}}" ::ProgramTZM_ENfuse,thisfusewasmissedduringmanufacturingoffirstKW45samples.WithoutTZM_ENfuseset,theS3MUAsemaphoreisnotworkingproperlyandaftergettingofownership,thewriteaccesstoTRregistercausingBUSFault.IfS3MUAsemaphoreisnotusedduringcommunicationwithS3MUA(e.g.onlyonethreadiscommunicatingwithS3MUA(EdgeLock)),thenTZM_ENfusecanremain0. ..inlhost.exe-pCOM14--fuse-program0xD"{{1}}" ::Setvoltagetonormalvalue ..inlhost.exe-pCOM14set-property0x160
成功后可以回读0x0A fuse地址,查看当前lifecycle状态,成功后如果使用Jlink去连接显示如下Secure debug disabled:
5.2 生成DC使用的公私钥对
#generateprivatekeybasedonsecp384r1curve-Debug ROTK0_Debug_PRIVATE_KEY_PATH=WORKSPACE+"ec_pk_secp384r1_cert0_debug.pem" ROTK0_Debug_PUBLIC_KEY_PATH=WORKSPACE+"ec_pk_secp384r1_cert0_debug.pub" %!nxpcrypto$VERBOSITYkeygenerate-ksecp384r1$ROTK0_Debug_PRIVATE_KEY_PATH--force assert_exit_code==0 #verifythatkeysweregenerated assertos.path.exists(ROTK0_Debug_PRIVATE_KEY_PATH) assertos.path.exists(ROTK0_Debug_PUBLIC_KEY_PATH)
5.3 DC证书模板生成
#obtainatemplatefordebugcert DC_CONFIG_PATH=WORKSPACE+"DC.yml" %!nxpdebugmboxget-template-f$DC_CONFIG_PATH assert_exit_code==0
#Copyright2023NXP # #SPDX-License-Identifier:BSD-3-Clause #DCBlockstructure #============================================ #============================================ #============================================ #===Version=== #============================================ #===SocClass=== #============================================ #===UUID=== #============================================ #===RoTMetaSHA256offollowing:=== #===RoTKey0SHA256=== #===RoTKey1SHA256=== #===RoTKey2SHA256=== #===RoTKey3SHA256=== #============================================ #===DebuggerKeyDCK(Pub):=== #===Mod:2048Exp:32=== #============================================ #===CCSOCU=== #============================================ #===CCVU=== #============================================ #===CB=== #============================================ #===RoTKey(pub)=== #===Mod:2048Exp:32=== #============================================ #============================================ #===Signatureofallblock=== #===SHA256ofwholeblock=>RSA(RoTK)=== #============================================ #============================================ #============================================ #============SoCClass============ #AuniqueidentifierforasetofSoCsthatrequirenoSoC-specificdifferentiationin #theirdebugauthentication.Themainusageistoallowadifferentsetofdebug #domainsandoptionstobenegotiatedbetweenthedeviceconfigurationand #credentials.AclasscancontainjustasinglerevisionofasingleSoCmodel,ifthe #granularityofdebugcontrolwarrantsit. #Exampleslistofpossiblesettings: #0x0000:i.MXRT595,i.MXRT685, #0x0001:LPC550x,LPC55s0x,LPC551x,LPC55s1x,LPC552x,LPC55s2x,LPC55s6x #0x0004:LPC55s3x,RW61x #0x0005:KW45xx/K32W1xx #0x0006:MCXN9xx(A0) #0x0007:MCXN9xx(A1) #0x000A:RW61x(A2) #0x5254049C:i.MXRT118x socc:0x0005 #============DeviceUUID============ #128-bitIETFRFC4122compliantnon-sequentialUniversallyUniqueIdentifier(UUID) uuid:"00000000000000000000000000000000" #============SoCUsage============ #ACC(constraint)valuethatisabitmask,andwhosebitsareusedinan #SoCC-specificmanner.Thesebitsaretypicallyusedforcontrollingwhichdebug #domainsareaccessedviatheauthenticationprotocol,butdevice-specificdebug #optionscanbemanagedinthiswayalso. cc_socu:0xFFFF #============VendorUsage============ #ACC(constraint)valuethatisopaquetothedebugauthenticationprotocolitselfbut #whichcanbeleveragedbyvendorsinproduct-specificways. cc_vu:0 #============CredentialBeacon&Authenticationbeacon============ #Avaluethatispassedthroughtheauthenticationprotocol,whichisnotinterpreted #bytheprotocolbutisinsteadmadevisibletotheapplicationbeingdebugged.A #credentialbeaconisassociatedwithaDCandisthereforevendor/RoT-signed.An #authenticationbeaconisprovidedandsignedbythedebuggerduringthe #authenticationprocess. cc_beacon:0 #============RoTmeta-data============ #TheRoTmeta-datarequiredbythedevicetocorroborate;theROTIDsentinthe #DAC,thefieldinthisDC,andanyadditionalRoTstatethatisnotstoredwithinthe #device.ThisallowsdifferentRoTidentification,managementandrevocation #solutionstobehandled. rot_meta: -../kw45_debug_auth/secp384r1_private_key0.pub -../kw45_debug_auth/secp384r1_private_key1.pub -../kw45_debug_auth/secp384r1_private_key2.pub -../kw45_debug_auth/secp384r1_private_key3.pub #============RoTIdentifier============ #RoTIDallowsthedebuggertoinferwhichRoTpublickey(s)areacceptabletothe #device.Ifthedebuggercannotordoesnotprovidesuchacredential,the #authenticationprocesswillfail. rot_id:0 #============DebugCredentialKey============ #Auser-ownedkeypair.ThepublicpartofthekeyisassociatedwithaDC,the #privatepartisheldbytheuserandusedtoproducesignaturesduring #authentication. dck:../kw45_debug_auth/secp384r1_private_dck.pub #================================================================================================== #Signatureconfigurationarea #================================================================================================== #TherearetwowayshowsignthefinalDCdatablob. # #1.Incasethatyouisavailableprivatepairforrot_metawithindexrot_idjustusefirstsimplestyle #touseitbyrotkkey.Asasecondwaytodosameisusesign_provider(orsignProvider-bothareaccepted)optionwith'type=file'. # #2.ForcasethatDebugCredentialfilesaregeneratedinuntrustedenvironment(withoutaccesstoRoTprivatekeys), #thereisoptiontouseplugin(examplehowtocreateownpluginisin:./SPSDK/examples/dat/hsm/).Theplugin #hassimpleinterfacethatallowshandleDCdatablobintopluginwithindexofRoTmetapublickeytogetbacksigned #DCimage. # #Thoseoptionsareexclusive,soonlyoneoptioncouldbeusedtosigntheDC. #============SignatureProvider============ #Tousesigningproviderexamples # #sign_provider:'type=file;file_path=./hsm/k0_cert0_2048.pem' #sign_provider::'type=sasp;key_number=0' #============RoTsignatureprivatekey============ #PrivatekeyforfortheRoTmetachosenbyrot_idtosigntheimage. rotk:../kw45_debug_auth/secp384r1_private_key0.pem
此处的公钥是NXP生成的默认值,这个是客户拿不到的
5.4 DC证书生成
%!nxpdebugmbox-p2.1gendc-cD:YU_IOTKW45_3SPSDKdebug_authenworkspacecert0_template_debug.ymlD:YU_IOTKW45_3SPSDKdebug_authenworkspacedebug_authen.cert1 %!nxpdebugmbox-p2.1gendc-cD:YU_IOTKW45_3SPSDKdebug_authenkw45_debug_auth est.ymlD:YU_IOTKW45_3SPSDKdebug_authenkw45_debug_auth est.cert
5.5 Debug认证过程
nxpdebugmboxstart nxpdebugmbox-v-p2.1-ijlinkauth-b0x0–cD:YU_IOTKW45_3SPSDKdebug_authenworkspacedebug_authen.cert–kD:YU_IOTKW45_3SPSDKdebug_authenkw45_debug_authsecp384r1_private_dck.pem nxpdebugmbox-v-p2.1-ijlinkauth-b0x0–cD:YU_IOTKW45_3SPSDKdebug_authenkw45_debug_auth est.cert–kD:YU_IOTKW45_3SPSDKdebug_authenkw45_debug_authsecp384r1_private_dck.pem
执行debug authen的命令和步骤如下,可以看到在debug authen成功后会显示successful。
此时再去用Jlink尝试连接KW45,会显示secure debug enabled.
6. 总结
至此,完成了对在ISP下KW45 Radio firmware下载过程和Debug authentication实现步骤的讲解。以上步骤确实比较多,笔者也摸索了好久,但熟悉其原理和每一步的执行目的后,可以简化成几个自定义的脚本,在开发阶段建议使用NXP默认的Key和证书,在量产阶段再根据自定义的key和证书做自定义。
审核编辑:汤梓红
-
芯片
+关注
关注
455文章
50732浏览量
423278 -
mcu
+关注
关注
146文章
17135浏览量
351031 -
内核
+关注
关注
3文章
1372浏览量
40282 -
代码
+关注
关注
30文章
4780浏览量
68539 -
DEBUG
+关注
关注
3文章
93浏览量
19910
原文标题:KW45使用SPSDK进行代码更新和debug authentication指南
文章出处:【微信号:pzh_mcu,微信公众号:痞子衡嵌入式】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论