首页 > 评测 > 优雅使用J-Link解除APM32F003的读保护

优雅使用J-Link解除APM32F003的读保护

  
  • 作者:kai迪皮
  • 来源:21ic BBS
  • [导读]
  • 最近拿到了一块APM32F003F6 MINI开发板,发现其在同价位的芯片中有着丰富的资源和优秀的低功耗水平。准备拿来做一些小产品的



前言

最近拿到了一块APM32F003F6 MINI开发板,发现其在同价位的芯片中有着丰富的资源和优秀的低功耗水平。准备拿来做一些小产品的开发。板子美照如下所示(截取官网资源)。



1 APM32F003的读保护设置

在开发过程中,发现其对代码保护如同APM32F4一样,可以设置读保护。如其手册描述,APM32F003支持写保护和读保护。



通过手册描述和使用相关的库函数,我们可以将库函数封装,方便我们一个指令进行读写保护。

  1. /*!
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]       Flash Read Out Protection Config.
  3. *
  4. * @param       rdp : Set the chip read protection level
  5. *               This parameter can be one of the following variables:
  6. *               FMC_RDP_ENABLE : Enable read protection
  7. *               FMC_RDP_DISABLE : Disable read protection
  8. *
  9. * @retval      None
  10. *
  11. * @note
  12. */
  13. void ReadOutProtectionConfig(FMC_RDP_T rdp)
  14. {
  15.     FMC_Unlock();
  16.     FMC_ConfigReadOutProtection(rdp);
  17.     FMC_Lock();
  18. }
复制代码

在我们的功能函数里面对ReadOutProtectionConfig()函数进行调用即可完成对芯片的读写保护。如:

  1. /*!
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]       Main program
  3. *
  4. * @param       None
  5. *
  6. * @retval      None
  7. *
  8. * @note
  9. */
  10. int main(void)
  11. {
  12.     uint32_t i = 0;
  13.  
  14.     LedInit();
  15.  
  16.     /* Enable read protection */
  17.     ReadOutProtectionConfig(FMC_RDP_ENABLE);
  18.  
  19.     for (i = 0; i < 10; i++)
  20.     {
  21.     Delay(0x7ffff);
  22.     Board_LedToggle(BOARD_LED2);
  23.     Board_LedToggle(BOARD_LED3);
  24.     }
  25.  
  26.     /* Disable read protection */
  27.     ReadOutProtectionConfig(FMC_RDP_DISABLE);
  28.  
  29.     while (1)
  30.    {
  31.  
  32.    }
  33. }
复制代码

以上代码是实现了一个读保护设置后,闪灯5下后解除读保护。(值得注意的是:APM32F003手册是说明“在配置完选项字节后,需要复位才能生效 ”)。

2 为什么需要使用J-Link解除APM32F003读保护


由于我们的代码出厂后不想让有心之人看到我们的二进制内容,我们会对芯片进行读保护,且不会留解除读保护的“后门”,以防用户误操作将产品弄坏。所以我们迫切需要一个工具能够在开发,维护阶段,在没有设置解除读保护的“后门”的情况下对芯片进行解除读保护操作。

而在开发阶段,我们最常用的工具就是J-Link,如何使用J-Link解决该问题便是我们的需求。

3 J-Link解除读保护的原理

书接上回“https://bbs.21ic.com/icview-3223010-1-1.html”我在J-Link的安装目录下面找到了相应J-Link的使用手册。我们可以在手册中看到,对使用J-Link Commander给芯片下载代码的一个例子。



(图片来源:[J-Link Commander - SEGGER Wiki](https://wiki.segger.com/J-Link_Commander#Perform_flash_download))

在例子中我们可以看到-Link Commander使用了“w4”指令对STM32F103ZE的一些外设进行了写值设置,以使得可以下载STM32F103ZE的外置Flash。

同理我们也可以依葫芦画瓢,理论上我们可以通过将我们对APM32F003芯片的解除写保护的代码。

4 APM32F003解除读保护分析

下面我们看一下官方源码中对于解除读保护,我们操作了那些寄存器。

- FMC_Unlock()函数内容

  1. void FMC_Unlock(void)
  2. {
  3.     FMC->KEY = FMC_KEY_1;
  4.     FMC->KEY = FMC_KEY_2;
  5. }
复制代码

对FMC 关键字(FMCwKey)写入解锁的键值以解锁 FMC。
- FMC_EraseOptionByte()函数内容

  1. FMC_STATE_T FMC_EraseOptionByte(void)
  2. {
  3.     uint16_t rpKey;
  4.     FMC_STATE_T state;
  5.  
  6.     rpKey = FMC->OBCS_B.READPROT ? 0 : FMC_RP_KEY;
  7.  
  8.     state = FMC_WaitForReady(FMC_DELAY_ERASE);
  9.  
  10.     if(state == FMC_STATE_COMPLETE)
  11.     {
  12.         FMC->OBKEY = FMC_KEY_1;
  13.         FMC->OBKEY = FMC_KEY_2;
  14.  
  15.         FMC->CTRL2_B.OBE = BIT_SET;
  16.         FMC->CTRL2_B.STA = BIT_SET;
  17.  
  18.         state = FMC_WaitForReady(FMC_DELAY_ERASE);
  19.  
  20.         if(state == FMC_STATE_COMPLETE)
  21.         {
  22.             FMC->CTRL2_B.OBE = BIT_RESET;
  23.  
  24.             FMC->CTRL2_B.OBP = BIT_SET;
  25.  
  26.             OB->READPROT = rpKey;
  27.  
  28.             state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
  29.  
  30.             if(state != FMC_STATE_TIMEOUT)
  31.             {
  32.                 FMC->CTRL2_B.OBP = BIT_RESET;
  33.             }
  34.         }
  35.         else if(state != FMC_STATE_TIMEOUT)
  36.         {
  37.             FMC->CTRL2_B.OBE = BIT_RESET;
  38.         }
  39.     }
  40.  
  41.     return state;
  42. }
  43.  
复制代码


1. 对FMC的OBKEY写入解锁键值以解锁对OB的操作。
2. 通过FMC的CTRL2寄存器,擦除选项字节。
3. 写入读保护等级至OB的READPROT寄存器,然后通过FMC的CTRL2寄存器进行编程。
4. 等待编程完成。

- FMC_Lock函数内容

  1. void FMC_Lock(void)
  2. {
  3.     FMC->CTRL2_B.LOCK = BIT_SET;
  4. }
复制代码

通过FMC的CTRL2寄存器的LOCK位写1,锁定FMC的CTRL2寄存器。

5 J-Link 解除 APM32F003读保护实现

有了解除读保护的C代码,我们简单的就可以将其“翻译”成J-Link的指令。下面是各个部分指令情况及其解析。
1. 规定选择的连接接口,连接的目标芯片类型及相应的连接速度(必须)。

  1. si 1
  2. device CORTEX-M0
  3. speed 100
  4. JTAGConfg -1,-1
复制代码


2. 停止运行当前芯片的程序(一般而言初始连接上芯片时,程序均处于暂停暂停),保证芯片没有在进行中的Flash操作(必须)。

  1. h
  2. r
  3. h
复制代码


3. 解锁代码的指令实现(必须)。

  1. w4 0x40011004 0x45670123
  2. w4 0x40011004 0xCDEF89AB
  3. w4 0x40011008 0x45670123
  4. w4 0x40011008 0xCDEF89AB
  5. sleep 100
  6. w4 0x40011010 0x00000220
  7. w4 0x40011010 0x00000260
  8. sleep 100
  9.  
  10. w4 0x40011010 0x00000200
  11. w4 0x40011010 0x00000210
  12. w4 0x00020400 0xFFFF00A5
  13. sleep 100
  14. w4 0x40011010 0x00000080
复制代码



4. 读取FMC的CTRL2寄存器内容,看看是否回到复位值(非必须)。

  1. mem32 0x40011010 0x01
  2. sleep 10
复制代码


5. 复位芯片以使解除读保护操作生效(必须)。

  1. r
复制代码


    我们新建一个文本文件,将上述代码保存至文件,然后将文件后缀名更改为“.jflash”(详情请查阅附件),最后使用“JLink.exe”打开即可(硬件要连接好)。对已经上了读保护的APM32F003芯片进行解除读保护操作。



6 注意事项

1. 芯片上读保护后使用Keil的下载命令会有如下提示弹框。



2. 使用本脚本文件,需保证硬件连接正常。

     

 

  • 本文系21ic原创,未经许可禁止转载!

网友评论