STM32+IAP方案的实现,IAP实现原理(详细解决说明)。

2023-11-05

此文档内容摘自: http://www.51hei.com/stm32/4315.html

可参考文档:https://blog.csdn.net/gin_love/article/details/82015646

 

 

 

--基于STM32F103ZET6的UART通讯实现

 

一、什么是IAP,为什么要IAP

      IAP即为In Application Programming(在应用中编程),一般情况下,以STM32F10x系列芯片为主控制器的设备在出厂时就已经使用J-Link仿真器将应用代码烧录了,如果在设备使用过程中需要进行应用代码的更换、升级等操作的话,则可能需要将设备返回原厂并拆解出来再使用J-Link重新烧录代码,这就增加了很多不必要的麻烦。站在用户的角度来说,就是能让用户自己来更换设备里边的代码程序而厂家这边只需要提供给用户一个代码文件即可。

      而IAP却能很好的解决掉这个难题,一片STM32芯片的Code(代码)区内一般只有一个用户程序。而IAP方案则是将代码区划分为两部分,两部分区域各存放一个程序,一个叫bootloader(引导加载程序),另一个较user application(用户应用程序)。bootloader在出厂时就固定下来了,在需要变更user application时只需要通过触发bootloader对userapplication的擦除和重新写入即可完成用户应用的更换。如图1-1所示

图 1-1

      在程序执行初始进入bootloader,在bootloader里面检测条件是否被触发(可通过按键是否被按下、串口是否接收到特定的数据、U盘是否插入等等),如果有则进行对user application进行擦除和重新写入操作,如果没有则直接跳转到user application执行应用;如果有则进行擦除用户代码并重新写入新的用户代码。

 

二、STM32F103ZET6硬件条件

      STM32F103ZET6的启动方式有三种:内置FLASH启动、内置SRAM启动、系统存储器ROM启动,通过BOOT0和BOOT1引脚的设置可以选择从哪中方式启动,这里选择内置的FLASH启动。其FLASH的地址为0x08000000—0x0807ffff,共512KB,这些都能从芯片数据手册中直接得到。而这里首要的一个问题是中断的问题。正常情况下发生中断的过程为:发生中断(中断请求)à到中断向量表查找中断函数入口地址à跳转到中断函数à执行中断函数à中断返回。也就是说在STM32的内置的Flash中有一个中断向量表来存放各个中断服务函数的入口地址,内置Flash的分配情况大致如下图2-1。

图2-1

 

在只有一个程序的情况下,程序执行的走向应该如图2-2所示(借用网友的原图)。

图2-2

      STM32F10x有一个中断向量表,这个中断向量表存放在代码开始部分的后4个字节处(即0x08000004),代码开始的4个字节存放的是堆栈栈顶的地址,当发生中断后程序通过查找该表得到相应的中断服务程序入口地址,然后再跳到相应的中断服务程序中执行。上电后从0x08000004处取出复位中断向量的地址,然后跳转到复位中断程序的入口(标号①所示),执行结束后跳转到main函数中(标号②所示)。在执行main函数的过程中发生中断,则STM32强制将PC指针指回中断向量表处(标号③所示),从中断向量表中找到相应的中断函数入口地址,跳转到相应的中断服务函数(标号④所示),执行完中断函数后再返回到main函数中来(标号⑤所示)。

      若在STM32F103x中使用IAP方案,则内置的Flash分配情况大致如下图2-3。

图2-3

在内置的Flash里面添加一个BootLoader程序,BootLoader程序和user application各有一个中断向量表,假设BootLoader程序占用的空间为N+M字节,则程序的走向应该如图2-2所示(借用网友的原图并做改动,其中虚线部分为原图步骤④⑤的走向,本人改为指向灰色部分)。

图2-2

      上电初始程序依然从0x08000004处取出复位中断向量地址,执行复位中断函数后跳转到IAP的main(标号①所示),在IAP的main函数执行完成后强制跳转到0x08000004+N+M处(标号②所示),最后跳转到新的main函数中来(标号③所示),当发生中断请求后,程序跳转到新的中断向量表中取出新的中断函数入口地址,再跳转到新的中断服务函数中执行(标号④⑤所示),执行完中断函数后再返回到main函数中来(标号⑥所示)。

      对于步骤④⑤,网友认为是:“在main执行的过程中,如果CPU得到一个中断请求,PC指针仍强制跳转到地址0x08000004中断向量表处,而不是新的中断向量表,如图标号④所示,程序再根据我们设置的中断向量表偏移量,跳转到对应中断源新的中断服务程序中,如图标号⑤所示”。我对此的理解是:“当发生中断后,程序从0x08000004(旧)处的中断向量表中得到相应的中断服务函数入口地址,继而跳转到相应的中断服务程序”。但是旧的中断向量列表里边存放的是IAP程序中断函数的入口地址,它是如何得到user程序中断函数的入口地址呢?所以我觉得此种说法是错误的。“当发生中断时PC指针强制会跳转到0x08000004处”这种说法并没有错,只是忽略了后续的一些知识要点而导致这个说法出现矛盾。

      对于步骤④⑤我认为的是,在main函数的执行过程中,如果CPU得到一个中断请求,PC指针本来应该跳转到0x08000004处的中断向量表,由于我们设置了中断向量表偏移量为N+M,因此PC指针被强制跳转到0x08000004+N+M处的中断向量表中得到相应的中断函数地址(待求证),再跳转到相应新的中断服务函数,执行结束后返回到main函数中来。

 

三、实现过程

      STM32F103ZET6的Flash地址为0x08000000—0x0807ffff共512KB,把这512KB的空间分为两块,第一块大小为32KB存放BootLoader程序,剩余的空间存放用户程序(根据实际情况分配这两块空间的大小,BootLoader程序占用的空间越小越好,则BootLoader地址为0x08000000—0x08007fff,用户程序地址为0x08008000—0x0807ffff。BootLoader流程图大致应该如下:

1、初始化时钟。

2、初始化中断向量表地址。

3、初始化按键。      (使用按键触发方式,上电时如果按键被按下则进行用户程序更新操作)

4、初始化串口。

5、检测按键是否被按下,是则执行步骤6,否则执行步骤10。

6、擦除用户程序(擦除0x08008000—0x0807ffff地址空间Flash)。

7、从串口读取新的用户代码数据,把代码写入用户程序空间。

8、检测串口数据接收完毕?是则执行步骤9,否则跳回步骤7。

9、用户程序更新完毕,等待重新上电或硬件复位。

10、跳转到用户程序(强制将PC指针跳转到0x08008000+4处)。

     

到这里首先要解决的问题就有:

1、如何进行对STM32的Flash进行擦除和写入操作。

2、中断向量表偏移如何设置。

3、如何改变代码存放的地址空间(因为BootLoader要存放在0x08000000处,用户程序要存放在0x08008000处,而默认的代码存放的地址空间为0x08000000)。

4、怎么进行PC指针的强制跳转,跳转时需要做些什么。

5、串口接收的用户代码数据是什么样的代码数据,是一种什么样的文件。

 

问题的解决:

1、使用STM32的固件库函数,只需调用几个库函数即可轻松解决,使用的固件库为stm32f10x_flash.c文件,对Flash的操作过程简要为:Flash解锁àFlash擦除àFlash写入àFlash上锁。(对Flash编程的更详细操作参考STM32F10xxx闪存编程手册)

①解锁:

FLASH_Unlock();            //解锁Flash

FLASH_SetLatency(FLASH_Latency_2);            //因为系统时钟为72M所以要设置两个时钟周期的延时

②擦除:

for(i=0;i<240;i++)

{

  if(FLASH_ErasePage(FLASH_ADDR+i*2048) != FLASH_COMPLETE)      //一定要判断是否擦除成功

    return ERROR;

}

说明:FLASH_ErasePage(uint32_t Page_Address)即为Flash擦除操作,按页擦除,每页2KB,Page_Address为页的起始地址,如0x08000000是第一页起始地址,0x08000800为第二页起始地址,这里的操作擦除了0x08008000—0x0807ffff地址空间的Flash。

③写入:

unsigned char buf[1024];            //假设待写入的代码数据

unsigned short temp;            //临时数据

for(i=0;i<512;i++)

{

      temp = (buf[2*i+1]<<8) | buf[2*i];            //2个字节整合为1个半字

      if(FLASH_ProgramHalfWord(ADDR,temp) != FLASH_COMPLETE)      //判断是否写入成功

      {

            Return ERROR;

      }

ADDR +=2;      //地址要加2,因为每次写入的是2个字节(1个半字)

}

说明:因为STM32的Flash写入为双字节(1个半字)写入,FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)函数即为对地址为Address写入1个半字的Data,每次写入完成后地址要加2。

④上锁:

FLASH_Lock();      //Flash 上锁,一个固件库函数即可实现。

 

2、关于中断向量表的偏移设置,对于BootLoader程序只需设置中断向量表的指向在0x08000000处,对于用户程序需要设置中断向量表的指向在0x08008000处即可。

①在BootLoader程序的中断向量表指向设置中应有这么一句:

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);      //设置中断向量表指向

其中NVIC_VectTab_FLASH是个宏定义,的值为0x08000000。

②在用户程序的中断向量表指向设置用应有这么一句:

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000);      //设置中断向量表指向

 

3、确认代码存放的地址空间,在IAR和在Keil中的设置是不同的,网上有在Keil中设置的方法,设立介绍在IAR软件环境下的设置方法。

①在固件库目录\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template\EWARM下找到一个stm32f10x_flash.icf文件,将其复制到工程目录中来,在打开IAR工程,将配置文件添加到工程中,如下图3-2所示

图3-1

②在工程中打开stm32f10x_flash.icf该文件,修改两个参数即可改变代码存放的地址空间,图下图3-2所示。

图3-2

 

4、关于PC指针的强制跳转,想在BootLoader程序中将PC指针跳转到用户代码处,可选择下面的操作

typedef        void (*pFunction)(void);     

pFunction       Jump_To_Application;

uint32_t       JumpAddress;

#define       ApplicationAddress       0x08008000

 

 

if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)       //--------①

{

  JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);                  //--------②

  Jump_To_Application = (pFunction) JumpAddress;                              //--------③

  __set_MSP(*(__IO uint32_t*) ApplicationAddress);                             //--------④

  Jump_To_Application();                                                                 //--------⑤

}

①因为用户程序开始位置(0x08008000处)的前4个字节存放的是堆栈的地址,堆栈地址必定是指向RAM空间的,而STM32的RAM空间起始地址为0x20000000,所以要进行判断。

②程序跳转地址的确认,前面已经说过0x08008004处的4个字节存放的是复位函数的入口地址,该句的意思为获得(ApplicationAddress + 4)地址处的数据,即为获得新的复位函数入口地址。

③令Jump_To_Application这个函数指针指向复位函数入口地址。

④堆栈的初始化,重新设定栈顶代地址,把栈顶地址设置为用户代码指向的栈顶地址。

⑤跳转到新的复位函数。

 

5、通过串口来接收代码数据,就是PC机通过串口将代码数据发送到STM32中去。这里就涉及到两个问题:

①数据怎么得来。

②数据传输的过程需要遵循的协议,什么时候开始,什么时候结束。

解决①:一般我们就将*.hex文件使用JFlash-ARM打开再通过Jlink仿真器烧录到STM32芯片中,但是*.hex文件里边包含的数据不纯粹是代码数据还有一些别的东西,而*.bin文件数据就全部是代码数据。

在IAR软件环境中打开一个用户工程,先设置好中断向量表偏移和代码存放的地址空间后(前面已介绍过这两种方法)。设置工程如下图3-3所示,确认后重新编译工程,在工程的\Debug\Exe目录下会相应生成一个xxx.bin文件,这就是所需要的代码文件。

图3-3

②数据通过串口来传输文件常用的协议有XModem、YModem、ZModem这三种协议,在PC端使用这些协议传输文件只需要PC的超级终端或者终端工具SecureCRT即可,但是在STM32这边的编程会增加一些困难(因为要先去读懂、解析这些协议,在通过编程来实现)。也可选择自己定义一套简单的传输协议,但同样会有一些困难(因为要在PC端进行文件和串口编程)。总之不管通过什么办法都行,只要能将xxx.bin文件数据通过串口全部发送到STM32并且STM32能够全部接收到这些数据并写入Flash即可(我选择后者,自定义传输协议并用VC进行文件和串口编程)。

 

四、结束语

      总的来说STM32的IAP方案实现需要在进行用户程序之前加一段Bootloader程序,BootLoader程序的作用就是:

①什么都不做,直接跳转到用户程序。

②删除原有的用户程序,读取*.bin文件数据并将数据重新写入新的用户程序。

对于用户程序相比普通的编程只需要做三步改动即可

①改变中断向量表。

②改变代码存放的地址空间

③修改生成*.bin文件

  

   使用通过UART的IAP方案并不是很好的选择,这只是IAP方案的一个机制,因为能使用PC机通过串口升级程序,同样能通过Jlink烧写程序,并且自定义的串口通讯协议在没有校CRC校验的情况下不能及时发现数据传输过程发生的错误。这里推荐使用SD卡(或U盘)进行用户程序更新,将*.bin文件复制到SD卡(或U盘)中,STM32再通过读取SD卡(或U盘)的*.bin文件进行用户程序更新,这也避免了STM32与PC笨重的通讯,只需插一个SD卡(或U盘)更显得人性化一些,但需要去弄懂STM32如何与SD卡(或U盘)的通讯。

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

STM32+IAP方案的实现,IAP实现原理(详细解决说明)。 的相关文章

  • 《国富论》笔记——货币

    上一个读书笔记 我简单发散思维到了货币 从以物易物到以贝壳作为货币举了一段例子 国富论 第四章就马上讲到了货币 并且补充了我很多未分析到的地方 货币的起源 当以物易物的时候 也许是因为我不再需要你的物品了 所以不再需要和你交换 你的东西只有
  • 逻辑回归分类器

    版权归作者所有 任何形式转载请联系作者 作者 junior 来自豆瓣 来源 https www douban com note 573235939 Logistic的算法实现非常简单 但它背后的逻辑挺复杂的 前天学完很快又忘了 只记得算法怎
  • 《开拓者FPGA开发指南》读书笔记——Verilog HDL语法

    Verilog HDL语法 6 1 Verilog和C的区别 6 2 Verilog基础知识 6 2 1 Verilog的逻辑值 6 6 2 Verilog的标识符 6 2 Verilog概述 6 2 1 Verilog简介 6 2 2 V
  • 【读书笔记】《Web全栈工程师的自我修养》

    读书笔记 Web全栈工程师的自我修养 推荐书单 1 什么是全栈工程师 黑客与画家 专业主义 2 如何成为全栈工程师 重来 更为简单有效的商业思维 精益创业 3 从学生到工程师 编程之美 微软技术面试心得 4 野生程序员的故事 打造Faceb
  • 《结构化思维》读书笔记

    读书使人进步 每天进步一点点 本周小萌精心读的一本书是 结构化思维 主要是讲结构化思考 很棒的一本书 推荐读 麦肯锡金字塔原理 以及其他的麦肯锡结构化思考方法 第一章 初识思维 思维是我们解读事实的起点 是产生行为的源头 是决定结果的根本
  • Python深度学习-u4.1:分类和回归术语表

    分类和回归都包含很多专业术语 这些术语在机器学习领域都有确切的定义 本文对常见术语进行整理 样本 sample 或输入 input 进入模型的数据点 预测 prediction 或输出 output 从模型出来的结果 目标 target 真
  • NAT穿越原理——STUN

    STUN是RFC3489规定的一种NAT穿透方式 它采用辅助的方法探测NAT的IP和端口 毫无疑问的 它对穿越早期的NAT起了巨大的作用 并且还将继续在ANT穿透中占有一席之地 STUN的探测过程需要有一个公网IP的STUN server
  • 《大话数据结构》-程杰 读书笔记

    认为程序设计的实质是对确定的问题选择一种好的结构 加上设计一种好的算法 可见 数据结构在程序设计当中占据了重要的地位 程序设计 数据结构 算法 要你相信自己一定可以学得会 学得好 既然无数人已经掌握了 你凭什么不行 于每个链表来说 它所占用
  • 解决gcc编译链接含weak函数的库文件出现的一些BUG_2019/03/13

    项目介绍 本项目包含IAP程序与APP程序 APP程序有部分共用代码 包括main stm32标准库 RTOS BSP 都编译进库中 另外部分特殊代码由其它程序生成后 连接共用代码库生成目标bin文件 通过IAP下载至FLASH中 问题描述
  • STM32PWM控制智能风扇

    设计思路 这个是一个STM32通过定时器产生PWM波控制小风扇的设计 首先STM32驱动ds18b20温度传感器采集环境温度 然后通过按键设置温度的阈值 不同的温度范围定时器产生的PWM波不同 相应的小风扇的转速也会不一样 温度越高 小风扇
  • 《曾国藩家书》读书手记(修身篇一)

    曾国藩被章太炎评价为 誉之则圣相 谳之则元凶 为什么有这样的评价呢 我们可以看出曾国藩这个人褒贬不一 不过毛和蒋对于曾国藩都是推崇备至 毛说过 吾近于人 独服于曾国藩 看来曾国藩还是有可取之处的 尤其是他的家书 很多人评价甚高 一 修身篇
  • wireshark数据包分析实战 读书笔记

    由头 永久链接 之前读了很多书籍 但是现在回顾的时候 很多内容仅仅是熟悉 而不是真正掌握 所以尝试一种新的方式 将读书时觉得比较重要的 或者是自己还不理解的东西记录下来 达到这本书我已经不需要再去翻 只要看笔记即可的效果 第一章 数据包分析
  • 读《洞穴奇案》——从虐猫到禁食狗肉,自然法真的存在吗?

    这是读 洞穴奇案 的第四篇心得体会 本篇的题目一下子就包含了两个热点话题 高校学生虐猫案 和 立法禁止吃狗肉 这两个事件不得不说是争议不断的 从理性和感性的角度出发得出的结论不一而足 如果此人像探险者一样并没有邪恶的意图 而我们判他有罪 判
  • 突破人生的瓶颈(心灵之灯)

    人生 四度 平时除了看新闻外我很少看电视 但是那天除外 那天晚上写完稿子 随意打开了一个频道 是央视三套的艺术人生 为何庆魁加油 我不喜欢主持人以煽情的方式 不停发掘主人公内心伤痛泪水的惯用风格 本想换台 考虑到剧作家何庆魁今年来家庭遇到的
  • 《从Paxos到ZooKeeper》读书笔记之第一章(二)

    从Paxos到ZooKeeper 读书笔记之第一章 二 1 2从ACID到CAP BASE 这一节由三小节 从大家数值的数据库事务的四个特性 引出来分布式事务的概念 通过对ACID模型的讨论 提出如何构建一个兼顾可用性和一致性的分布式系统方
  • 《学会提问》-批判性思维

    这本书名为学会提问 但实际内容是讲解如何训练批判性思维能力 如何通过提问 来质疑别人的观点 选择正确的论证 来形成自己的理性决策 批判性思维的最终结果就是要求一个人虚怀若谷地接纳各种观点 理性评判这些观点 然后在理性判断的基础上决定采取哪些
  • 《疯狂Java讲义》读书笔记(一)

    面向对象具有三个基本特征 封装 Encapsulation 继承 Inheritance 和多态 Polymorphism 继承是面向对象实现软件复用的重要手段 当子类继承父类 子类作为一个特殊的父类 将获得父类所有的属性和方法 封装是指将
  • STM32 用cubemx移植IAP功能,实现串口升级

    感谢网上的大神 通过你们的文章我终于测试iap升级通过了 具体iap功能我白嫖一段 程序上电先进入 bootloader代码功能 后面通过bootloader跳转到用户的功能代码中 使用的开发板芯片 STM32F103VET6 串口1升级
  • MAX31865硬件和程序攻坚

    MAX31865硬件和程序攻坚 中文数据手册 STM32H库与工程文件创建 模块硬件部分 温度数据准确性 中文数据手册 MAX31865中文手册可以看这个博主挂上的文章 总结 STM32F103C8T6通过MAX31865读取PT100电阻
  • 【华为数据之道学习笔记】5-10标签设计

    标签是根据业务场景的需求 通过对目标对象 含静态 动态特 性 运用抽象 归纳 推理等算法得到的高度精练的特征标识 用于差异化管理与决策 标签由标签和标签值组成 打在目标对象上 标签由互联网领域逐步推广到其他领域 打标签的对象也由用 户 产品

随机推荐

  • JDK20又来了!你还在用JDK8么?

    文章目录 前言 JDK 20发布 JDK20下载 JDK 20新特性 矢量API 虚拟线程 第二次优化 结构化并发 Scoped values 作用域值 记录模式 第二次优化 外部函数和内存API switch语句和表达式的模式匹配 写在最
  • Linux命令+shell脚本大全:shell 的父子关系

    用于登录某个虚拟控制器终端或在GUI中运行终端仿真器时所启动的默认的交互shell 是一 个父shell 本书到目前为止都是父shell提供CLI提示符 然后等待命令输入 在CLI提示符后输入 bin bash 命令或其他等效的 bash
  • 网络编程(三次握手、四次挥手)

    一 Wireshark 窗口介绍 二 wireshark与对应的OSI七层模型 服务器和客户端的代码不能都运行在ubuntu 因为wireshark抓的是流经真实网卡的数据包 若将服务器客户端都运行在ubuntu 数据直接经过虚拟网卡通信
  • Spring cloud Gateway版本升级踩坑总结

    目录 背景 问题及方案 1 Kubernetes pom文件中的依赖包名称不同 2 项目引入 OpenFeign 或者 RestTemplate 启动假死 解决方案有以下三种 1 使用异步方法并且延迟注入 OpenFeignClient 推
  • 什么是机器学习分类算法?【K-近邻算法(KNN)、交叉验证、朴素贝叶斯算法、决策树、随机森林】

    Python微信订餐小程序课程视频 https edu csdn net course detail 36074 Python实战量化交易理财系统 https edu csdn net course detail 35475 1 K 近邻算
  • C++异常处理机制详解

    异常处理是一种允许两个独立开发的程序组件在程序执行期间遇到程序不正常的情况 异常exception 时相互通信的机制 本文总结了19个C 异常处理中的常见问题 基本涵盖了一般C 程序开发所需的关于异常处理部分的细节 1 throw可以抛出哪
  • 区块链概念、原理、特点

    01 区块链概念 区块链可以借由密码学 串接并保护内容的串联交易记录 又称区块 在区块链中 区块内容具有难以篡改的特性 每一个区块都包含了前一个区块的加密散列 相应时间戳记以及交易数据 通常用Hash树计算的散列值表示 用区块链串接的分布式
  • 【问答】区块链遇到Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is heWaiting for

    前言 在日常区块链或是正常的使用中 总是会遇到这个问题 Waiting for cache lock Could not get lock var lib dpkg lock frontend It is heWaiting for cac
  • 微服务化之无状态化与容器化(转载)

    一 为什么要做无状态化和容器化 很多应用拆分成微服务 是为了承载高并发 往往一个进程扛不住这么大的量 因而需要拆分成多组进程 每组进程承载特定的工作 根据并发的压力用多个副本公共承担流量 将一个进程变成多组进程 每组进程多个副本 需要程序的
  • ASP快速入门教程

    ASP快速入门教程 ASP快速入门教程能让你一个小时就学会ASP 如果想看懂更多的ASP代码 希望大家在网上找找ASP教程 相信看完后大家对ASP更有个感性的认识 请熟记下面的ASP语句是你快速入门的不二法则 lt 1 gt lt 2 gt
  • R语言学习:数据结构8-日期和时间

    日期和时间 date time 日期 Date 内部存储的是距离1970 01 01的天数 相关函数 date Sys Date weekdays months quarters 查看日期 date x lt date 查看当前系统日期和时
  • 数据清洗的步骤和注意事项:提高数据分析的准确性和可靠性

    作为一名数据分析师 我深知数据清洗是数据分析的重要一步 数据清洗的质量直接影响到数据分析的准确性和可靠性 在这篇文章中 我将分享一些数据清洗的步骤和注意事项 帮助你提高数据分析的准确性和可靠性 1 确定数据清洗的目标和指标 在开始数据清洗之
  • 腾讯云部署(gin框架+vue3.0)前后端分离项目

    腾讯云部署 gin框架 vue3 0 前后端分离项目 项目架构和部署工具 项目工具 部署工具 后端项目准备及部署 购买云端服务器 以下是腾讯云 阿里云请点击我 https blog csdn net it vegetable article
  • C++ · 求和篇

    C 求和法千万条 等差数列第一条 哈哈 跟大家开个玩笑 现在咱们步入正题 求和法之一 等差数列 没错 等差数列是最简便的解法 众所周知 等差数列求和公式为 首项 末项 项数 2 首项即是等差数列的起始数 末项是等差数列的结束项 好 问题来了
  • 实例化和具体化详解

    在解释具体化和实例化看的有点乱 分解出来备忘 在代码中包含函数模板本身并不会生成函数定义 它只是用于生成函数定义的方案 编译器使用模板为我写类型生成函数定义时 得到的是模板实例 如这个模板 template
  • keil5 编辑栏一直是灰色

    无语了 气炸了 愤怒啊 查了一下 有很多 arm 和 c51 并存 不管他了 之前装了用完51 又装了arm 现在反而什么都用不了 打开license 发现过期了 重新破解 即可 注意音乐 大半夜吓死人 你以为这样就可以了 你就太天真了 网
  • java:最差产品奖

    import java util Scanner 注意类名必须为 Main 不要有任何 package xxx 信息 public class Main public static void main String args Scanner
  • dll文件反编译源代码 C#反编译 dotpeek反编译dll文件后export

    目录 背景 下载安装dotpeek 导入dll文件 export导出文件 参考 背景 项目合作的时候 使用前人的或者其他部门dll文件直接在机台运行 会出现很多问题 逻辑 效率等等 此时我们可以选择对他们的代码进行反编译和重构 重新梳理逻辑
  • Windows C++运行命令编程

    Windows C 运行命令编程 一 命令处理方式 二 popen函数 三 重定向的子进程 四 参考链接 一 命令处理方式 Windows下编程经常需要使用批处理指令 bat或cmd 因此如何执行命令和获取返回数据是一个关键点 对于控制台程
  • STM32+IAP方案的实现,IAP实现原理(详细解决说明)。

    此文档内容摘自 http www 51hei com stm32 4315 html 可参考文档 https blog csdn net gin love article details 82015646 基于STM32F103ZET6的U