LPC1768学习笔记

2023-05-16

LPC1768学习笔记:IAP升级

1.需求:通过串口给主机升级,主机的通信串口与升级串口相同
2.方法:要完成APP与IAP程序的切换判断,我们需要一个flag_update单独标识地址的,当flag_update为0xFF的时候,视为正常上电状态,程序由IAP(0x10000000)可以直接跳转到APP中执行;当flag_update为0x55的时候,视为远程烧写状态,程序由IAP开始之后,不跳转APP,而是执行自己的等待烧写流程。这边具体的流程和应用后面会具体介绍。
为了满足切换判断的功能,就需要该标志位不随APP程序的烧写而发生变化,所以我这边选择将IAP存储区之后的一个扇区,即地址0x10009000作为flag_update的存储地址,这样,在IAP程序不变的情况下,随便怎么烧写APP,只要目标地址满足上述表格中的要求,该标志位就不会发生变化。当然,使用用其他满足条件的存储方式(诸如存入外部Flash、存入EEPROM等)都可以。
一.芯片内存划分:芯片总内存为512K
(1)IAP程序内存 :0x0000 0000 - 0x0000 8FFF -36K(可根据自己调整)
(2)升级标志内存:0x0000 9000 - 0x0000 9FFF -4K
(3)数据缓冲内存:0x0000 B000 - 0x0000 BFFF -4k
(4)APP程序内存 :0x0000 C000 - 0x0007 FFFF -472k
芯片手册内存分布地址:
在这里插入图片描述
二.IAP流程图说明:
【IAP】:对于IAP程序来说,首先根据flag_update状态判断是否跳转APP,如果不跳转,则等待升级包。待升级包传输完毕,全部写到APP的地址中之后,再执行跳转到APP程序的起始地址执行(或者直接重启)。跳转或者重启之前需要将flag_update重新置为正常上电状态(0xFF),这样以避免下一次重启之后,程序仍然跑在IAP中。
【APP】:对于APP程序来说,需要实现的很简单,就是在串口收到某些外部指令的时候(可自由设置),将flag_update置为远程烧写状态(0x55),并重启。重启之后,MCU会重新从IAP程序开始执行,执行到flag_update判断,不跳转APP,进而执行IAP中等待升级文件的流程。
在这里插入图片描述
三:程序跳转与地址改写
APP:程序主要包括地址配置和跳转IAP两方面功能:
【1】地址配置:
将其地址配置为功能介绍中规划的地址,同时在系统初始化程序中,将SCB->VTOR的地址配置为APP程序的起始地址
在这里插入图片描述
在系统void SystemInit (void)改写
在这里插入图片描述
【2】跳转IAP:
APP程序需要修改的核心程序体如下所示,串口收数据处理逻辑中,如果收到满足条件的通信码,则改写flag_update所在地址上的值:


if(/*收到满足条件的通信码*/)
    {
        iap_init(BANK0);
        Iap_Write_Config_Value(0x55); //改写标志地址值
        //runIap(); // 跳转函数
        __set_FAULTMASK(1);  //直接重启
        NVIC_SystemReset();

四:IAP部分程序:主要概括为以下几个点:地址配置、跳转APP、串口读写
【1】:将其地址配置为功能介绍中规划的地址,同时在系统初始化程序中,将SCB->VTOR的地址配置为APP程序的起始地址:
在这里插入图片描述
在系统void SystemInit (void)改写
在这里插入图片描述
【2】跳转APP:
IAP程序中需要修改的核心程序体如下所示,上电IAP程序自检,如果位于0X10009000的标志位值为0xFF,则进入APP程序地址运行,反之执行自身的烧写流程:

int main (void)
{
	uint8_t  APP_UPDATE_VALUE=0xFF;
    uint8_t  work_mode=0;
	uint8_t *flag_update=(uint8_t *)FLAG_UPDATE_ADDRESS; //	 0x00009000  ---用户升级标志区 0xFF跳转APP--0X55停留IAP等待升级程序
	  	                                                                 
	UARTInit()	 ;  			 /* 初始化UART2---9600		*/	
	GucRcvOver  = 0;
	GulRcvCount = 0;
	memset(GucIapTmp, 0, 4096);		/* 缓冲区清零					*/

	if((*flag_update)==APP_UPDATE_VALUE)	   //0xFF
	 {
	 	work_mode=0;
		RunApp();
	 }
	 else
	 {
	   UARTSend((uint8_t *)(" 等待升级程序BIN文件中 "), strlen(" 等待升级程序BIN文件中 "));

	   zyIrqDisable(); 					   /* 禁止所有中断	        */
	   u32IAP_PrepareSectors(12, 29);		   /* 选择12-29扇区			*/
	   u32IAP_EraseSectors	(12, 29);		   /* 擦除12-29扇区         */
	   zyIrqEnable(); 
	   work_mode=1;				
	 }

	while(work_mode==1)
	{
		if(GucRcvOver == 0) //接收完成标志
		{
		  if (GulRcvCount != 0) 
		  {
			zyIrqDisable();  //禁止中断
    		userDataProgram();	    /*****下载更新程序*****/				
			zyIrqEnable();
		  }
		}
		else
		{
		 	*flag_update=0x55;	   /*****修改程序跳转标志*****/
			UARTSend((uint8_t *)(" 升级结束,等到重启中 "), strlen(" 升级结束,等到重启中 "));
			myDelay (5);                             /*	延时等待稳定		*/
			memset(GucIapTmp, 0x00, 256);			/* 	临时缓冲区清空		*/
	
	   		/**刚烧录完跳转有时不稳,直接重启***/
		    __set_FAULTMASK(1);
		    NVIC_SystemReset();
		}
	}
}

其中跳转接口runApp逻辑如下所示:

void RunApp(void )
{
  	 	/*  Change the Vector Table to the USER_FLASH_START 
			in case the user application uses interrupts 
			将矢量表更改为用户闪存启动 如果用户应用程序使用中断 */
//	SCB->VTOR = USER_APP_START_ADD ;
	JMP_Boot(USER_APP_START_ADD );
//	iap_load_app(USER_APP_START_ADD );

}
__asm void JMP_Boot( uint32_t address ){
   LDR SP, [R0]		;Load new stack pointer address
   LDR PC, [R0, #4]	;Load new program counter address
}

【3】:串口收发就是正常串口收发配置即可;

void UART2_IRQHandler (void) 
{
//  uint8_t IIRValue, LSRValue;
  uint8_t Dummy = Dummy;
   volatile  uint8_t i; 

   while ((UART2->IIR & 0x01) == 0)
   {                                       								/* 判断是否有中断挂起           */
      switch (UART2->IIR & 0x0E) {                                      /* 判断中断标志                 */
        
		case 0x04:                                         				/* 接收数据中断      A&E=0X04  */
            for (i = 0; i < 8; i++) {                 				    /* 连续接收8个字节              */
                puiRcvData[GulRcvCount++] = UART2->RBR;            	    /*  接收缓冲寄存器				*/
            }
            break;
        case 0x0C:                                                      /* 字符超时中断                 */
            while ((UART2->LSR & 0x01) == 0x01) {                            /* 判断数据是否接收完毕         */ 
                puiRcvData[GulRcvCount++] = UART2->RBR;
            }
		    GucRcvOver = 1;
            break; 
        default:
            break;
        }
    } 	
								
}

【5】:将缓冲区的代码复制进去APP区代码:

void  userDataProgram (void)
{
	uint32_t  ulAddr= 0;	/* 字节偏移量清0*/							/* Addr:字节偏移量 				*/
	uint32_t  ulProgramCount;						                    /* ProgramCount:编程到Flash扇   */
                                                 
	while (GulRcvCount != 0) 
	{
		if (GulRcvCount > (1024 * 4)) 
		{									/* 一次最多写入4K代码量			*/
			memcpy(GucIapTmp, puiRcvData + ulAddr, 1024 * 4);
			GulRcvCount 	-= (1024 * 4);	        //清零
			ulProgramCount = 1024 * 4;
		   UARTSend((uint8_t *)(" 写入数据错误,请重新发送BIN文件 "), strlen(" 写入数据错误,请重新发送BIN文件 "));
		}
		else 
		 {
			memcpy(GucIapTmp, puiRcvData + ulAddr, GulRcvCount);	//puiRcvData --数据缓冲区
			ulProgramCount = GulRcvCount;	
			GulRcvCount = 0;
			if ((ulProgramCount   == 256 ) 
			    ||(ulProgramCount == 512 )
			    ||(ulProgramCount == 1024)
			    ||(ulProgramCount == 4096)) {
				
				goto flashProgram;
			}

			/* 
			 *  满足编程字节数的要求,256、512、1024等 
			 */
			if (ulProgramCount < 256) {
				ulProgramCount = 256;					
				goto flashProgram;
			}
			if (ulProgramCount < 512) {
				ulProgramCount = 512;
				goto flashProgram;
			}
			if (ulProgramCount < 1024) {
				ulProgramCount = 1024;
				goto flashProgram;
			}
			if (ulProgramCount < 4096) {
				ulProgramCount = 4096;
				goto flashProgram;
			}
		}
        flashProgram:

		/******* 升级用户程序空间 *******/
			zyIrqDisable();
			u32IAP_PrepareSectors(12, 29);									    /* 选择扇区			        */

			u32IAP_CopyRAMToFlash(USERLOW + ulAddr, (uint32_t)GucIapTmp, ulProgramCount);	   /* 写数据到FLASH 		        */
                                      
			zyIrqEnable();
			ulAddr += ulProgramCount;

	}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LPC1768学习笔记 的相关文章

  • 并查集--解析关押罪犯问题(二)

    在网上看到一道ACM竞赛题 xff0c 很巧妙的运用了并查集解决了一个现实生活的问题 xff0c 然而网上的解析太少 xff0c 在这里贴出来我的思考 xff1a 题目 xff1a S 城现有两座监狱 xff0c 一共关押着N 名罪犯 xf
  • 如何在Windows下安装ubuntu子系统

    TOCM 如何在Windows下安装ubuntu子系统 1 windows设置 首先打开控制面板 xff0c Windows设置 xff0c 勾选Windows下的linux系统 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直
  • R语言批量生成CaseWhen的解决方案

    近期写R代码 xff0c 经常用dplyr case when结合stringr str detect进行条件判断 痛点 xff1a 判断条件可能会改或增删 xff0c 全写在case when里 xff0c 代码冗余且不利于复制和维护 x
  • R新管道操作符 |> 使用体验

    R users应该对magrittr的 gt 管道符都不陌生 然后R官方估计看如此普及不能再装看不见了 xff0c 于是4 1版本官方也出了个管道操作符 gt xff0c 简直就是baseR党的福音啊 虽然我不是忠实的baseR党 xff0
  • R包bs4Dash控件效果对照图

    记录一下bs4Dash各个控件的效果 xff0c 方便查找和对照 案例均来自于官方文档 accordion accordion span class token punctuation span id span class token op
  • 用一个公式列出R语言所有的数据集

    做了个app xff0c 点R datasets快速查看数据集 测试数据 xff0c 经常用到R语言的数据集 xff0c 于是就开始寻思怎么用尽可能短的代码把所有的数据集一次性全列出来 xff0c 再慢慢挑选 代码如下 xff1a data
  • R语言用dbplyr操作数据库解决丢失连接以持久化tbl查询的方案

    在我看来 xff0c R语言tidyverse包里 xff0c 最高价值的包是dbplyr xff08 dplyr的数据库版 xff09 xff0c 用起来非常爽 xff0c 但最怕的是丢失数据库连接 xff0c 一丢则流畅感瞬间崩塌 xf
  • iPad使用UTM SE装Win7

    因工作需要 xff0c 有的公文只能在windows系统下才能通过vpn及专用控件情况下审批 xff0c 带个电脑嫌笨重 xff0c 经测试 xff0c 在ipad上通过虚拟机成功安装win7系统 xff0c 当然还可以安装linux ma
  • Excel内置函数参数为整列是否会有性能损失

    比如 xff0c sumif a a b c c 的性能是否会比限定范围的公式sumif a1 a10 b c1 c10 的性能更差 答案是 xff0c 不会 看微软官方的回答 所以 xff0c 放心大胆的用sumif 43 entire
  • 远程代码执行(RCE)漏洞

    文章目录 1 fastjson 远程代码执行漏洞2 简单复现3 反弹shell3 1 正向反弹shell3 2 反向反弹shell 1 fastjson 远程代码执行漏洞 最近读到一篇文章 fastjson 远程代码执行漏洞分析 xff0c
  • 洛谷 P4180 【模板】严格次小生成树

    题目链接 https www luogu org problem P4180 分析 根据Kruskal算法的思想 xff0c xff08 非 xff09 严格次小生成树应该是来自最小生成树的 xff1b 具体来说 xff0c 是将某条非树边
  • Pyinstaller打包高级用法

    前段时间在制作词云制作小工具的时候 xff0c 直接在命令行用pyinstaller F 工具 py指令打包成功后 xff0c 启动exe可执行文件的时候各种报错 今天 xff0c 我们就分享一下踩坑经过 目录 xff1a 1 安装pyin
  • yum无法找到xorg-x11-xkb-utils-devel包的解决方法

    缘由 使用robotgo开发 xff0c 需要安装依赖如下 xff08 官方文档要求 xff09 96 96 96 Fedora sudo dnf install libxkbcommon devel libXtst devel libxk
  • Ubuntu中突然断网了

    使用命令行 xff0c 网络恢复 sudo service network manager restart
  • Windows 平台 VSCode 使用 SSH 免密登录 docker 中的 Ubuntu 虚拟机

    可以先了解一下 SSH 免密登录的原理 xff08 不了解也不影响 xff09 xff1a SSH 设置密钥对实现免密码连接 知乎 参考了 xff1a Docker下多机器免密码SSH登录 腾讯云开发者社区 腾讯云 该博客的场景较为复杂 x
  • 最新codeforces的rating评级(等级

    一 xff1a 在你没有打任何Codeforces的比赛前 xff0c 你是 unrated xff08 暂未评级 xff09 xff0c 名字颜色是黑色 rating 61 1500 xff08 不显示 xff0c 只有打了比赛之后才会体
  • W: GPG 错误:file:/var/cuda-repo-ubuntu2004-11-1-local Release: 由于没有公钥,无法验证下列签名: NO_PUBKEY F60F4B3D7FA

    记录一下学习 今天安装cuda11 1的时候 在解压包的时候遇到的问题 W span class token punctuation span GPG 错误 xff1a span class token builtin file span
  • virt-install工具创建虚拟机命令介绍(详细)

    virt install介绍 virt span class token operator span install是一个命令行工具 xff0c 它能够为 span class token constant KVM span Xen或其它支
  • 什么是状态机?用C语言实现进程5状态模型

    前言 状态机在实际工作开发中应用非常广泛 xff0c 在刚进入公司的时候 xff0c 根据公司产品做流程图的时候 xff0c 发现自己经常会漏了这样或那样的状态 xff0c 导致整体流程会有问题 xff0c 后来知道了状态机这样的东西 xf
  • 希腊字母与对应的Unicode码

    希腊字母 xff08 大小写各24个 xff09 xff1a 大写 xff1a xff08 对应Unicode码为 xff1a 913 937 xff0c 无930 xff09 小写 xff1a xff08 对应Unicode码为 xff1

随机推荐

  • Debian OS本地及局域网apt源搭建

    Debian OS本地及局域网apt源搭建 一 本地apt源搭建1 1 上传ISO镜像到本地OS1 2 挂载ISO镜像1 3 编辑apt配置文件1 4 验证apt源 二 局域网apt源搭建2 3 编辑本地apt配置文件2 4 验证apt源
  • 使用conda时出现Solving environment: failed错误

    一 问题 win10系统下 xff0c 在安装anaconda后 xff0c 执行conda install mingw libpython时报错如图 D anaconda Scripts gt conda install mingw li
  • 政务外网后端接口PUT和DELETE不通

    政务外网后端接口PUT和DELETE不通 错误信息 解决思路 1 xff0c 首先排查政务内网环境下接口是否能通 2 查看nginx反向代理问题 3 查看接口是否调通后端 xff0c 后端是否有相应信息 4 排查端口是否对外开放 5 关闭防
  • 安装Anaconda3后缺失大量文件的解决方法:安装旧的版本再升级

    项目场景 xff1a 安装Anaconda3 项目场景 xff1a 安装Anaconda3后缺失大量文件 问题描述 安装Anaconda3后缺失大量文件 正确安装后的样子 xff1a 原因分析 xff1a 找了很多帖子 xff0c 也尝试了
  • IOS开发 汉化

    UIImagePicker TZImagePicker选择图片时默认是英文 只需要修改xcode本地设置即可 xff0c 具体操作如图示 1 选择info 2 添加Localizations 3 将English改成Chinese 2 iO
  • WSL2 Linux搭建xfce4桌面和使用xrdp远程连接

    基于Ubuntu20 04测试 1 安装 span class token function sudo span apt span class token function install span xfce4 xrdp y 如果遇到下面页
  • 修改 WSL2 可用内存大小和交换分区大小

    WSL2默认可以使用的内存大小为主机的80 对于Linux而言即使装了桌面 一般的开发也没必要给这么多内存 分多了 反而有可能卡主机的Windows 操作 1 打开Windows资源管理器 地址栏输入 UserProfile 回车 在该目录
  • C++代码: Linux下获取基本设备信息

    测试环境 基于C 43 43 20构建测试 g 43 43 10 2 1 CMakeLists txt 设置用于构建该项目的最低cmake版本 cmake minimum required VERSION 3 1 设置项目名称和编程语言 p
  • VMware虚拟机Ubuntu无法使用摄像头的问题

    注 之前我在使用Ubuntu的虚拟机中 搞OpenCV开发 需要使用摄像头 遇到了摄像头无法使用的问题 后面折腾了很久才发现 USB3 1 兼容设置的问题 刚才又用新的虚拟机配置环境 又遇到了之前的问题 因此做个记录 1 摄像头未连接到虚拟
  • 一文搞懂光纤的方方面面

    光纤 一直以为光纤模块会非常贵 xff0c 呃 xff0c 只能说没有想象中的贵 xff0c 相比网线还是贵上不少 一个常见的光纤系统通常会包括收发器 xff0c 光电转换器还有光纤收发器 通常简单的入门级一套下来可能也在200 300左右
  • msys2配置cmake构建环境

    注 本人主要在Linux下搞开发 使用msys2是为了方便移植部分程序到Windows下 做以下纪录方便环境配置 1 换源 span class token comment 更新本地软件数据库 span pacman Sy 2 安装开发工具
  • Windows 10安装 WSL2 (Ubuntu 20.04)

    条件 对于 x64 系统 xff1a 版本 1903 或更高版本 xff0c 采用 内部版本 18362 或更高版本 对于 ARM64 系统 xff1a 版本 2004 或更高版本 xff0c 采用 内部版本 19041 或更高版本 低于
  • Ubuntu 20.04 server 切换中文语言

    1 安装区域设置 locales Ubuntu 一般是预装了的 Kali Linux 和 Debian可能没有 就需要安装 更新索引 sudo apt update span class token comment 安装locales sp
  • 全新安装的Termux配置Ubuntu环境

    基于 Termux 0 101 测试 换国内源 默认官方源在国外速度慢 有梯子的话也可以不换 这里换清华源为例 更多 执行命令 span class token function sed span i span class token st
  • 1g 路由器使用

    前言 xff08 1 xff09 首次使用以及断网后配置都可参看本文 xff08 2 xff09 简谈 xff0c 创翼实际登录拨号的账号其实并不是 电话 64 cqit xff0c 而是在这个账号前面根据拨号时间生成一个随机字符串 xff
  • 基于随机森林的手写数字识别 (OpenCV)

    OpenCV 4 5 1 C 43 43 20 Ubuntu 20 04 素材 来源 基于 K近邻博文 中原5000个手写数字得到的按行排列的手写数字数据以及对应行的标签 保存为图片后直接放到这里使用 避免重复数据处理 右键图片另存为 行数
  • 使用支持向量机分类 (OpenCV)

    OpenCV 4 5 1 C 43 43 20 Ubuntu 20 04 素材 像素点和分类标签 组态档 设置用于构建该项目的最低cmake版本 cmake minimum required VERSION 3 1 设置项目名称和编程语言
  • 退出该博客平台声明

    试用c s d n快三个月了 xff0c 最不满的就是审核的问题 1 我自己写的东西因为有误修改了一下再提交就说我的博文已有相似的 xff0c 审核不通过 xff0c 不止一次 2 反而好奇有人抄了我的却发出去了 这应该是最后一次在这里发文
  • CMake Error at CMakeLists.txt:11 (find_package): Found package configuration file: /home/luw

    参考资料 xff1a https www cnblogs com newneul p 8364924 html CMake Error at CMakeLists txt 11 find package Found package conf
  • LPC1768学习笔记

    LPC1768学习笔记 xff1a IAP升级 1 需求 xff1a 通过串口给主机升级 xff0c 主机的通信串口与升级串口相同 2 方法 xff1a 要完成APP与IAP程序的切换判断 xff0c 我们需要一个flag update单独