📄 main.c
字号:
//-------------------------------------------------------------------------*
//工 程 名:DG128FLASH后门(FlashBackDoor) *
//硬件连接:MCU的串行口与PC机的串行口相连 *
//程序描述:实现对Flash指定区域的擦除,写入,读取 *
//说 明: *
//目 的:初步掌握Flash擦写的基本知识 *
//-------《嵌入式系统-使用HCS12微控制器的设计与应用》教学实例-------------*
//头文件
#include "includes.h" //总头文件
//内部调用函数声明
INT8U Convert(INT8U ASC1,INT8U ASC2); //将两个ASCII码组合成一个十六进制数
INT8U CvtPage(INT8U buff[8]); //从字节数组中提取页号
INT16U CvtAddr(INT8U buff[8]); //从字节数组中提取地址
//由于在Flash擦写时会在Flash区产生高压,造成擦写不稳定,本工程把在高压时执行
//的程序转换成机器码存放在RAM区,在执行擦写操作时,执行RAM区的机器码,
//擦写操作稳定,该机器码存放在下面数组中,其中'0x3D'是'RTS'的机器码
const INT8U P[18]={0x18,0x0B,0x80,0x01,0x05,0xF6,0x01,0x05,0x87,
0x87,0xC4,0x40,0x8C,0x00,0x00,0x27,0xF4,0x3D};
//主函数
int main()
{
INT8U i;
INT8U j;
INT8U k;
INT8U flag; //读写字节奇偶个数标志
INT8U Line_end[2];
INT8U Convert(INT8U ASC1,INT8U ASC2);
DISABLE_INTERRUPTS; //禁止总中断
//1. 芯片初始化
MCUInit();
//2. 模块初始化
SCIInit(); //(1) 串行口初始化
//3.内存初始化
//ASCII码换行符
Line_end[0]=13;
Line_end[1]=10;
//把存放在RAM区的机器码赋值给数组PrgOfRam,供Flash擦写函数调用
for (i=0; i<18; i++)
PrgOfRam[i] = P[i];
//后门机制密码
for(i=0;i<8;i++)
BackdoorKey[i]=0xFF;
//安全字节
SecureByte[0]=0xFF;
SecureByte[1]=0xFE;
//主循环
while (1)
{
i = SCIReN(1,SerialBuff);
if (i != 0) continue;
switch (SerialBuff[0])
{
//收到提问信号
case '?' :
{
SCISendN(11,"E:PAGE:ADDR"); //擦除命令格式
SCISendN(2, (void *)Line_end);
SCISendN(18,"W:PAGE:ADDR:N:DATA"); //写入命令格式
SCISendN(2, (void *)Line_end);
SCISendN(13,"R:PAGE:ADDR:N"); //读取命令格式
SCISendN(2,(void *)Line_end);
SCISendN(13,"S:BackdoorKey"); //设置密码命令格式
SCISendN(2,(void *)Line_end);
SCISendN(12,"C:SecureByte"); //设置安全状态命令格式
SCISendN(2,(void *)Line_end);
SCISendN(24,"U:BackdoorKey"); //解除安全模式命令格式
SCISendN(2,(void *)Line_end);
break;
}
//收到擦除信号
case 'E' :
{
j = SCIReN(8,SerialBuff);
if (j == 0)
{
//将收到的字符数据转换成十六进制数据
for (k=1; k<8; k++)
if((SerialBuff[k]>='0') && (SerialBuff[k]<='9'))
SerialBuff[k] = SerialBuff[k]-'0';
else SerialBuff[k] = SerialBuff[k]-'A'+0x0A;
//对页号和地址处理
page=CvtPage(SerialBuff);
addr=CvtAddr(SerialBuff);
//擦除指定的扇区
Flash_Erase_Sector(page,addr);
//发送擦除结果
SCISendN(250,(void *)addr);
}
break;
}
//收到写入信号
case 'W' :
{
j = SCIReN(11,SerialBuff);
if (j == 0)
{
//将收到的字符数据转换成十六进制数据
for (k=1; k<10; k++)
if ((SerialBuff[k]>='0') && (SerialBuff[k]<='9'))
SerialBuff[k] = SerialBuff[k]-'0';
else SerialBuff[k] = SerialBuff[k]-'A'+0x0A;
//对页号和地址处理
page=CvtPage(SerialBuff);
addr=CvtAddr(SerialBuff);
//接收写入的数据个数
N = SerialBuff[9];
//接收写入的数据
k = SCIReN(N,SerialBuff);
//对数据的奇偶个数进行处理
if (k == 0)
{
flag = 0;
if(1 == N%2)
{
SerialBuff[N] = 0xFF;
N += 1;
flag = 1;
}
//写入数据
Flash_Write_Nword(page,addr,(INT16U)SerialBuff,N/2);
if(1 == flag)
{
N -= 1;
}
//发送写入到Flash的数据
SCISendN(N,(void *)addr);
}
}
break;
}
//收到读取信号
case 'R' :
{
i = SCIReN(10,SerialBuff);
if (i == 0)
{
//将收到的字符数据转换成十六进制数据
for (i=1; i<10; i++)
if((SerialBuff[i]>='0') && (SerialBuff[i]<='9'))
SerialBuff[i] = SerialBuff[i]-'0';
else SerialBuff[i] = SerialBuff[i]-'A'+0x0A;
//对页号和地址处理
page=CvtPage(SerialBuff);
addr=CvtAddr(SerialBuff);
//接收要读取的数据个数
N = SerialBuff[9];
//发送要读取的数据
SCISendN(N,(void *)addr);
}
break;
}
//设置后门机制进入密码
case 'S' :
{
i = SCIReN(17,SerialBuff);
if (i == 0)
{
for(i=0; i<8; i++)
BackdoorKey[i]=Convert(SerialBuff[i*2+1],SerialBuff[i*2+2]);
Flash_SetKey(BackdoorKey);
SCISendN(8,(void *)0xFF00);
}
break;
}
//改变安全状态
case 'C' :
{
i = SCIReN(3,SerialBuff);
if (i == 0)
{
SecureByte[1]=Convert(SerialBuff[1],SerialBuff[2]);
Flash_SetStatus(SecureByte);
SCISendN(1,(void *)0xFF0F);
}
break;
}
//使用后门机制解密
case 'U' :
{
i = SCIReN(17,SerialBuff);
if (i == 0)
{
for(i=0; i<8; i++)
BackdoorKey[i]=Convert(SerialBuff[i*2+1],SerialBuff[i*2+2]);
Flash_unsecured(BackdoorKey);
SCISendN(20,"Unsercured Success !");
SCISendN(2,(void *)Line_end);
}
break;
}
}
}
}
//内部子程序实现
//Convert:将两个ASCII码组合成一个十六进制数--------------------------------*
//功 能:将两个ASCII码组合成一个十六进制数 *
//参 数:ASC1=十六进制数的高四位,ASC2=十六进制数的低四位 *
//返 回:temp=十六进制数 *
//-------------------------------------------------------------------------*
INT8U Convert(INT8U ASC1,INT8U ASC2)
{
INT8U temp;
//将ASC1转换成十六进制数
if((ASC1>='0') && (ASC1<='9'))
temp = ASC1-'0';
else
temp=ASC1-'A'+0x0A;
//取得十六进制数的高四位
temp=temp<<4;
//将ASC2转换成十六进制数并组合成一个十六进制数
if((ASC2>='0') && (ASC2<='9'))
temp = temp+ASC2-'0';
else
temp= temp+ASC2-'A'+0x0A;
return temp; //返回转换好的十六进制数
}
//CvtPage:从字节数组中提取页号---------------------------------------------*
//功 能:从字节数组buff中提取页号 *
//参 数:buff--字节数组 *
//返 回:页号 *
//注 意:无 *
//-------------------------------------------------------------------------*
INT8U CvtPage(INT8U buff[8])
{
INT8U page;
page = buff[1]<<4;
page = buff[2]+page;
return page;
}
//CvtAddr:从字节数组中提取地址---------------------------------------------*
//功 能:从字节数组buff中提取地址 *
//参 数:buff--字节数组 *
//返 回:地址 *
//注 意:无 *
//-------------------------------------------------------------------------*
INT16U CvtAddr(INT8U buff[8])
{
INT16U addr;
addr = buff[4]<<4;
addr = buff[5]+addr;
addr = addr<<8;
addr = addr+(buff[6]<<4);
addr = buff[7]+addr;
return addr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -