⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 IAPARM,ARM的IAP刷新程序
💻 CPP
字号:
/*--------------------------------------------------------------------------
             LPCARM之IAP应用举例及FLASH二次写入C++程序祥解

IAP全攻略将会衍生出许多系列,例如: 
1.Flash之二次写入.              (此点最简单但最重要)
2.Flash之计数器和变量.          (Flash做真正的EEPROM,而非STCMCU鼓吹的EEPROM)
3.公开产品Hex文件之远程代码还原.(加密解密)
这些将在随后发布。至少赶在情人节发个“情人版”。

同时菜农也给大家拜早年了~~~恭喜各位明年发大菜~~~

菜地公告:引用本文必须注明出处!!!
菜农HotPower 2007.2.12 于西安大雁塔菜地 http://HotPower.21ic.org/
---------------------------------------------------------------------------*/

#include "LPC213XDEF.h"
#include "main.h"
#include <string.h>
#include <stdio.h>
/*-----------------------------------
     串口0中断服务程序
-----------------------------------*/
extern "C" void IRQ_UART0 (void) __irq
{
unsigned int i;
unsigned char ch;
  switch(U0->IIR & 0x0f) {
    case 0x06://接收线状态
	  switch (U0->LSR) {
	    case 0x63:
		  break;
	  }
	  break;
/*-----------------------------------------------------------------
    串口接收部分代码
用while循环从FIFO中快速地取出全部数据,也可不用循环每次取出一个字节
的数据但达不到FIFO的功效。
-----------------------------------------------------------------*/
    case 0x04://接收数据可用
    case 0x0c://字符超时指示
	  while (U0->LSR & 0x01) {//从FIFO中取出全部数据
	    ch = U0->RBR;//从FIFO中取出1个字符的数据
	    Uart.RxBuffer[Uart.RxCount ++] = ch;//暂存入缓冲区
	  }
      break;
/*-----------------------------------------------------------------
    串口发送激活部分代码
由于U0->IIR & 0x0f==1时为LPCARM保留中断,可用于软件模拟激活UART0中断
利用此漏洞来实现非典的思想来达到实战的要求。
-----------------------------------------------------------------*/
	case 0x01://LPCARM保留中断,可用于软件模拟激活UART0中断
     if (!(VIC->SoftInt & (1 << VICIntSel_UART0))) {//硬件UART0中断
	   break;//正常的UART0中断退出
	 }
	 //至此成功利用了软件模拟中断偷入敌阵~~~继续运行,以达到发送首字符的目的
/*-----------------------------------------------------------------
    串口发送部分代码
这里主要是充分地利用LPCARM的16个字节的FIFO来实现“无限FIFO”
-----------------------------------------------------------------*/
    case 0x02://THRE中断
  	  Uart.TxBusy = Uart.TxCount != Uart.TxdCount;//保证FIFO发送全部结束时,缓冲区空不拒绝发送
	  for (i = 0; (i < 16) && (Uart.TxCount != Uart.TxdCount); i ++) {//1次写入FIFO最多16个字节
		ch = Uart.TxBuffer[Uart.TxdCount ++];//取出缓冲区1个字节数据
	    U0->THR = ch;//将缓冲区1个字节数据写入FIFO
	  }
	  VIC->SoftIntClr = (1 << VICIntSel_UART0);//这里必须清除此软件标志!!!
	  break;
  }
  VIC->VectAddr = 0x00;		/* 通知VIC中断处理结束							*/
}


int main (void) {
char str[512];
unsigned int result;
unsigned int i, j;
unsigned char *ramptr, *flashptr;
/*-------------------------------------------------------------------------
    扇区写法,特点简洁。缺点不知地址和大小
--------------------------------------------------------------------------*/
//  Iap.SelSector(7, 7);//选择扇区7
//  Iap.EraseSector(7, 7);//擦除扇区7
//  Iap.SelSector(0, 26);//选择全部扇区
//  Iap.EraseSector(0, 26);//擦除全部扇区,哈哈,肯定刚删除1个就死机
/*-------------------------------------------------------------------------
    地址写法,特点发晕。优点地址和大小自己掌握
--------------------------------------------------------------------------*/
//  Iap.EraseFlash(0x00000000,0x0007cfff);//擦除扇区0~26  500KByte(倒塌了)

//  Iap.EraseFlash(0x00000000,0x00000000);//擦除扇区0       4KByte
//  Iap.EraseFlash(0x00007000,0x00007fff);//擦除扇区7       4KByte
//  Iap.EraseFlash(0x00008000,0x0000ffff);//擦除扇区8      32KByte
//  Iap.EraseFlash(0x00070000,0x00077fff);//擦除扇区21     32KByte
//  Iap.EraseFlash(0x00078000,0x00078fff);//擦除扇区22      4KByte
//  Iap.EraseFlash(0x0007c000,0x0007cfff);//擦除扇区26      4KByte
  Uart.puts("器件标识号: ");
  Uart.Wait();//等待串口数据发送结束才能操作IAP
  result = Iap.ReadPartID();
  if (result != CMD_SUCCESS) {
    Uart.puts("失败    ");
  }
  else {
    sprintf(str, "%d    ", Iap.result[1]);
    Uart.puts(str);
    Uart.puts("器件名称: ");
    switch(Iap.result[1]) {
	  case Device_LPC2131:
	       strcpy(str, "LPC2131");
		   break;
	  case Device_LPC2132:
	       strcpy(str, "LPC2132");
		   break;
	  case Device_LPC2134:
	       strcpy(str, "LPC2134");
		   break;
	  case Device_LPC2136:
	       strcpy(str, "LPC2136");
		   break;
	  case Device_LPC2138:
	       strcpy(str, "LPC2138");
		   break;
	  default:
	       strcpy(str, "无效器件");
	}
    Uart.puts(str);//显示器件具体名称
  }
  Uart.puts("    Boot代码及版本号: ");
  Uart.Wait();//等待串口数据发送结束才能操作IAP
  result = Iap.ReadBootLoaderID();
  if (result != CMD_SUCCESS) {
    Uart.puts("失败\n");
  }
  else {
    sprintf(str, "%1d.%02d\n", Iap.result[1] >> 8, Iap.result[1] & 0xff);
    Uart.puts(str);
  }
  Uart.puts("擦除Flash扇区7(0x00007000~0x00007fff 4K字节): ");
  Uart.Wait();//等待串口数据发送结束才能操作IAP
//  result = Iap.SelSector(7, 7);
//  result = Iap.EraseSector(7, 7);
  result = Iap.EraseFlash(0x00007000, 0x00007fff);
  if (result != CMD_SUCCESS) {
    Uart.puts("失败\n");
  }
  else {
    Uart.puts("成功\n");
  }
  Uart.puts("查空Flash扇区7(0x00007000~0x00007fff 4K字节): ");
  Uart.Wait();//等待串口数据发送结束才能操作IAP
//  result = Iap.BlankCheck(7, 7);
  result = Iap.CheckFlash(0x00007000, 0x00007fff);
  if (result != CMD_SUCCESS) {
    Uart.puts("失败\n");
  }
  else {
    Uart.puts("空白\n");
  }
  Uart.puts("RAM(0x40000000~0x40000fff)写入Flash(0x00007000~0x00007fff 4K字节): ");
  Uart.Wait();//等待串口数据发送结束才能操作IAP
//  result = Iap.SelSector(7, 7);
//  result = Iap.UploadtoFlash(0x00007000, 0x40000000, 4096);
  result = Iap.WriteFlash(0x00007000, 0x40000000, 4096);
  if (result != CMD_SUCCESS) {
    Uart.puts("失败\n");
  }
  else {
    Uart.puts("成功\n");
  }
  Uart.puts("查空Flash扇区7(0x00007000~0x00007fff 4K字节): ");
  Uart.Wait();//等待串口数据发送结束才能操作IAP
//  result = Iap.BlankCheck(7, 7);
  result = Iap.CheckFlash(0x00007000, 0x00007fff);
  if (result != CMD_SUCCESS) {
    Uart.puts("失败\n");
  }
  else {
    Uart.puts("空白\n");
  }
  Uart.puts("RAM(0x40000f00~0x40000fff)比较Flash扇区7(0x00007f00~0x00007fff 256字节): ");
  Uart.Wait();//等待串口数据发送结束才能操作IAP
  result = Iap.CompareFlash(0x00007f00, 0x40000f00, 256);
  if (result != CMD_SUCCESS) {
    Uart.puts("失败\n");
  }
  else {
    Uart.puts("成功\n");
  }
  flashptr = (unsigned char *)0x00007f00;//Flash
  ramptr = (unsigned char *)0x40000f00;//Flash
  for(i = 0;i < 16; i ++) {
    sprintf(str, "0x%08X: ", flashptr);//Flash
    Uart.puts(str);
    for(j = 0;j < 16; j ++) {
      sprintf(str, "%02X ", *flashptr++);//Flash
      Uart.puts(str);
	}
    sprintf(str, "0x%08X: ", ramptr);//Flash
    Uart.puts(str);
    for(j = 0;j < 16; j ++) {
      sprintf(str, "%02X ", *ramptr++);//Flash
      Uart.puts(str);
	}
	Uart.puts("\n");
	Uart.Wait();//等待串口数据发送结束
  }
  Uart.Wait();//等待串口数据发送结束才能操作IAP
  Uart.puts("Flash二次写入扇区(0x00007000~0x000070ff 256字节): ");
  Uart.Wait();//等待串口数据发送结束才能操作IAP
//  result = Iap.SelSector(7, 7);
//  result = Iap.EraseSector(7, 7);
  result = Iap.EraseFlash(0x00007000, 0x00007fff);
  if (result == CMD_SUCCESS) {
    Iap.ReadFlash(0x00007000,(unsigned char*)&str, 256);//读入全0xff
    for(i = 0; i < 256; i += 2) {
      str[i] = 0x5f;
    }
    Iap.WriteFlash(0x00007000, (unsigned int)&str, 256);//1次写入0x5f
    if (Iap.result[0] != CMD_SUCCESS) {
      Uart.puts("1次写入0x5f失败  ");
    }
    else {
      Uart.puts("1次写入0x5f成功  ");
    }
    for(i = 0; i < 256; i += 2) {
      str[i] = 0xf5;
    }
    Iap.WriteFlash(0x00007000, (unsigned int)&str, 256);//2次写入0xf5
    if (Iap.result[0] != CMD_SUCCESS) {
      Uart.puts("2次写入0xf5失败\n");
    }
    else {
      Uart.puts("2次写入0xf5成功\n");
    }
    flashptr = (unsigned char *)0x00007000;
    ramptr = (unsigned char *)0x00007100;
    for(i = 0;i < 16; i ++) {
      sprintf(str, "0x%08X: ", flashptr);
      Uart.puts(str);
      for(j = 0;j < 16; j ++) {
        sprintf(str, "%02X ", *flashptr++);
        Uart.puts(str);
	  }
      sprintf(str, "0x%08X: ", ramptr);
      Uart.puts(str);
      for(j = 0;j < 16; j ++) {
        sprintf(str, "%02X ", *ramptr++);
        Uart.puts(str);
	  }
	  Uart.puts("\n");
	  Uart.Wait();//等待串口数据发送结束
    }
  }
  while(1) {
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -