GD32F103VE侵入事件

GD32F103VE的TAMPER引脚(PC13),当PC13输入低电平时,会产生一个侵入检测事件。它会将所有"数据备份寄存器"内容清除。

这个功能有什么用?

一是防止被人开壳,抄袭。二是自毁功能。

直奔主题,多一句就是浪费时间。测试程序如下:

复制代码
#include "TamperDetectionFunction.h"
#include "stdio.h"  //使能printf(),sprintf()
//#include "LED.h"

/*
当TAMPER引脚上的信号从0到1或从1到0
取决于备份控制寄存器BKP_TPCTL的TPAL位,
会产生一个侵入检测事件;
侵入检测事件会将所有数据备份寄存器内容清除。
*/

#define BKP_DATA_REG_NUM  42  //备份寄存器有42个

void write_backup_register(uint16_t data);
uint32_t check_backup_register(uint16_t data);
uint32_t is_backup_register_clear(void);
void TamperDetectionFunction_Init(void);

//函数功能:TAMPER引脚(PC13)输入低电平时,会产生一个侵入检测事件,它会将所有数据备份寄存器内容清除。
//为防止侵入事件丢失,PC13引脚检测到边沿检测信号与TPEN位的逻辑与作为侵入检测信号
void TamperDetectionFunction_Init(void)
{//MCU提供侵入检测功能以保护重要的用户数据,可通过设置BKP_TPCTL寄存器中的TPEN位来使能TAMPER引脚对应的功能。
	nvic_irq_enable(TAMPER_IRQn,0,0);//设置TAMPER_IRQn的中断优先级,抢占优先级为0,子优先级为0

	rcu_periph_clock_enable(RCU_PMU);//使能RCU_PMU时钟
	rcu_periph_clock_enable(RCU_BKPI);//使能RCU_BKPI时钟

	pmu_backup_write_enable();                          //使能对备份域寄存器的写访问
	bkp_tamper_active_level_set(TAMPER_PIN_ACTIVE_LOW); //配置TAMPER引脚(PC13)输入低电平有效

	bkp_tamper_detection_disable();//不使能"TAMPER引脚(PC13)实现备份复位功能"
	bkp_interrupt_disable();       //不使能"TAMPER-RTC引脚(PC13)侵入中断"
	bkp_flag_clear();              //清除"TAMPER-RTC引脚(PC13)侵入事件标志"

	bkp_interrupt_enable();        //使能"TAMPER引脚(PC13)侵入中断"
	bkp_tamper_detection_enable(); //使能"TAMPER引脚(PC13)可实现备份复位功能"

/*
	bkp_data_write(BKP_DATA_41,0xA0A0);//将0xA0A0写入备份数据寄存器41
	if(bkp_data_read(BKP_DATA_41)==0xA0A0) LED2_On();
	else LED3_On();
*/

	write_backup_register(0x1226);//将0x1226写入地址为BKP_DATA_0的备份寄存器
	if(0x00 == check_backup_register(0x1226))//写入备份数据寄存器正确
	{
//		MCU_Led_On();//写入备份数据寄存器正确
		printf("\r\nwrite_backup_register OK!!!");
	}
	else//写入备份数据寄存器不正确
	{
//		MCU_Led_Off();//写入备份数据寄存器不正确
		printf("\r\nwrite_backup_register Error!!!");
	}
}

//函数功能:将data,data+0x50,data+0x50*2,......data+0x50*41,写入备份寄存器
void write_backup_register(uint16_t data)
{
	uint32_t temp = 0;

	/* write data to backup data registers */
	for (temp = 0; temp < BKP_DATA_REG_NUM; temp++)
	{
		bkp_data_write( (bkp_data_register_enum)(temp+1),(data + (temp * 0x50)) );
		//BKP_DATA_0的初始值为1,所以这里要用(temp+1)
//		if(temp < 10)
//		{
//			BKP_DATA0_9(temp) = data + (temp * 0x50);
//		}
//		else
//		{
//			BKP_DATA10_41(temp) = data + (temp * 0x50);
//		}
	}
}

//函数功能:从备份寄存器读取数据,并比较;若发现错误,则返回
uint32_t check_backup_register(uint16_t data)
{
	uint32_t temp = 0;

	for(temp = 0; temp < BKP_DATA_REG_NUM; temp++)
	{
		if(bkp_data_read( (bkp_data_register_enum)(temp+1) ) != (data + (temp * 0x50)) )
		{//BKP_DATA_0的初始值为1,所以这里要用(temp+1)
			return temp+1;//发现错误
		}

//		if(temp < 10)
//		{
//			//get data from data register 0-9
//			if(data + (temp * 0x50) != BKP_DATA_GET(BKP_DATA0_9(temp)))
//			{
//				return temp+1;
//			}
//		}
//		else
//		{
//			//get data from data register 10-41
//			if(data + (temp * 0x50) != BKP_DATA_GET(BKP_DATA10_41(temp)))
//			{
//				return temp+1;
//			}
//		}
	}

	return 0;
}

//函数功能:检查"备份寄存器"的数据是否为0x0000,并比较;若发现不是0x0000,则返回
uint32_t is_backup_register_clear(void)
{
	uint32_t temp = 0;

	for(temp = 0; temp < BKP_DATA_REG_NUM; temp++)
	{
		if(bkp_data_read((bkp_data_register_enum)(temp+1))!=0x0000)
		{//BKP_DATA_0的初始值为1,所以这里要用(temp+1)
			return temp+1;//发现错误
		}
//		if(temp < 10)
//		{
//			//check if the data of data register 0-9 is 0x0000
//			if(0x0000 != BKP_DATA_GET(BKP_DATA0_9(temp)))
//			{//BKP_DATA_GET(BKP_DATA0_9(temp)和bkp_data_read( (temp+1))等价
//        return temp+1;
//      }
//    }
//		else
//		{
//			// check if the data of data register 10-41 is 0x0000
//			if(0x0000 != BKP_DATA_GET(BKP_DATA10_41(temp)))
//			{//BKP_DATA_GET(BKP_DATA10_41(temp)和bkp_data_read( (temp+1))等价
//         return temp+1;
//      }
//    }
	}

	return 0;
}

//函数功能:"TAMPER引脚(PC13)侵入中断服务函数
//bkp_tamper_active_level_set(TAMPER_PIN_ACTIVE_LOW)配置TAMPER引脚(PC13)输入低电平有效
//TAMPER引脚(PC13)输入低电平时,会产生一个侵入检测事件,它会将所有数据备份寄存器内容清除。
void TAMPER_IRQHandler(void)
{
	if(RESET != bkp_interrupt_flag_get())//读取"TAMPER-RTC引脚(PC13)侵入中断标志"
	{
		if(0 == is_backup_register_clear())//发现"侵入事件"清除了"备份数据寄存器"
		{//"备份数据寄存器"中的数据被清除了
//			MCU_Led_On();
			printf("\r\nClear backup_register!!!");
		}
		else//发现"侵入事件"没有清除"备份数据寄存器"
		{//"备份数据寄存器"中的数据没有被清除
//			MCU_Led_On();
			printf("\r\nDon't Clear backup_register!!!");
		}

		bkp_interrupt_flag_clear();//清除"TAMPER-RTC引脚(PC13)侵入中断标志",clear the interrupt bit flag of tamper interrupt
		bkp_flag_clear();//清除"TAMPER-RTC引脚(PC13)侵入事件标志",clear the bit flag of tamper event 

		bkp_interrupt_disable();//不使能"TAMPER-RTC引脚(PC13)侵入中断",disable the tamper pin
		bkp_interrupt_enable();//TAMPER-RTC引脚(PC13)侵入中断使能,enable the tamper pin
		bkp_tamper_active_level_set(TAMPER_PIN_ACTIVE_LOW);//配置TAMPER引脚(PC13)输出低电平有效,tamper pin active level set
	}
}

#include "UART3.h"
#include "stdio.h"  //使能printf(),sprintf()

void UART3_Init(unsigned int bound);

//函数功能:初始化串口3,这个和STM32F103VET6的UART4兼容
void UART3_Init(unsigned int bound)
{
	rcu_periph_clock_enable(RCU_GPIOC); //使能GPIOC时钟,enable GPIO clock 
	rcu_periph_clock_enable(RCU_UART3); //使能UART3时钟,enable USART clock

	gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
	//将GPIOC10设置为AFIO口(复用IO口),输出上拉

	gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
	//将GPIOC11设置为浮空输入口

	usart_deinit(UART3);                         //复位UART3,USART configure
	usart_baudrate_set(UART3, bound);          //设置UART3的波特率
	usart_word_length_set(UART3, USART_WL_8BIT); //设置UART3数据传输格式为8位
	usart_stop_bit_set(UART3, USART_STB_1BIT);   //设置UART3停止位为1位
	usart_parity_config(UART3, USART_PM_NONE);   //设置UART3无需奇偶校验
	usart_hardware_flow_rts_config(UART3, USART_RTS_DISABLE); //设置不使能UART3的RTS引脚功能
	usart_hardware_flow_cts_config(UART3, USART_CTS_DISABLE); //设置不使能UART3的CTS引脚功能
	usart_receive_config(UART3, USART_RECEIVE_ENABLE);   //使能UART3接收
	usart_transmit_config(UART3, USART_TRANSMIT_ENABLE); //使能UART3发送
	usart_enable(UART3); //使能UART3
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
	usart_data_transmit(UART3, (uint8_t) ch);
	while( RESET == usart_flag_get(UART3, USART_FLAG_TBE) )
	{//等待串口0发送结束
	}

	return ch;
}

main.c程序如下:

复制代码
#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t,bool
#include "UART3.h"
#include "stdio.h"  //使能printf(),sprintf()

#include "LED.h"
#include "TamperDetectionFunction.h"

const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
int main(void)
{
	//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
	//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
	//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
	//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
	//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"
	UART3_Init(115200);//初始化UART3
	printf("%s",CPU_Reset_REG);//调试串口输出"\r\nCPU reset!\r\n"

  INTX_ENABLE();//开启所有中断

	LED_Init();//初始化MCU_Led

	TamperDetectionFunction_Init();
//TAMPER引脚(PC13)输入低电平时,会产生一个侵入检测事件,它会将所有数据备份寄存器内容清除。
//当将PC13输入低电平时,串口输出"Clear backup_register!!!"
	while(1)
	{
	}
}
相关推荐
蓝斯4977 小时前
从.到实现一个Windows上的虚拟hid键盘设备
windows·单片机·计算机外设
熙芯XiChip7 小时前
硬实时与软实时RTOS核心区别
嵌入式硬件
伟大的前程8 小时前
unsigned int 定义的变量 在 电脑的 64 位系统中 和 32 位 cortex-m0 和 8 位的 51 单片机
单片机·嵌入式硬件
小渔村的拉线工8 小时前
1.HPM6E80 解析芯片整体工作原理和存储架构
单片机·嵌入式硬件·mcu·架构·hpm6e80
熙芯XiChip9 小时前
CAN与CANopen的本质区别
单片机
lilihewo9 小时前
Altium Designer 封装库的创建(分享pcb 3D封装库)
嵌入式硬件·51单片机
神罚天下ET10 小时前
典型arm位单片机启动流程(从上电到main.c)
c语言·arm开发·单片机
碧海银沙音频科技研究院11 小时前
蓝牙耳机使用WSDF5361锂保芯片进入船运模式实现方法
嵌入式硬件·算法
Zevalin爱灰灰12 小时前
模拟信号链电路——基于TL431的电压基准电路
单片机·嵌入式硬件
csdn杰哥12 小时前
瑞萨单片机开发教程[二十七] DTC 外部中断触发传输实验
单片机·嵌入式硬件·mongodb·瑞萨·ra6m5