【STM32】IAP升级01 bootloader实现以及APP配置(主要)
APP程序以及中断向量表的偏移设置
前言
通过之前的了解 之前的了解,我们知道实现IAP升级需要两个条件:
1.APP程序必须在 IAP 程序之后的某个偏移量为 x 的地址开始;
2.APP程序的中断向量表相应的移动,移动的偏移量为 x;
1.APP 程序起始地址设置
默认条件下的起始地址
默认的条件下,图中 IROM1 的起始地址(Start)一般为 0x08000000,大小(Size)为 0x100000,即从 0x08000000 开始的 1024K 空间为我们的程序存储区。
设置APP起始地址
存储在flash上的APP起始地址设置方法
设置起始地址(Start)为 0x08010000,偏移量为 0x10000(64K 字节,即留给 BootLoader 的空间),因而,留给 APP 用的 FLASH 空间(Size)为 0x80000-0x10000=0x70000(448KB)。设置好 Start 和 Size,就完成 APP 程序的起始地址设置。IRAM 是内存的地址,APP 可以独占这些内存,我们不需要修改。
需要确保 APP 起始地址在 Bootloader 程序结束位置之后,并且偏移量为 0x200 的倍数即可
存储在SRAM上的APP起始地址设置方法
将 IROM1 的起始地址(Start)定义为:0x20001000,大小为 0x19000(100K 字节),即从地址 0x20000000 偏移0x1000 开始,存放 SRAM APP 代码。
STM32F407ZGT6 只有一个 128K(不算 CCM)的片内 SRAM,存放程序的位置与变量的加载位置不能重复,所以我们需要设置 IRAM1 中的地址(SRAM)的起始地址变为 0x2001A000,分配大小只有 0x6000(24K 字节)。整个 STM32F407ZGT6 的 SRAM(不含 CCM)分配情况为:最开始的 4K 给 Bootloader 程序使用,随后的 100K 存放 APP 程序,最后 24K,用作 APP 程序的内存。
2. 重新设置中断向量表的地址
SCB->VTOR寄存器存放的是中断向量表的起始地址。默认的情况它由 BOOT 的启动模式决定。重定向这个位置,这样就可以从 Flash 区域的任意位置启动代码。
就是你跳转到app程序后,你后续得跑app的中断向量表。要实现这个就必须在刚进入app的时候重定向中断向量表
/* 设置 NVIC 的向量表偏移寄存器,VTOR 低 9 位保留,即[8:0]保留 */SCB->VTOR = baseaddr | (offset & (uint32_t)0xFFFFFE00);
baseaddr 为基地址(即 APP 程序首地址)
,Offset 为偏移量
比如 FLASH APP 设置中断向量表偏移量为 0x10000
SCB->VTOR = FLASH_BASE | ( 0x10000 & (uint32_t)0xFFFFFE00);
SRAM APP 的情况可以参考正点原子探索者开发指南V1.1。
3.设置keil生成bin文件
MDK 默认生成的文件是.hex 文件,并不方便用作 IAP更新,我们希望生成的文件是.bin 文件.
hex和bin文件的区别
简单来说:HEX文档是ascii码的文档。 是不能直接烧到单片机中的。 中间要有转换程序。 但是现在很多编程器都设计成直接可以导入hex文件烧录的,其实这是做了设计的。 bin文件是二进制文件,是可以直接烧到芯片中,中间不用转换的。
设置keil生成bin文件
在 MDK 点击 Options for Target→User 选项卡,在 After Build/Rebuild一栏中,勾选 Run #1,我们推荐使用相对地址,在勾选的同一行后的输入框并写入命令行:fromelf --bin -o …\Output@L.bin …\Output%L
D:\Keil_v5\ARM\ARMCC\bin\fromelf.exe是MDK 自带的格式转换工具 fromelf.exe的路径。
通过这一步设置,我们就可以在 MDK 编译成功之后,调用 fromelf.exe,
..\..\Output\%L
表示当前编译的链接文件(…\是相对路径,表示上级目录,编译器默认从工程文件*.uvprojx 开始查找,根据我的工程文件 Output 的位置就能明白路径的含义)
指令–bin –o …\Output@L.bin表示在 Output 目录下生成一个.bin 文件,
@L
在 Keil 的下表示 Output 选项卡下的 Name of Executable 后面的字符串,即在 Output 文件夹下生成一个 atk_f407.bin 文件。
在得到.bin 文件之后,我们只需要将这个 bin 文件传送给单片机,即可执行 IAP 升级。
Bootloader程序的实现
1、APP文件的编写与通常编写一致,只需要设定好偏移地址
2、新的中断向量表的偏移设置好
这两点在前文已经写过,接下来就是bootloader的实现了。
Bootloader 和 app 属于两个独立的工程,不是一个工程!!!
相关资料:
1.写 STM32 内部 Flash 的功能用到 STM32 的 Flash操作。STM32片上Flash操作
2.设置bootloader的起始地址为复位之后第一个启动的工程。
这个例子中,bootloader从0x800 0000开始,APP从0x800 8000开始,执行完bootloader之后再执行APP。
BootLoader 的编译器设置
App 的编译器设置
1.bootloader程序也是一个app程序
是我们专门用来搬运APP程序的工具,所以也和是和普通程序一样的执行流程。
IAP升级程序(bootloader)启动流程
简单来说
初始化好时钟,GPIO,外设(依照升级方法来确定初始化对应的外设),那么这块MCU就有了可以和外部通信的能力。
例如,使用串口升级,那么步骤就是
bootloader的main之前
1.单片机复位,从0x800 0000开始执行。
2.执行0x0800 0004处的Rest_Handler复位中断向量函数
3. 复位中断向量函数执行
调用SystemInit函数。这个函数里面开启了外部晶振,设置了PLL,除能了所有中断,设置了时钟
_main 标号表示 C/C++标准实时库函数里的一个初始化子程序 _main的入口地址。该程序的一个主要作用是初始化堆栈(跳转_user_initial_stackheap标号进行初始化堆栈),并初始化映像文件,最后跳转到C程序中的main函数。这也正解释了为什么所有的C程序必须有一个main函数作为程序的起点,因为这是由C/C++标准实时库所规定的。
4.跳转到IAP升级程序(bootloader)的main函数。
bootloader的main之后
1.初始化
初始化和正常没有bootloader 的程序一下,该咋样就咋样,为了避免无效功耗损失,一般是需要什么就初始化什么。时钟初始化,串口初始化,定时器初始化等(如果有用到定时轮询或者定时器延时等可以初始化)
2.检查APP 程序是否完整
若出现某些情况导致APP程序不全,有可能导致程序跑飞,进入硬件错误。
初始化完成后,首先检测 APP 分区中最后地址的标志位是否符合(如是否等于0x5a5a,一般APP程序的末尾加入特殊字符,以检测完整性),如果符合,启动倒计时(时间大约几百毫秒就行,根据实际情况决定),等待进入 APP 程序,在此期间,也会等待接收升级的指令;否则,则一直等待接收升级的指令。
check收到的估计bin的最后四个字节是否为0x5A5A
int CheckIfAPPCanJump(void)
{uint32_t *pFlag = (uint32_t *)(APP_FLASH_CODE_BASE + APP_FLASH_CODE_SIZE - 4);if (*pFlag == 0x5A5A){ return 1; }return 0;
}
3.升级
接收到升级指令后,则启动升级流程,升级期间不允许进入 APP 程序。
4.跳转APP程序(IAP 如何实现跳转到用户程序)
升级完成后,需要跳转到 APP 程序(可以自动跳转,也可以增加跳转指令手动跳转),跳转前的准备:
1.检测 APP 程序是否存在,若存在,则继续往下执行APP升级
2.关闭全局中断(可选,放置升级中被打断)
3.清除所有中断标志位(可选,放置升级中被打断)
void Disable_irq(void)
{uint8_t i;__disable_irq(); // 关闭总中断//__enable_irq();/* 清除所有中断标志 */for(i= 0; i < CRS_IRQn; i++){NVIC_ClearPendingIRQ((IRQn_Type)i);}
}
4.跳转 APP 启动程序地址(当然,也能直接跳转到 APP 程序的 main 函数,但在跳转前需要重新初始化堆栈等内容,所以最好还是交给启动文件处理,跳转到resethandle)
4.1 设定跳转地址
typedef void (*pFunction)(void); //定义一个pFunction类型 这是个函数指针
pFunction Jump_To_Application; //Jump_To_Application设置为pFunction类型/*设定跳转地址,FLASH_USER_START_ADDR是APP程序的起始地址*/
JumpAddress = *(__IO uint32_t*) (FLASH_USER_START_ADDR + 4);
Jump_To_Application = (pFunction) JumpAddress;//将APP程序的中断向量表的Rest_Handler地址赋值给Jump_To_Application
__set_MSP(*(__IO uint32_t*) FLASH_USER_START_ADDR); //这里是将把应用程序起始地址设为栈顶指针
Jump_To_Application(); //设置PC指针为复位地址,你可以理解为跳转到应用程序的函数
设定跳转地址,FLASH_USER_START_ADDR是APP程序的起始地址,+4是因为中断向量表每四个字节代表一个中断函数的地址。所以JumpAddress指向APP中断向量表的Rest_Handler
.
将跳转地址JumpAddress强制转换pFunction类型,可以理解为编译器将其编译成一个函数
。
2.官方的demo,以stm32f10x为例
IAP/src/main.c int main(void)
{/* Flash unlock *//*flash解锁,因为需要操作flash*/FLASH_Unlock();/* Initialize Key Button mounted on STM3210X-EVAL board *//*初始化按键,demo中的升级触发条件为按键按下*/ STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO); /* Test if Key push-button on STM3210X-EVAL Board is pressed */if (STM_EVAL_PBGetState(BUTTON_KEY) == 0x00){ /* If Key is pressed *//*如果按键按下,即触发升级,进行升级*//* Execute the IAP driver in order to re-program the Flash *//*初始化串口,demo里面使用的是usart1 + Y-MODe协议*/IAP_Init();SerialPutString("\r\n================================================================");SerialPutString("\r\n= (C) COPYRIGHT 2010 STMicroelectronics =");SerialPutString("\r\n= =");SerialPutString("\r\n= In-Application Programming Application (Version 3.3.0) =");SerialPutString("\r\n= =");SerialPutString("\r\n= By MCD Application Team =");SerialPutString("\r\n============================================================");SerialPutString("\r\n\r\n");/*升级菜单,用户自己实现*//*升级中可选关闭所有中断,防止升级被打断,但是在跳转到APP程序后要第一时间打开总中断*/Main_Menu ();}/* Keep the user application running */else//不升级 进入APP{/* Test if user code is programmed starting from address "ApplicationAddress" *//*升级条件不满足,跳转到用户程序处执行用户程序*/if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)//检测栈顶指针{ /* Jump to user application *//*ApplicationAddress为用户程序的栈地址,+4便为用户程序的复位中断向量地址*/ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) ApplicationAddress);/*执行用户空间的复位中断向量函数,里面主要是进行系统时钟配置,执行用户空间的main函数数*/ Jump_To_Application();}}while (1){}
}
检测栈顶指针
升级菜单demo,更具需求裁剪
void Main_Menu(void)
{uint8_t key = 0;/* Get the number of block (4 or 2 pages) from where the user program will be loaded *//*计算IAP占用的flash页数*/ BlockNbr = (FlashDestination - 0x08000000) >> 12;/* Compute the mask to test if the Flash memory, where the user program will beloaded, is write protected */
#if defined (STM32F10X_MD) || defined (STM32F10X_MD_VL)UserMemoryMask = ((uint32_t)~((1 << BlockNbr) - 1));
#else /* USE_STM3210E_EVAL */if (BlockNbr < 62){UserMemoryMask = ((uint32_t)~((1 << BlockNbr) - 1));}else{UserMemoryMask = ((uint32_t)0x80000000);}
#endif /* (STM32F10X_MD) || (STM32F10X_MD_VL) *//* Test if any page of Flash memory where program user will be loaded is write protected *//*检测flash中用户空间的写保护锁是否开启*/ if ((FLASH_GetWriteProtectionOptionByte() & UserMemoryMask) != UserMemoryMask){FlashProtection = 1;}else{FlashProtection = 0;}while (1){SerialPutString("\r\n================== Main Menu ============================\r\n\n");SerialPutString(" Download Image To the STM32F10x Internal Flash ------- 1\r\n\n");SerialPutString(" Upload Image From the STM32F10x Internal Flash ------- 2\r\n\n");SerialPutString(" Execute The New Program ------------------------------ 3\r\n\n");if(FlashProtection != 0){SerialPutString(" Disable the write protection ------------------------- 4\r\n\n");}SerialPutString("==========================================================\r\n\n");key = GetKey();if (key == 0x31){/* Download user application in the Flash *//*下载程序*/ SerialDownload();}else if (key == 0x32){/* Upload user application from the Flash */SerialUpload();}else if (key == 0x33){JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);/* Jump to user application */Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) ApplicationAddress);Jump_To_Application();}else if ((key == 0x34) && (FlashProtection == 1)){/* Disable the write protection of desired pages */FLASH_DisableWriteProtectionPages();}else{if (FlashProtection == 0){SerialPutString("Invalid Number ! ==> The number should be either 1, 2 or 3\r");}else{SerialPutString("Invalid Number ! ==> The number should be either 1, 2, 3 or 4\r");} }}
}
进入APP
APP 代码起始设置见前文
APP中断向量表需要偏移就是你跳转到app程序后,你后续得跑app的中断向量表。要实现这个就必须在刚进入app的时候重定向中断向量表
注意在 mian 函数起始处重新设置中断向量表(寄存器 SCB->VTOR)的偏移量,否则 APP 无法正常运行
void SetVectorTable(void)
{uint8_t i;SCB->VTOR = APP_FLASH_CODE_BASE;/* 清除所有中断标志 */for(i= 0; i < CRS_IRQn; i++){NVIC_ClearPendingIRQ((IRQn_Type)i);}/* 在BOOT中跳转之前若关闭了全局中断, 此需要重新打开 */__enable_irq();
}
相关文章:
【STM32】IAP升级01 bootloader实现以及APP配置(主要)
APP程序以及中断向量表的偏移设置 前言 通过之前的了解 之前的了解,我们知道实现IAP升级需要两个条件: 1.APP程序必须在 IAP 程序之后的某个偏移量为 x 的地址开始; 2.APP程序的中断向量表相应的移动,移动的偏移量为 xÿ…...
ruoyi(若依)接口拦截路径配置,接口访问要授权,放开授权直接访问
1.找到文件SecurityConfig.java文件,里面配置相应的放行路径...
Ctfshow web入门 XSS篇 web316-web333 详细题解 全
CTFshow XSS web316 是反射型 XSS 法一: 利用现成平台 法二: 自己搭服务器 先在服务器上面放一个接受Cookie的文件。 文件内容: <?php$cookie $_GET[cookie];$time date(Y-m-d h:i:s, time());$log fopen("cookie.txt"…...
watch()监听vue2项目角色权限变化更新挂载
<template><div><el-form:model"updateRole"ref"roleForm"label-width"100px"label-position"right"style"width: 400px":rules"roleRules"><el-form-item label"角色名称" prop&…...
轻量化设计、佩戴更舒适——轻律 Umelody U1头戴式蓝牙耳机
头戴式耳机不像以前那么笨重,身边很多人都在用,而且拍照还巨出片,拍照累了还能听歌放松,何乐而不为,国庆节即将来临,秋冬季节也就快要到了,棕色在合适不过了,最近有一款高颜值的复古…...
嵌入式Linux应用开发-基础知识-第三章 LED原理图-GPIO及操作
嵌入式Linux应用开发-基础知识-第三章 LED原理图-GPIO及操作 第三章 硬件知识_LED 原理图3.1 先来讲讲怎么看原理图 第四章 普适的 GPIO 引脚操作方法4.1 GPIO 模块一般结构4.2 GPIO 寄存器操作4.3 GPIO 的其他功能:防抖动、中断、唤醒 第五章 具体单板的 GPIO 操作…...
外贸人员如何选择适合的邮箱服务
随着互联网和数字技术的快速发展,电子邮件已经成为商务沟通的主要方式之一。对于外贸人员来说,选择一个合适且高效的邮箱服务至关重要。本文将探讨外贸人员在选择外贸邮箱时应考虑的因素,以便找到最适合自己的解决方案。 “外贸人员如何选择合…...
pt29django教程
文件上传 文件上传必须为POST提交方式, 表单<form>中文件上传时必须有带有enctype"multipart/form-data" 时才会包含文件内容数据。 表单中用<input type"file" name"xxx">标签上传文件 名字xxx对应request.FILES[xx…...
【操作系统笔记七】进程和线程
进程的组成 进程要读取 ELF 文件,那么: ① 要知道文件系统的信息,fs_struct② 要知道打开的文件的信息,files_struct 一个进程除了需要读取 ELF 文件外,还可以读取其他的文件中的数据。 进程中肯定有一个 mm_struct…...
Kakfa高效读写数据
1.概述 无论 kafka 作为 MQ 也好,作为存储层也罢,无非就是两个功能:一是 Producer 生产的数据存到 broker,二是 Consumer 从 broker 读取数据。那 Kafka 的快也就体现在读写两个方面了,本文也是从这两个方面去剖析Kafk…...
C++ 类和对象(4)构造函数
C的目标之一是让使用类对象就像使用标准类型一样,但是常规的初始化语法不适用于类似类型Stock: int year 2001; struct thing {char * pn;int m; }; thing amabob {"wodget",-23}; //有效初始化 Stock hot {"Sukies Autos…...
数据结构————广度寻路算法 Breadth First Search(广度优先算法)
(一)基础补充 二叉树的基本定义 1)二叉树就是度不超过2的树,其每个结点最多有两个子结点 2)二叉树的结点分为左结点和右结点 代码实现二叉树 #include <stdio.h> #include <stdlib.h> struct Node {int data;struct Node* pLeft;struct Node* pRight; }…...
安卓桌面记事本便签软件哪个好用?
日常生活及工作中,很多人常常会遇到一些一闪而现的灵感,这时候拿出手机想要记录时,却找不到记录的软件。在这个快节奏的时代,安卓手机是我们日常生活不可或缺的伙伴。然而,正因为我们的生活如此忙碌,记事变…...
河北吉力宝以步力宝健康鞋引发的全新生活生态商
在当今瞬息万变的商业世界中,成功企业通常都是那些不拘泥于传统、勇于创新的先锋之选。河北吉力宝正是这样一家企业,通过打造一双步力宝健康鞋,他们以功能性智能科技穿戴品为核心,成功创造了一种结合智能康养与时尚潮流的独特产品…...
反射获取Constructor、Field、Method对象
1、获取构造器 Constructor [ ] getConstructor s ( ) 获取全部的构造器:只能获取 public 修饰的构造器 package com.csdn.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.junit.Test; import jav…...
【Netty】 ByteBuf的常用API总结
目录 一、ByteBuf介绍 二、ByteBuf创建 1.池化创建 ByteBufAllocator 2.Unpooled (非池化)创建ByteBuf 3.ByteBufUtil 操作ByteBuf 三、读取ByteBuf数据 1.get方法 2.read方法 3.set方法 4.write方法 5.索引管理 6.索引查找 7.索引查找 8.其…...
热门敏捷开发管理工具
敏捷管理研发工具可以协助团队更好地进行敏捷开发和管理。以下是几种流行的敏捷管理研发工具: Leangoo:Leangoo领歌一款永久免费的专业敏捷研发管理工具,它覆盖了敏捷项目研发全流程,包括小型团队敏捷开发,规模化敏捷…...
Java分支结构:一次不经意的选择,改变了我的一生。
👑专栏内容:Java⛪个人主页:子夜的星的主页💕座右铭:前路未远,步履不停 目录 一、顺序结构二、分支结构1、if语句2、switch语句 好久不见!命运之轮常常在不经意间转动,有时一个看似微…...
Unity中Shader需要了解的点与向量
文章目录 前言一、点和向量的区别二、向量加法减法1、向量加法2、向量减法(可以把向量减法转化为向量加法) 三、向量的模四、标量![在这里插入图片描述](https://img-blog.csdnimg.cn/03df81df3cdf47989a11605d5f5e7da5.png)1、向量与标量的乘法 前言 Unity中Shader了解使用的…...
Java初始化大量数据到Neo4j中(一)
背景:我们项目第一次部署图数据库,要求我们把现有的业务数据以及关系上线第一时间初始化到Neo4j中。开发环境数据量已经百万级别。生成环境数据量更多。 我刚开始开发的时候,由于对Neo4j的了解并没有很多,第一想到的是用代码通用组…...
Excel·VBA日期时间转换提取正则表达式函数
标准日期转换 Function 标准日期(ByVal str$) As DateDim pat$, result$arr Array("(\d{4}).*?(\d{1,2}).*?(\d{1,2})", "(\d{4}).*?(\d{1}).*?(\d{1,2})")If Len(str) < 8 Then pat arr(1) Else pat arr(0)With CreateObject("vbscript.r…...
Django中的缓存
Django中的缓存 缓存的定义 定义: 缓存是-类可以更快的读取数据的介质统称,也指其它可以加快数据读取的存储方式。一般用来存储临时数据,常用介质的是读取速度很快的内存 意义:视图渲染有一定成本,数据库的频繁查询过高;所以对于低频变动的页…...
Python 编程基础 | 第二章-基础语法 | 2.4、while 语句
一、while 语句 1、循环语句 Python 编程中 while 语句用于循环执行程序,其基本形式为: while 判断条件(condition):执行语句(statements)……例如: count 0 while (count < 9):print(count)count 1while 语句时还有另外两个…...
Qt Charts简介
文章目录 一.图标类型Charts分类1.折线图和样条曲线图2.面积图和散点图3.条形图4.饼图5.误差棒图6.烛台图7.极坐标图 二.坐标轴Axes类型分类三.图例四.图表的互动五.图表样式主题 一.图标类型Charts分类 图表是通过使用系列类的实例并将其添加到QChart或ChartView实例来创建的…...
MinGW、GCC、GNU和MSVC是什么?有什么区别?
在C和C开发中,常常会遇到MinGW、GCC、GNU和MSVC这些术语。本教程将向您解释它们的含义以及它们之间的区别,帮助您更好地理解这些常见的编译工具和开发环境。 MinGW(Minimalist GNU for Windows): MinGW是一个开源的软件…...
引入easyExcel后,导致springboot项目无法开启tomcat
报错信息: Caused by: java.lang.annotation.IncompleteAnnotationException: org.terracotta.statistics.Statistic missing element type at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:81) at com.sun.proxy…...
Doris数据库FE——启动流程源码详细解析
Doris中FE主要负责接收和返回客户端请求、元数据以及集群管理、查询计划生成等工作。代码路径:doris/fe/fe-core/src/main/java/org/apache/doris/DorisFE.java 环境检查 在启动FE的时候,主要做环境检查。检查一些启动时必要的环境变量以及初始化配置…...
服务断路器_Resilience4j线程池隔离实现
线程池隔离配置修改YML文件 resilience4j:thread-pool-bulkhead: instances:backendA:# 最大线程池大小maxThreadPoolSize: 4# 核心线程池大小coreThreadPoolSize: 2# 队列容量queueCapacity: 2编写controller /*** 测试线程池服务隔离* return*/Bulkhead(name "backe…...
原神启动原神启动原神启动原神启动
测试游戏抽卡场景是确保玩家可以正常抽取虚拟物品或角色的重要部分。以下是一些可能的游戏抽卡场景的测试用例示例: 1.正常抽卡流程: 2.测试用户是否能够成功进行一次或多次抽卡操作。 3.确保每次抽卡后,用户收到相应的物品或角色。 4.抽卡…...
Glide - Android的图像加载和缓存库,专注于平滑滚动
官网 GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling 项目介绍 An image loading and caching library for Android focused on smooth scrolling Glide is a fast and efficient open source media management a…...
无锡网站建设专家/网络营销课程总结
1. 淘宝商品信息定向爬虫 链接: https://www.taobao.com/ 2. 实例编写 2.1 整体框架 # -*- coding: utf-8 -*-import requests import redef getHTMLText(url):print("")# 对获得的每个页面进行解析 def parsePage(ilt, html):print("")#将商品…...
怎样给公司申请一个网站/最近的新闻摘抄
Transformer是一种基于注意力机制的神经网络模型,由谷歌公司提出,其最初目的是用于自然语言处理任务,如机器翻译、文本摘要、语音识别等。相比于传统的循环神经网络模型,如LSTM和GRU,Transformer模型具有更好的并行化能…...
湖南英文网站建设/seo推广排名重要吗
undefined:声明了变量,但是没有赋值undeclared:没有声明变量就直接使用 如上图,num 就是undefined,arr 则是 undeclared。...
做试客需要去哪些网站/深圳高端网站建设公司
1 文件管理 # ls ls -a 列出当前目录下的所有文件,包括以.头的隐含文件 文件管理 # ls ls-l或ll 列出当前目录下文件的详细信息 文件管理 # pwd pwd 查看当前所在目录的绝对路经 文件管理 # cd cd.. 回当前目录的上一级目录 文件管理 # cd cd - 回上一次所在的目…...
做网站到八方资源网怎么样/阳江网站建设
示例Demo的基本功能 首先读取待跟踪图片集文件目录中第一张(第一帧),用鼠标选定一个待跟踪的矩形区域,然后按空格键继续处理后面的图片。 实验环境:vs2010 opencv2.4.2 代码示例 #include <opencv2/core/core.…...
门网站源码/软文推广公司有哪些
下载服务器时常被人盗链,时间久了导致服务器大量资源浪费,由于服务器使用nginx做为web服务器。nginx的防盗链方法有很多,可以使用现成的防盗链模块nginx-accesskey-2.0.3,编译ningx时添加此模块即可。由于服务其他业务需要&#x…...