S32K3xx系列在未使用 HSE 时,使用密码限制JTAG调试访问
目录前提整体流程设置ADKP设置LC推进生命周期查看解锁调试接口小结前提在芯片量产阶段通常需要关闭JTAG调试口。针对NXP的K3系列芯片对于未使用过HSE的工程师可设置密码ADKP来实现JTAG的禁用。整体流程第一设置ADKP即调试密码第二设置LC推进生命周期第三使用PE官方的脚本解锁调试设置ADKP这里只需要设置16Byte的密码0x1B000080-0x1B00008F剩余的是预留位(0x1B000090-0x1B00009F)。注意一点ADKP写入后无法变更且必须在LC推进之前设置否则会跑飞。boolean Set_Jtag_ADKP(void)//一旦写入无法变更 { //ADKP uint8_t FLS_MASTER_ID 0U; uint8_t FLS_BUF_SIZE16U; uint32_t FLS_SECTOR_ADDR0x1B000080U; uint8 TxBuffer[16] {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}; /* Password */ if(*((uint32*)FLS_SECTOR_ADDR)!0xFFFFFFFF) //已写入ADKP { return 1; } C40_Ip_StatusType C40_Ip_StatusC40_Ip_Init(C40_Ip_InitCfg); C40_IP_DEV_ASSERT(C40_Ip_Status STATUS_C40_IP_SUCCESS ); uint8_t VSectorC40_Ip_GetSectorNumberFromAddress(FLS_SECTOR_ADDR); //unlock do{ C40_Ip_ClearLock(VSector, FLS_MASTER_ID); }while(0x09!C40_Ip_GetLock(VSector)); //Erase C40_Ip_MainInterfaceSectorErase(VSector, FLS_MASTER_ID); do{ C40_Ip_StatusC40_Ip_MainInterfaceSectorEraseStatus(); }while(C40_Ip_StatusSTATUS_C40_IP_BUSY); C40_IP_DEV_ASSERT(C40_Ip_Status STATUS_C40_IP_SUCCESS ); //Write C40_Ip_MainInterfaceWrite(FLS_SECTOR_ADDR, FLS_BUF_SIZE,TxBuffer , FLS_MASTER_ID); do{ C40_Ip_StatusC40_Ip_MainInterfaceSectorEraseStatus(); }while(C40_Ip_StatusSTATUS_C40_IP_BUSY); C40_IP_DEV_ASSERT(C40_Ip_Status STATUS_C40_IP_SUCCESS ); return C40_Ip_Status; }设置LC推进生命周期LifeCycle是芯片内部的状态机制在不同的LC状态支持某些特定的功能和配置。S32K3有4个Lifecycle阶段CUST_DEL、OEM_PROD、IN_FIELD、FA。出厂默认是CUST_DEL调试接口无限制。我们需要将其推进到限制更严格的阶段比如OEM_PROD。修改LCW为指定的值复位后SBAF安全启动辅助固件会根据LCW演进到相应的Lifecycle• LCW 0xDADADADA advances LC to OEM_PROD• LCW 0xBABABABA advances LC to IN_FIELD注意一旦成功推进LC则无法再回退。0x004EA000U可以是除了HSE区域以外的任何Pflash地址建议是APP内存后面选一块Sector。boolean Set_LC_OEM_PROD(void)//一旦写入无法变更 { uint8_t FLS_MASTER_ID 0U; uint8_t FLS_BUF_SIZE8U; uint32_t FLS_SECTOR_ADDR0x004EA000U; uint8_t LC_TxBuffer[8] {0xDA, 0xDA, 0xDA, 0xDA, 0x0, 0x0, 0x0, 0x0}; /* Minimum data length 8 bytes */ if(*((uint32*)FLS_SECTOR_ADDR)!0xFFFFFFFF) //已写入LC { return 1; } C40_Ip_StatusType C40_Ip_StatusC40_Ip_Init(C40_Ip_InitCfg); C40_IP_DEV_ASSERT(C40_Ip_Status STATUS_C40_IP_SUCCESS ); uint8_t VSectorC40_Ip_GetSectorNumberFromAddress(FLS_SECTOR_ADDR); //unlock do{ C40_Ip_ClearLock(VSector, FLS_MASTER_ID); }while(0x09!C40_Ip_GetLock(VSector)); //Erase C40_Ip_MainInterfaceSectorErase(VSector, FLS_MASTER_ID); do{ C40_Ip_StatusC40_Ip_MainInterfaceSectorEraseStatus(); }while(C40_Ip_StatusSTATUS_C40_IP_BUSY); C40_IP_DEV_ASSERT(C40_Ip_Status STATUS_C40_IP_SUCCESS ); //Write C40_Ip_MainInterfaceWrite(FLS_SECTOR_ADDR, FLS_BUF_SIZE,LC_TxBuffer , FLS_MASTER_ID); do{ C40_Ip_StatusC40_Ip_MainInterfaceSectorEraseStatus(); }while(C40_Ip_StatusSTATUS_C40_IP_BUSY); C40_IP_DEV_ASSERT(C40_Ip_Status STATUS_C40_IP_SUCCESS ); return C40_Ip_Status; }上面代码是在一个PFALSH区域写入LC的值我们需要通过SBAF来推进则需要在启动文件Startup_cm7.s中设置LC的指针。#define LF_CONFIG_ADDR (0x004EA000) .section .boot_header,ax .long SBAF_BOOT_MARKER /* IVT marker */ .long (CM7_0_ENABLE CM7_0_ENABLE_SHIFT) | (CM7_1_ENABLE CM7_1_ENABLE_SHIFT) | (CM7_2_ENABLE CM7_2_ENABLE_SHIFT) /* Boot configuration word */ .long 0 /* Reserved */ .long CM7_0_VTOR_ADDR /* CM7_0 Start address */ .long 0 /* Reserved */ .long CM7_1_VTOR_ADDR /* CM7_1 Start address */ .long 0 /* Reserved */ .long CM7_2_VTOR_ADDR /* CM7_2 Start address */ .long 0 /* Reserved */ .long LF_CONFIG_ADDR /* Lifecycle configuration pointer */查看通过执行上面两个阶段的API已成功写入ADKP和LC值了下面需要硬件复位休眠再唤醒或者Reset_B引脚接地注意不是软复位。我们可以通过IDE自带的Memory查看是否写入成功如S32DS NXP官方开发工具。调试测试现在使用PEmicro调试如果操作正确应该看到以下信息这时的JTAG接口已经被禁用了只有密码校验通过的设备才能够调试。解锁调试接口现在要解锁MCUPEmicro提供了一些Python脚本。一般在S32DS这个IDE中自带该文件包位于 NXP\S32K3xx 文件夹内。使用 PEmicro 脚本需要 Python 3.5 或更高版本来运行。UP使用的Python 3.14.5。在该目录下打开CMD窗口输入以下指令(密码与前面ADKP保持一致)py authenticate_password_mode.py -hardwareidUSB1 -password0102030405060708090A0B0C0D0E0F00注意一点USB1可以是用于调试的硬件 IP 地址、名称、序列号或端口名称等等。不知道的可以查看调试设备的配置在调试器经过认证之后开发人员就可以在 S32 Design Studio 或任何第三方集成开发环境中使用 PEmicro 插件来安全地调试设备了。注意只有在安全调试模式下设备才能继续被访问直到下一次硬重置或电源重启。默认情况下在调试过程中会触发硬重置这会清除认证信息。为了避免这种情况请在软件中指定“SECUREDEBUG”设备。调试成功小结最后讲一下ADKP和LC推进之后是无法再更改的。但是LC中我们配置的0x004EA000这个Pflash区域块是可以重新被擦除写入数据的相当于LC推进是一次性操作操作完了。这个区域该怎么样还是怎么样。但是ADKP所在的Utest区域不一样是不能被更改的属于一次性编程区域OTP。补充一般调试禁用需要软硬件同步实施这里的密码禁用其实依然不太安全可以尝试当作一个31例程写入一个随机的密码这样谁也不会知道了。