本帖最后由 cruelfox 于 2017-3-31 23:03 编辑
PCROP --- Proprietary Code Readout Protection 是用来加强MCU里面软件的保护的功能,即防止Flash内容的读出(复制)。
即使没有PCROP, 作为一个MCU也总是有某些防复制机制的。STM32F722和其它F7型号一样,已经具备RDP(读保护)功能:
RDP有三个保护级别:
Level 0: 默认的,无保护
Level 1: 当从Bootloader启动或SRAM启动,以及当调试功能开启时,对Flash的读、写和擦除都禁止,对备份SRAM的读写也禁止。仅当从Flash启动时,才可以允许操作。
Level 2: 完全禁止读或调试。JTAG被禁止,SRAM启动被禁止,bootloader可以启动但只能读ID等少量信息。而且,Option bytes不能再被修改。
保护级别的 Level 1是可以回到Level 0的,当然被保护的代码将被擦除。但是一旦芯片被配置到 RDP Level 2, 就不可逆转了,不能再使用调试功能,只适合产品定型量产后使用。
PCROP和RDP有何不同?从手册里面的描述看来,PCROP是FLASH硬件部分的自我保护,而RDP是芯片级别的保护。在具体的实施上,PCROP可以有选择地保护Flash的某些部分(sector). PCROP也不区分是从Flash启动还是从SRAM启动、bootloader启动,不区分软件的访问还是通过JTAG的访问,只要是非执行方式的读(从D-bus接口访问),都会拒绝访问,并产生总线异常。
PCROP 的开关是配置 Option Bytes 0x1FFF0020 来控制的。
一共有8个bit, 对应Flash 8个setor的PCROP保护开/关
例如要对Flash的前32K使用PCROP保护,那只需要把 Option Bytes 中 PCROP0, PCROP1 两个位写为1.
写一段程序用来修改 Option bytes, 将 PCROP[0] 设成1
int main(void)
{
gpio_config();
uart_setup();
uart_wstr("\nFLASH_OPTCR ");
uart_whex(FLASH->OPTCR);
uart_wstr("\nFLASH_OPTCR1 ");
uart_whex(FLASH->OPTCR1);
uart_wstr("\nFLASH_OPTCR2 ");
uart_whex(FLASH->OPTCR2);
FLASH->OPTKEYR = 0x08192A3B;
FLASH->OPTKEYR = 0x4C5D6E7F;
while(FLASH->SR & FLASH_SR_BSY);
FLASH->OPTCR2 = 1; // PCROP sector 0
FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT;
__DSB();
while(FLASH->SR & FLASH_SR_BSY);
uart_wstr("\nChanged PCROP0");
uart_wstr("\nFLASH_OPTCR2 ");
uart_whex(FLASH->OPTCR2);
for(;;)
{
}
}
这段程序编译成HEX以后,用OpenOCD载入到ITCM RAM中执行。然后…… 板子复位了也不再执行Flash中的程序了。
然后,居然 ST-Link Utility 连不上板子了
神马情况?Can't halt the core
看来PCROP已经保护起作用了,但是因为D-bus访问Flash被禁止,导致了现在的异常状态。我猜测是CPU不能读取中断向量表,所以死在那里了……
但是SWD调试口还是活着的,ST-Link并不是无法和F722通信。还是用 OpenOCD 来看吧。
> reg pc
pc (/32): 0x00000000
> reg xPSR
xPSR (/32): 0x00000000
> reg sp
sp (/32): 0x00000000
>
寄存器的状态貌似都是空的,很奇怪。再读下Flash看看。
> mdw 0x08000000 4
> mdw 0x08004000 4
0x08004000: ffffffff ffffffff ffffffff ffffffff
> mdw 0x08003ff0 4
>
访问 0x08000000 到 0x08003FFF 之间(Flash 前16k)会出错,读不出来。正好表明 PCROP 保护了这部分,不能读。 16k之后的Flash内容可以读出。
|