0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CW32L010安全运行库保护的实现

CW32生态社区 来源:CW32生态社区 作者:CW32生态社区 2025-05-12 14:51 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前言

CW32L010的FLASH存储器支持安全运行库功能,方案商可将核心算法存储于安全运行库区域以供客户二次开发时调用。使能安全运行库保护功能后,用户代码可正常调用运行安全运行库区域内的函数,但无法通过任何方式(CPU、SWD、ISP)读出安全运行库区域的内容,只有提供正确的密码时才能通过ISP协议禁止安全运行库保护功能,同 时清空安全运行库存储空间的数据。

一、工作原理

通过将要保护的算法指定存放到FLASH对应的页面page(0

二、设置安全运行库的具体步骤

2.1.将算法函数指定到目标页面

只需要使用__attribute__((section(".ARM.__at_address")))就可以将变量、数组、函数指定到FLASH的任意地址。

wKgZPGggaqeAacjeAAAs0mtrR3o682.jpg

常见的函数类型指定地址方法如下:

@font-face{
font-family:"Times New Roman";
}
@font-face{
font-family:"宋体";
}
@font-face{
font-family:"Calibri";
}
p.MsoNormal{
mso-style-name:正文;
mso-style-parent:"";
margin:0pt;
margin-bottom:.0001pt;
mso-pagination:none;
text-align:justify;
text-justify:inter-ideograph;
font-family:Calibri;
mso-fareast-font-family:宋体;
mso-bidi-font-family:'Times New Roman';
font-size:10.5000pt;
mso-font-kerning:1.0000pt;
}
p.MsoFooter{
mso-style-name:页脚;
mso-style-noshow:yes;
margin:0pt;
margin-bottom:.0001pt;
tab-stops:center blank 207.6500pt right blank 415.3000pt ;
layout-grid-mode:char;
mso-pagination:none;
text-align:left;
font-family:Calibri;
mso-fareast-font-family:宋体;
mso-bidi-font-family:'Times New Roman';
font-size:9.0000pt;
mso-font-kerning:1.0000pt;
}
span.msoIns{
mso-style-type:export-only;
mso-style-name:"";
text-decoration:underline;
text-underline:single;
color:blue;
}
span.msoDel{
mso-style-type:export-only;
mso-style-name:"";
text-decoration:line-through;
color:red;
}
@page{mso-page-border-surround-header:no;
	mso-page-border-surround-footer:no;}@page Section0{
}
div.Section0{page:Section0;}
void func1 (void); 
void func1 (void) __attribute__((section(".ARM.__at_0x0000FE00")));
//指定func函数的地址为0x0000FE00,所在页面为127页
 
void func2 (uint8_t CNT);void func2 (uint8_t) __attribute__((section(".ARM.__at_0x0000FE50")));//指定func函数的地址为0x0000FE50,所在页面为127页
 
uint8_t func3 (uint8_t CNT1,uint8_t* p);
uint8_t func3 (uint8_t, uint8_t*) __attribute__(( section(".ARM.__at_0x0000FEA4" )));
//指定func函数的地址为0x0000FEA4,所在页面为127页

多个函数指定地址储存时,在指定地址前,需先在KEIL的map文件中找到各个函数的大小,免得指定地址时内存冲突。map文件如下:

wKgZO2ggaqiAQoN4AALl8rjUp84557.jpg

由此可以得到func1、func2、func3的字节大小分别是0x50、0x54、0x58,接下来就可以指定函数的存储地址了。

注意指定地址时,因为32位变量需要4字节对齐,也就是地址的最低位得是0、4、8、C才行,所以地址不能出现,如:0x0000FE01、0x0000FE02、0x0000FE03、0x0000FE05、0x0000FE06、0x0000FE07、0x0000FE09、0x0000FE0A、0x0000FE0B、0x0000FE0D、0x0000FE0E、0x0000FE0F

接着就可以指定func1的地址为0x0000FE00,func2的地址为0x0000FE00+0x50,func3的地址为0x0000FE00+0x50+0x54,如想指定其它地址,依次类推。

2.2.开启相应页面的安全运行库

使能安全运行库保护功能的方法为:在地址0xFFF0~ 0xFFFF 写入特定控制字,如下表所示:

wKgZPGggaqmAP5yGAAECAGD6p0o349.jpgwKgZO2ggaqmAJC5nAABz1keOiRc549.jpg

2.3.参考代码

文章及视频中使用到的例程源码文件:

通过网盘分享的文件:CW32L010 FLASH PROTECT.zip

链接: https://pan.baidu.com/s/1d5tj_zz-b1bQGkJkuAgbdQ?pwd=CW32

提取码: CW32

@font-face{
font-family:"Times New Roman";
}
@font-face{
font-family:"宋体";
}
@font-face{
font-family:"Calibri";
}
p.MsoNormal{
mso-style-name:正文;
mso-style-parent:"";
margin:0pt;
margin-bottom:.0001pt;
mso-pagination:none;
text-align:justify;
text-justify:inter-ideograph;
font-family:Calibri;
mso-fareast-font-family:宋体;
mso-bidi-font-family:'Times New Roman';
font-size:10.5000pt;
mso-font-kerning:1.0000pt;
}
p.MsoFooter{
mso-style-name:页脚;
mso-style-noshow:yes;
margin:0pt;
margin-bottom:.0001pt;
tab-stops:center blank 207.6500pt right blank 415.3000pt ;
layout-grid-mode:char;
mso-pagination:none;
text-align:left;
font-family:Calibri;
mso-fareast-font-family:宋体;
mso-bidi-font-family:'Times New Roman';
font-size:9.0000pt;
mso-font-kerning:1.0000pt;
}
span.msoIns{
mso-style-type:export-only;
mso-style-name:"";
text-decoration:underline;
text-underline:single;
color:blue;
}
span.msoDel{
mso-style-type:export-only;
mso-style-name:"";
text-decoration:line-through;
color:red;
}
@page{mso-page-border-surround-header:no;
	mso-page-border-surround-footer:no;}@page Section0{
}
div.Section0{page:Section0;}
void func1 (void) __attribute__((section(".ARM.__at_0x0000FE00")));//指定func函数的地址为0x0000FE00,所在页面为127页
void func2 (uint8_t ) __attribute__((section(".ARM.__at_0x0000FE50")));//指定func函数的地址为0x0000FE50,所在页面为127页
uint8_t func3 (uint8_t ,uint8_t* ) __attribute__((section(".ARM.__at_0x0000FEA4")));//指定func函数的地址为0x0000FEA4,所在页面为127页
 
void func1 (void) 
{
 //PB03---LED1 推挽输出
    CW_GPIOB->DIR_f.PIN3 = 0;
    CW_GPIOB->ANALOG_f.PIN3 = 0;

 uint8_t cnt = 10;

    while(cnt--)
 {
  CW_GPIOB->TOG_f.PIN3 = 1;
  uint32_t thisCnt = 0X9FFFF;
  while( thisCnt-- )
  {
   ;
  }
 }
}
 
void func2 (uint8_t CNT) 
{
 //PB03---LED1 推挽输出
    CW_GPIOB->DIR_f.PIN3 = 0;
    CW_GPIOB->ANALOG_f.PIN3 = 0;

 uint8_t cnt = CNT;

    while(cnt--)
 {
  CW_GPIOB->TOG_f.PIN3 = 1;
  uint32_t thisCnt = 0X9FFFF;
  while( thisCnt-- )
  {
   ;
  }
 }
}
 
uint8_t func3 (uint8_t CNT1,uint8_t* p) 
{
 //PB03---LED1 推挽输出
    CW_GPIOB->DIR_f.PIN3 = 0;
    CW_GPIOB->ANALOG_f.PIN3 = 0;

 uint8_t cnt = CNT1 + *p;

    while(cnt--)
 {
  CW_GPIOB->TOG_f.PIN3 = 1;
  uint32_t thisCnt = 0X9FFFF;
  while( thisCnt-- )
  {
   ;
  }
 }
 return 0;
}
 
int32_t main(void)
{        
    uint8_t ret,temp;
    
    __SYSCTRL_FLASH_CLK_ENABLE();
    __SYSCTRL_CRC_CLK_ENABLE();
 __SYSCTRL_GPIOB_CLK_ENABLE();

    ret = FLASH_SafetyLibraryEnable(SlibKey, 0x7F, 0x7F);
    
    if (ret)
    {
        // 开启安全区失败
        while(1);
    }    

 func1();

 func2(10);

 temp = 5;
 ret = func3(5,&temp);
    
    //结束
    while(1)
    {
        
    }
}

2.4.函数调用

函数调用时需要在指定的地址上加1,因为对于cortex M核的芯片,任何跳转相关地址的最低位,即BIT0都应是1。该位表示将用到的的指令集为Thumb指令。具体调用方法如下:

@font-face{
font-family:"Times New Roman";
}
@font-face{
font-family:"宋体";
}
@font-face{
font-family:"Calibri";
}
p.MsoNormal{
mso-style-name:正文;
mso-style-parent:"";
margin:0pt;
margin-bottom:.0001pt;
mso-pagination:none;
text-align:justify;
text-justify:inter-ideograph;
font-family:Calibri;
mso-fareast-font-family:宋体;
mso-bidi-font-family:'Times New Roman';
font-size:10.5000pt;
mso-font-kerning:1.0000pt;
}
p.MsoFooter{
mso-style-name:页脚;
mso-style-noshow:yes;
margin:0pt;
margin-bottom:.0001pt;
tab-stops:center blank 207.6500pt right blank 415.3000pt ;
layout-grid-mode:char;
mso-pagination:none;
text-align:left;
font-family:Calibri;
mso-fareast-font-family:宋体;
mso-bidi-font-family:'Times New Roman';
font-size:9.0000pt;
mso-font-kerning:1.0000pt;
}
span.msoIns{
mso-style-type:export-only;
mso-style-name:"";
text-decoration:underline;
text-underline:single;
color:blue;
}
span.msoDel{
mso-style-type:export-only;
mso-style-name:"";
text-decoration:line-through;
color:red;
}
@page{mso-page-border-surround-header:no;
	mso-page-border-surround-footer:no;}@page Section0{
}
div.Section0{page:Section0;}
#define  Slib_Led_Blink1     ((void (*)())(0x0000FE00UL + 1))
#define  Slib_Led_Blink2     ((void (*)(uint8_t))(0x0000FE50UL + 1))
#define  Slib_Led_Blink3     ((uint8_t (*)(uint8_t,uint8_t*))(0x0000FEA4UL + 1))
 
int32_t main(void)
{
    SYSCTRL_HSI_Enable(SYSCTRL_HSIOSC_DIV12);
 __SYSCTRL_GPIOB_CLK_ENABLE();

 Slib_Led_Blink1();//方法一:宏调用
 ((void (*)())(0x0000FE00UL + 1))();//方法二:直接调用
 void (*ppp1) ();//方法三;函数指针调用
 ppp1 = (void (*) ())(0xFE00 + 1);
 ppp1();

 Slib_Led_Blink2(10);//方法一:宏调用
 ((void (*)(uint8_t))(0x0000FE50UL + 1))(10);//方法二:直接调用
 void (*ppp2)(uint8_t);//方法三;函数指针调用
 ppp2 = ((void (*)(uint8_t))(0x0000FE50UL + 1));
 ppp2(10);

 uint8_t xx = 5;
 uint8_t temp = Slib_Led_Blink3(5,&xx);//方法一:宏调用
 ((uint8_t (*)(uint8_t,uint8_t*))(0x0000FEA4UL + 1))(5,&xx);//方法二:直接调用
 uint8_t (*ppp3)(uint8_t,uint8_t*);//方法三;函数指针调用
 ppp3 = (uint8_t (*)(uint8_t,uint8_t*))(0x0000FEA4+1);
 ppp3(5,&xx);

    while (1)
    {

    }
}

2.5.擦除安全运行库

禁止安全运行库保护功能共有两种方法:

(1).通过ISP协议执行片擦操作:芯片接收到片擦指令及正确的安全运行库密码时,将自动擦除本芯片的所有数据并禁止安全运行库保护功能;。

需要用到上位机CW-Programmmer,具体连线请按上位机提示进行连接,上位机配置需按下图配置:

wKgZPGggaqqAaPjYAAB01jsbjCA934.jpg

填写SDK区域密码时,需按16进制来填写密码,如:十进制1,0xF,'_','!','@','*','A','1',填写时为它们对应ascii值的16进制,分别是0x01、0x0F、0x5F、0x21、0x40、0x2A、0x41、0x31,所以密码应该填写010F5F21402A4131。

填写完密码后,点击在线编程,即可擦除安全运行库。

(2).在RAM中对芯片执行片擦操作:配置编译器参数,使片擦操作从RAM中执行。片擦操作完成后,本芯片的所有数据均被擦除并禁止安全运行库保护功能。

2.6.注意事项

(1).指定算法函数的地址不要太靠前,否则会与下载的代码起冲突,建议选择FLASH靠后的页面。

(2).储存在安全运行库页面里的函数,不可调用安全区外的函数。

(3).安全运行库代码下载到MCU后,要进行上电复位才能生效。

三、现象演示

将安全运行库的代码下载到CW32L010F8P6 StartKit REV01板子中后,断电后重新上电,DEBUG页面的memory中,127页显示不可读,全0,表示127页已经受到保护了。

wKgZO2ggaquARyW3AAFMKuxTQ_k875.jpg

用户可以在其它工程中调用储存在安全运行库页面的函数,具体调用方法详情见2.4函数调用章节。

四、视频讲解

CW32L010黑客区安全运行库保护的实现 :1.FLASH及安全库区域原理_哔哩哔哩_bilibili

CW32L010黑客区安全运行库保护的实现 :2.算法编程调用及注意事项_哔哩哔哩_bilibili

CW32L010黑客区安全运行库保护的实现 :3. 实例代码运行讲解及FLASH读取验证_哔哩哔哩_bilibili

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RAM
    RAM
    +关注

    关注

    8

    文章

    1398

    浏览量

    119798
  • 算法
    +关注

    关注

    23

    文章

    4760

    浏览量

    97123
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CW32L010的2种启动模式介绍

    CW32L010 支持以下 2 种启动模式: ●从主 FLASH 存储器启动,运行用户程序。 ●从启动程序存储器启动,运行内部 BootLoader。 当运行 Bootloader
    发表于 11-28 08:09

    CW32L010的串口输出

    CW32L010是一款集成了丰富功能的低功耗微控制器,其串口输出功能是通过其内部的通用异步收发器(UART)实现的。 一、串口硬件资源 CW32L010提供了二路低功耗UART,这些UART接口支持
    发表于 11-27 07:27

    CW32L010新品安全低功耗MCU性能如何?有哪些优势?

    CW32L010新品安全低功耗MCU性能如何?有哪些优势?
    发表于 11-24 07:31

    CW32L010使能读保护后标志位不正确怎么解决?

    CW32L010使能读保护后标志位不正确
    发表于 11-20 07:44

    CW32L010用jlink能去除读保护吗?

    如题,板上的CW32L010有读保护,JLINK能识别到内核,但无法擦除下载程序。 要怎么才能去除读保护
    发表于 11-20 06:23

    CW32L010高速风筒方案的特点

    1、高性能处理能力:主控采用CW32L010F8P6,基于ARM Cortex-M0+ 32位高速处理器内核,能够实时处理复杂的控制算法,确保风筒在不同风速和温度设置下的稳定运行。 2、低功耗
    发表于 11-13 06:21

    请问CW32L010 能否使用SysTick中断?

    CW32L010 能否使用SysTick中断?
    发表于 11-12 07:25

    CW32L010系列的特点

    ,用户能依据采样时机的不同,灵活调整PWM波形的边沿位置。 RTC补偿精度高达060ppm,实现亚秒级读数 CW32L010在RTC补偿机制上进行了精心优化,提供三种可选的补偿周期:32秒、128秒
    发表于 11-12 06:51

    CW32L010安全运行库保护是什么功能?

    它是针对用户指定的MCU内部FLASH数据,提供的一种读保护功能;该功能生效后,就可以禁止对安全运行库进行任何形式的读取操作(比如CPU、 SWD、 ISP 均无法正确读取该区数据), 但不影响调用
    发表于 11-12 06:19

    基于CW32L010的高性能温控器方案

    武汉芯源半导体的明星产品CW32L010系列MCU凭借其ARM Cortex-M0+内核、超低功耗特性以及丰富的外设接口,为温控器设计提供了理想的解决方案。 本文将介绍无锡梓轩电子基于武汉芯源半导体低功耗CW32L010单片机开发的温控器方案,功能全面,性价比突出。
    的头像 发表于 07-02 09:47 964次阅读
    基于<b class='flag-5'>CW32L010</b>的高性能温控器方案

    基于CW32L010的高性能温控器方案

    CW32L010温控器 方案可实现: 温控范围:5-95℃; 温度开关偏差:0.5-10℃可调; 设定温度与时钟轮流显示,测量温度直接读取; 传感器故障提示; 支持人工控制、时段控制和临时控制三种
    发表于 07-02 09:46

    武汉芯源半导体CW32L010在两轮车仪表的应用介绍

    CW32L010凭借其优异的性能、丰富的外设资源和超低功耗特性,为两轮车仪表盘应用提供了高性价比的解决方案。其宽电压工作范围和工业级温度特性,特别适合车辆电子应用的严苛环境。对于想采用CW32L010进行两轮车仪表盘开发的客户,武汉芯源半导体可提供全面的技术支持,助力客户
    的头像 发表于 05-13 14:07 590次阅读
    武汉芯源半导体<b class='flag-5'>CW32L010</b>在两轮车仪表的应用介绍

    武汉芯源半导体CW32L010在两轮车仪表的应用介绍

    随着两轮电动车的智能化发展,仪表盘作为人机交互的重要界面,其功能需求日益复杂。武汉芯源半导体的安全低功耗单片机CW32L010凭借其优异的性能和丰富的外设资源,成为两轮车仪表盘应用的理想选择。 本文
    发表于 05-13 14:06

    CW32L010 Motor Control Driver无刷电机驱动板上手体验

    CW32L010无刷电机驱动开发板上手体验
    的头像 发表于 12-26 09:26 1722次阅读
    <b class='flag-5'>CW32L010</b> Motor Control Driver无刷电机驱动板上手体验

    方案介绍|CW32L010安全低功耗MCU:驱动高速风筒新力量

    芯源半导体CW32L010系列MCU可支持低成本、高性能、低功耗、高度集成的高速风筒方案,以满足市场对高效、安全、智能的高速风筒需求。 本文将介绍武汉芯源半导体CW32L010系列单片机在高速风筒
    发表于 12-10 09:57