11、软件锁
软件锁可以实现但不局限于环环相扣。对于初始化序列或者有一定先后顺序的函数调用,为了保证调用顺序或者确保每个函数都被调用,我们可以使用环环相扣,实质上这也是一种软件锁。此外对于一些安全关键代码语句(是语句,而不是函数),可以给它们设置软件锁,只有持有特定钥匙的,才可以访问这些关键代码。
比如,向Flash写一个数据,我们会判断数据是否合法、写入的地址是否合法,计算要写入的扇区。之后调用写Flash子程序,在这个子程序中,判断扇区地址是否合法、数据长度是否合法,之后就要将数据写入Flash。
由于写Flash语句是安全关键代码,所以程序给这些语句上锁:必须具有正确的钥匙才可以写Flash。这样即使是程序跑飞到写Flash子程序,也能大大降低误写的风险。
/***************************************************************
* 名称:RamToFlash()
* 功能:复制RAM的数据到FLASH,命令代码51。
* 入口参数:dst 目标地址,即FLASH起始地址。以512字节为分界
* src 源地址,即RAM地址。地址必须字对齐
* no 复制字节个数,为512/1024/4096/8192
* ProgStart 软件锁标志
* 出口参数:IAP返回值(paramout缓冲区) CMD_SUCCESS,SRC_ADDR_ERROR,DST_ADDR_ERROR,
SRC_ADDR_NOT_MAPPED,DST_ADDR_NOT_MAPPED,COUNT_ERROR,BUSY,未选择扇区
****************************************************************/
void RamToFlash(uint32 dst, uint32 src, uint32 no,uint8 ProgStart)
{
PLC_ASSERT("Sector number",(dst>=0x00040000)&&(dst<=0x0007FFFF));
PLC_ASSERT("Copy bytes number is 512",(no==512));
PLC_ASSERT("ProgStart==0xA5",(ProgStart==0xA5));
paramin[0] = IAP_RAMTOFLASH; // 设置命令字
paramin[1] = dst; // 设置参数
paramin[2] = src;
paramin[3] = no;
paramin[4] = Fcclk/1000;
if(ProgStart==0xA5) //只有软件锁标志正确时,才执行关键代码
{
iap_entry(paramin, paramout); // 调用IAP服务程序
ProgStart=0;
}
else
{
paramout[0]=PROG_UNSTART;
}
}
该程序段是编程lpc1778内部Flash,其中调用IAP程序的函数iap_entry(paramin, paramout)是关键安全代码,所以在执行该代码前,先判断一个特定设置的安全锁标志ProgStart,只有这个标志符合设定值,才会执行编程Flash操作。
如果因为意外程序跑飞到该函数,由于ProgStart标志不正确,是不会对Flash进行编程的。
|