当前位置:网站首页 >> 产品/行业资讯 >>

从简单的文件偏移,读取和写入进一步研究MCU程序的下载和软件升级(第1部分)

& nbsp;关于MCU固件的更新和下载,老师上大学时并未详细解释,但知道程序xxx.c已编译为生成xxx.hex或xxx.bin,然后生成了相应的xxx.hex和xxx。

bin将其下载到MCU,然后各种程序开始运行,程序处于正常运行状态,并且远程获取更新包,然后对程序进行更新。

程序的仅一部分被更新,而不会影响其他部分。

这就是所谓的软件升级。

& nbsp; & nbsp; & nbsp;下班后,为了学习技术知识,不要只是停留在表面上,而是要深入分析实现原理。

程序如何下载到MCU?我们的软件如何更新而不影响其他部分?在本节中,我们将使用一个简单的文件操作示例来说明最基本的原理。

& nbsp; & nbsp; & nbsp;首先,我们编写一个程序来创建1.bin文件,并将数据写入1,2,3,4,5,6,7,8,9,10中。

例程如下:test .c #include& lt; stdio.h& gt; #include& lt; unistd.h& gt; #include& lt; fcntl.h& gt; int main(void){int fd = -1;  char buffer [] = {1,2,3,4,5,6,7,8,9,10}; fd = open(“ 1.bin”,O_RDWR | O_CREAT); if(fd& lt -1){printf(" Open file fair ”); return -1;} write(fd,buffer,10);关闭(FD); return 0;} 现在,我们希望在1.bin中更改地址的值,而不会影响其他数据。

在下面的程序中,我们更改offset = 5的地址并将该地址的值修改为16。

例程如下:test1.c #include< stdio.h& gt; #include& lt; unistd.h& gt; #include& lt; fcntl.h& gt; & nbsp; int main(void){int i& nbsp ;; int fd = -1; 字符缓冲区[11] = {0}; int数据= 16; // 1,打开1.bin File& nbsp; fd = open(“ 1.bin”,O_RDWR); if(fd& lt -1){printf(“公开文件公平 ”); return -1;} //读取1.bin& nbsp;中的内容读(fd,buffer,11); for(i = 0; i& lt; 10; i ++){printf(“ buffer [%d]:%d ",i,buffer [i]);} printf(" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx读取原始数据xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ”); // 2,从地址0偏移地址1.bin到地址5  lseek(fd,5,SEEK_SET); // 3,将data = 16的值写入文件1.bin地址5的偏移量。

写入(fd,& amp; data,1);  // 4,清除缓冲区memset(缓冲区,0,11); // 5,将地址偏移更改回地址0 lseek(fd,0,SEEK_SET);  // 6,修改后读取1.bin中的内容读(fd,buffer,11); for(i = 0; i& lt; 10; i ++){printf(“ buffer [%d]:%d " i,buffer [i]); }& nbsp; printf(" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx读取修改后的数据xxxxxxxxxxxxxxxxxxxxxxxxxxxx ”); // 7。

关闭文件描述符。

关闭(FD); return 0;}在此程序中,我们首先读取原始1.bin中的数据,然后使用lseek函数将文件偏移到offset =,然后使用write将data = 16的数据写入offset =的地址。

5,重写此地址的数据,然后调用lseek将偏移地址重写回从0开始,然后读取所有重写的数据数据,效果如下:显然,第二个程序将数据写入即更改offset = 5的地址不会影响其他数据,而是以覆盖的形式直接覆盖offset地址的数据。

& nbsp; & nbsp; & nbsp;这个简单的例子可以说明什么?这与我们程序的最终更新原理相同。

让我们编写另一个程序: & nbsp; & nbsp; test2.c:#include& lt; stdio.h& gt; #include& lt; unistd.h& gt; #include& lt; fcntl.h& gt; & nbsp; & nbsp; int main(void){int i; int fd = -1;  char buffer [] = {2,1,4,2,3,1,4,8,9,6};字符缓冲区1 [11]; fd = open(“ 1.bin”,O_RDWR | O_CREAT); if(fd& lt -1){printf(“打开文件公平 ”); return -1;} //偏移地址0& nbsp; lseek(fd,0,SEEK_SET); //写入10个数据写(fd,buffer,10); //将地址偏移量为amp; nbsp; ; lseek(fd,0,SEEK_SET); //读取1.bin& nbsp;中的内容读(fd,buffer1,11); for(i = 0; i& lt; 10; i ++){printf(“ buffer1 [%d]:%d ",i,buffer1 [i]);} close(fd); return 0;}操作结果:从这里我们可以知道从偏移地址0到偏移地址9的数据已被修改,这也是我们MCU固件更新的原理。

& nbsp; & nbsp;固件更新和软件升级的原理是相同的,最后是用二进制数据简单地覆盖相应的地址区域。

在这里,我给出的示例仅仅是为了说明最基本的原理,MCU固件下载和程序更新中仍然有许多复杂的过程。

例如,首先将要更新的数据复制到区域tha

欢迎您的咨询