STM32读写内部Flash
参考:https://blog.csdn.net/Caramel_biscuit/article/details/131925715
参考:https://blog.csdn.net/qq_36075612/article/details/124087574?spm=1001.2014.3001.5502
目录
- 内存映射
- 内部Flash的构成
- 对内部Flash的写入过程
- 查看工程内存的分布
- ROM加载空间
- STM32读写内部Flash代码
- 读/写入数据流程
- Flash 解锁
- 擦除扇区
- 写数据操作
- 读数据操作
- 再次上锁
- 简单的小例程代码实现
内存映射
stm32的flash起始地址为0x0800 0000,结束地址为0x0800 0000加上芯片实际的Flash大小,不同芯片Flash大小不同,RAM同理。
对于STM32F103RCT6,Flash256KB,所以结束地址为 0x0803 ffff。
Flash中的内容一般用来存储代码和一些定义为const的数据,断电不丢失。
RAM可以理解为内存,用来存储代码运行时的数据,变量等等,掉电数据丢失。
STM32将外设等映射为地址的形式,对地址的操作就是对外设的操作。
stm32的外设地址从0x4000 0000开始,可以看到在库文件中,是通过基于0x4000 0000地址的偏移量来操作寄存器以及外设的。
一般情况下,程序文件是从0x0800 0000地址写入,这个是STM32开始执行的地方,0x0800 0004是STM32的中断向量表的起始地址。
在使用keil进行编写程序时,其编程地址的设置一般是:
程序的写入地址从0x0800 0000开始的,其大小为0x40000也就是256K的空间,换句话说就是告诉编译器Flash的空间是从0x0800 0000~0x0804 0000,RAM的地址从0x2000 0000开始,大小为48KB。
M3复位后,从0x0800 0004取出复位中断的地址,并且跳转到复位中断程序,中断执行完之后会跳到main函数,main函数里面一般是一个死循环,进去后就不会再退出,当有中断发生的时候,M3将PC指针强制跳转回中断向量表,然后根据中断源进入对应的中断函数,执行完中断函数之后,再次返回main函数。
内部Flash的构成
STM32F429 的内部 FLASH 包含主存储器、系统存储器、 OTP 区域以及选项字节区域,它们的地址分布及大小如下:
- 主存储器:一般说STM32内部FLASH的时候,都是指这个主存储器区域存储用户应用程序的空间,芯片型号说明中的 1M FLASH、 2M FLASH 都是指这个区域的大小。与其它 FLASH 一样,在写入数据前,要先按扇区擦除。
- 系统存储区:系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,负责实现串口、USB以及CAN等ISP烧录功能。
- OTP区域:One Time Program,只能写入一次的存储区域,容量为512字节,写入后数据就无法再更改,OTP常用于存储应用程序的加密秘钥。
- 选项字节:选项字节用于配置 FLASH 的读写保护、电源管理中的 BOR 级别、软件/硬件看门狗等功能,这部分共 32 字节。可以通过修改 FLASH 的选项控制寄存器修改。
STM32F103的中容量内部 FLASH 包含主存储器、系统存储器、 OTP 区域以及选项字节区域,它们的地址分布及大小如下:
对内部Flash的写入过程
1.解锁(固定的KEY值)
往FLASH秘钥寄存器FLASH_KEYR中写入KEY1=0x45670123
再往FLASH密钥寄存器FLASH_KEYR中写入KEY2=0xCDEF89AB
2.数据操作位数
最大操作位数会影响擦除和写入的速度,其中 64 位宽度的操作除了配置寄存器位外,还需要在 Vpp 引脚外加一个 8-9V 的电压源,且其供电间不得超过一小时,否则 FLASH可能损坏,所以 64 位宽度的操作一般是在量产时对 FLASH 写入应用程序时才使用,大部分应用场合都是用 32 位的宽度。
3.擦除扇区
在写入新的数据前,需要先擦除存储区域, STM32 提供了扇区擦除指令和整个FLASH 擦除(批量擦除)的指令,批量擦除指令仅针对主存储区。
扇区擦除的过程如下:
(1) 检查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以确认当前未执行任何Flash 操作;
(2) 在 FLASH_CR 寄存器中,将“激活扇区擦除寄存器位 SER ”置 1,并设置“扇区编号寄存器位 SNB”,选择要擦除的扇区;
(3) 将 FLASH_CR 寄存器中的“开始擦除寄存器位 STRT ”置 1,开始擦除;
(4) 等待 BSY 位被清零时,表示擦除完成。
4.写入数据
擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还还需要配置一系列的寄存器,步骤如下:
(1) 检查 FLASH_SR 中的 BSY 位,以确认当前未执行任何其它的内部 Flash 操作;
(2) 将 FLASH_CR 寄存器中的 “激活编程寄存器位 PG” 置 1;
(3) 针对所需存储器地址(主存储器块或 OTP 区域内)执行数据写入操作;
(4) 等待 BSY 位被清零时,表示写入完成。
查看工程内存的分布
由于内部 FLASH 本身存储有程序数据,若不是有意删除某段程序代码,一般不应修改程序空间的内容,所以在使用内部 FLASH 存储其它数据前需要了解哪一些空间已经写入了程序代码。
通过查询应用程序编译时产生的“*.map”后缀文件,打开map文件后,查看文件最后部分的区域,Memory Map of the image
这段代码提供了一张镜像的内存映射(Memory Map),其中包含了入口点地址以及主要的加载和执行区域信息。
镜像的入口点(Image Entry point)地址是0x08000131。
加载区域(Load Region) LR_IROM1(基地址:0x08000000,大小:0x00001cec,最大大小:0x00040000)用于存放程序代码和只读数据。它是一个绝对地址的加载区域。
执行区域(Execution Region) ER_IROM1(基地址:0x08000000,大小:0x00001cd0,最大大小:0x00040000)用于存放实际执行的代码。它也是一个绝对地址的执行区域。
这个内存映射中的加载和执行区域都是基于基地址0x0800 0000,并且大小相等。意味着整个镜像都被加载到该地址范围,并且执行也发生在相同的地址范围内。
ROM加载空间
这一段是某工程的 ROM 存储器分布映像,在 STM32 芯片中, ROM 区域的内容就是指存储到内部 FLASH 的代码。
在上面 map 文件的描述中,我们了解到加载空间和执行空间的基地址(Base)都是0x08000000,它正好是 STM32 内部 FLASH 的首地址,即 STM32 的程序存储空间就直接是执行空间;它们的大小(Size)分别为 0x00000b50 及 0x00000b3c,执行空间的 ROM 比较小的原因就是因为部分 RW-data 类型的变量被拷贝到 RAM 空间了;它们的最大空间(Max)均为 0x00100000,即 1M 字节,它指的是内部 FLASH 的最大空间。
计算程序占用的空间时,需要使用加载区域的大小进行计算,本例子中应用程序使用
的内部 FLASH 是从 0x08000000 至(0x08000000+0x00000b50)地址的空间区域,看上面图正好是 STM32F429 的内部 FLASH扇区0的一部分 。
所以从扇区 1(地址 0x08004000)后的存储空间都可以作其它用途,使用这些存储空间时不会篡改应用程序空间的数据。
具体可参考原子的例程:实验四十一:FLASH 模拟 EEPROM 实验
STM32读写内部Flash代码
以STM32F105系列为例:
读/写入数据流程
Flash 解锁
直接调用#include "stm32f10x_flash.h"中的void FLASH_Unlock(void)函数,这个函数是官方提供的,其内部代码如下:
/*** @brief Unlocks the FLASH Program Erase Controller.* @note This function can be used for all STM32F10x devices.* - For STM32F10X_XL devices this function unlocks Bank1 and Bank2.* - For all other devices it unlocks Bank1 and it is equivalent* to FLASH_UnlockBank1 function..* @param None* @retval None*/
void FLASH_Unlock(void)
{/* Authorize the FPEC of Bank1 Access */FLASH->KEYR = FLASH_KEY1;FLASH->KEYR = FLASH_KEY2;#ifdef STM32F10X_XL/* Authorize the FPEC of Bank2 Access */FLASH->KEYR2 = FLASH_KEY1;FLASH->KEYR2 = FLASH_KEY2;
#endif /* STM32F10X_XL */
}
擦除扇区
也是直接调用固件库官方的函数FLASH_Status FLASH_ErasePage(uint32_t Page_Address),这个官方函数代码也贴出来看看,代码如下:
/*** @brief Erases a specified FLASH page.* @note This function can be used for all STM32F10x devices.* @param Page_Address: The page address to be erased.* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.*/
FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
{FLASH_Status status = FLASH_COMPLETE;/* Check the parameters */assert_param(IS_FLASH_ADDRESS(Page_Address));#ifdef STM32F10X_XLif(Page_Address < FLASH_BANK1_END_ADDRESS){/* Wait for last operation to be completed */status = FLASH_WaitForLastBank1Operation(EraseTimeout);if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to erase the page */FLASH->CR|= CR_PER_Set;FLASH->AR = Page_Address;FLASH->CR|= CR_STRT_Set;/* Wait for last operation to be completed */status = FLASH_WaitForLastBank1Operation(EraseTimeout);/* Disable the PER Bit */FLASH->CR &= CR_PER_Reset;}}else{/* Wait for last operation to be completed */status = FLASH_WaitForLastBank2Operation(EraseTimeout);if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to erase the page */FLASH->CR2|= CR_PER_Set;FLASH->AR2 = Page_Address;FLASH->CR2|= CR_STRT_Set;/* Wait for last operation to be completed */status = FLASH_WaitForLastBank2Operation(EraseTimeout);/* Disable the PER Bit */FLASH->CR2 &= CR_PER_Reset;}}
#else/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(EraseTimeout);if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to erase the page */FLASH->CR|= CR_PER_Set;FLASH->AR = Page_Address;FLASH->CR|= CR_STRT_Set;/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(EraseTimeout);/* Disable the PER Bit */FLASH->CR &= CR_PER_Reset;}
#endif /* STM32F10X_XL *//* Return the Erase Status */return status;
}
注意这个擦除扇区函数是你提供一个STM32f105系列扇区的开始地址即可,擦除是按照页擦除(每页2KB=1024Byte)或者整个擦除(见STM32参考手册的第二章2.3.3嵌入式闪存部分介绍)
比如我们要擦除互联网型的127页,我们只需要FLASH_ErasePage(0x0803f800);执行后,第127页的0x0803f800-0x0803FFFF数据都将被擦除。
当然官方提供的也不知一个擦除函数,而是三个,具体如下,对于32位系统:一个是字节=4byte=32bite;一个是半字=2byte=16bite;一个是字节=1byte=8bite;进行擦除。
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);FLASH_Status FLASH_EraseAllPages(void);FLASH_Status FLASH_EraseOptionBytes(void);
接下来是写/读数据函数,该函数也是官方给出的,我们只需要用就好了。但要注意,这个是个半字的写操作,威少是uint16_t 的数据算半字呢,因为单片机是32的,对于32位单片机系统来说,一个字是4个字节的,8位的比如51单片机系统一个字就是2位的,64位单片机系统一个字就是8个字节,脱离单片机系统说字是多少个字节是没意义的。所以这里写入/读出半字也就是一次写入2个字节,写完/读出一次地址会加2。
写数据操作
/*** @brief Programs a half word at a specified address.* @note This function can be used for all STM32F10x devices.* @param Address: specifies the address to be programmed.* @param Data: specifies the data to be programmed.* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.*/
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{FLASH_Status status = FLASH_COMPLETE;/* Check the parameters */assert_param(IS_FLASH_ADDRESS(Address));#ifdef STM32F10X_XL/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(ProgramTimeout);if(Address < FLASH_BANK1_END_ADDRESS){if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new data */FLASH->CR |= CR_PG_Set;*(__IO uint16_t*)Address = Data;/* Wait for last operation to be completed */status = FLASH_WaitForLastBank1Operation(ProgramTimeout);/* Disable the PG Bit */FLASH->CR &= CR_PG_Reset;}}else{if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new data */FLASH->CR2 |= CR_PG_Set;*(__IO uint16_t*)Address = Data;/* Wait for last operation to be completed */status = FLASH_WaitForLastBank2Operation(ProgramTimeout);/* Disable the PG Bit */FLASH->CR2 &= CR_PG_Reset;}}
#else/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(ProgramTimeout);if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new data */FLASH->CR |= CR_PG_Set;*(__IO uint16_t*)Address = Data;/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(ProgramTimeout);/* Disable the PG Bit */FLASH->CR &= CR_PG_Reset;}
#endif /* STM32F10X_XL *//* Return the Program Status */return status;
}
当然官方给的不止是这一个函数写数据,官方提供了3个
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);//一次写一个字,对于32系统,一次写的是4个字节,uint32_t 变量大小,32bitFLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);//一次写一个半字,对于32系统,一次写的是2个字节,uint16_t 变量大小,16bitFLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);//一次写一个字节,对于32系统,一次写的是1个字节,uint8_t 变量大小,8bit
读数据操作
读数据的函数,官方并没有给出:下面我们自己给出,具体的读法代码如下:
//读取指定地址的半字(16位数据)
//也是按照半字读出,即每次读2个字节数据返回
uint16_t FLASH_ReadHalfWord(uint32_t address)
{return *(__IO uint16_t*)address;
}
如果要连续都区多个地址数据,可以进行如下代码操作
//从指定地址开始读取多个数据
void FLASH_ReadMoreData(uint32_t startAddress,uint16_t *readData,uint16_t countToRead)
{uint16_t dataIndex;for(dataIndex=0;dataIndex<countToRead;dataIndex++){readData[dataIndex]=FLASH_ReadHalfWord(startAddress+dataIndex*2);}
}
再次上锁
这步骤应该就是再次上锁,保护存储区不被重写覆盖了,直接使用官方的函数即可:FLASH_Lock();//上锁写保护
具体官方代码贴出如下:
/*** @brief Locks the FLASH Program Erase Controller.* @note This function can be used for all STM32F10x devices.* - For STM32F10X_XL devices this function Locks Bank1 and Bank2.* - For all other devices it Locks Bank1 and it is equivalent* to FLASH_LockBank1 function.* @param None* @retval None*/
void FLASH_Lock(void)
{/* Set the Lock Bit to lock the FPEC and the CR of Bank1 */FLASH->CR |= CR_LOCK_Set;#ifdef STM32F10X_XL/* Set the Lock Bit to lock the FPEC and the CR of Bank2 */FLASH->CR2 |= CR_LOCK_Set;
#endif /* STM32F10X_XL */
}
简单的小例程代码实现
例子功能:
1、将数据存储在stm32F105单片机的主存储区0x08036000地址开始的扇区,(0x08036000应该是该单片机大约108个扇区的开始地址位置即页108起始地址)。
2、将该单片机的页108(page108=0x08036000)处的数据再读出来;
具体实现代码如下,作为例子,只进行了半字的读写操作,我们写的数据buff为空,内容默认值为0
include "stm32f10x_flash.h"#define StartServerManageFlashAddress ((u32)0x08036000)//读写起始地址(内部flash的主存储块地址从0x08036000开始)
u16 wbuff[200] = "heihei";
u16 rbuff[200];//从指定地址开始写入多个数据
void FLASH_WriteMoreData(uint32_t startAddress,uint16_t *writeData,uint16_t countToWrite)
{ uint32_t offsetAddress=startAddress - FLASH_BASE; //计算去掉0X08000000后的实际偏移地址uint32_t sectorPosition=offsetAddress/SECTOR_SIZE; //计算扇区地址,对于STM32F103VET6为0~255uint32_t sectorStartAddress=sectorPosition*SECTOR_SIZE+FLASH_BASE; //对应扇区的首地址uint16_t dataIndex;if(startAddress<FLASH_BASE||((startAddress+countToWrite*2)>=(FLASH_BASE + SECTOR_SIZE * FLASH_SIZE))){return;//非法地址}FLASH_Unlock(); //解锁写保护FLASH_ErasePage(sectorStartAddress);//擦除这个扇区for(dataIndex=0;dataIndex<countToWrite;dataIndex++){FLASH_ProgramHalfWord(startAddress+dataIndex*2,writeData[dataIndex]);}FLASH_Lock();//上锁写保护
}//读取指定地址的半字(16位数据)
uint16_t FLASH_ReadHalfWord(uint32_t address)
{return *(__IO uint16_t*)address;
}//从指定地址开始读取多个数据
void FLASH_ReadMoreData(uint32_t startAddress,uint16_t *readData,uint16_t countToRead)
{uint16_t dataIndex;for(dataIndex=0;dataIndex<countToRead;dataIndex++){readData[dataIndex]=FLASH_ReadHalfWord(startAddress+dataIndex*2);}
}void write_to_flash(void)
{u16 wlen = sizeof(wbuff) / 2;FLASH_WriteMoreData(StartServerManageFlashAddress,wbuff,wlen);
}void read_from_flash(void)
{u16 rlen = sizeof(rbuff) / 2;FLASH_ReadMoreData(StartServerManageFlashAddress,rbuff,rlen);
}
void main(void)
{.........//初始化其他外设while(1){...........//其他外设执行函数if(满足条件真)//写数据操作{write_to_flash();}else //读数据操作{read_from_flash();}}}
值得的注意的是,我们读写的地址是0x08036000,读写方式是半字,这里地址空间对于stm32f105芯片来说是第108扇区,每个扇区2KB,stm32F105VC总共是256KB空间,128页。所以地址能取到0x08036000,像小中容量stm32f103单片机,64KB和128KB的主存储区地址都是到不了0x08036000,除非是stm32f103VE的256KB芯片的主存储快,0x08036000才是有效的存储地址,中小型这个地址都不是有效的主存储开地址(超出了)
相关文章:

STM32读写内部Flash
参考:https://blog.csdn.net/Caramel_biscuit/article/details/131925715 参考:https://blog.csdn.net/qq_36075612/article/details/124087574?spm1001.2014.3001.5502 目录 内存映射内部Flash的构成对内部Flash的写入过程查看工程内存的分布ROM加载空…...

golang文件锁,目录锁,syscall包的使用
先说结论 1. golang提供了syscall包来实现文件/目录的加锁,解锁 2. syscall包属于文件锁,是比较底层的技术,并不能在所有操作系统上完全实现,linux上实现了,windows下面就没有 3. 加锁时调用syscall.Flock(fd&#…...

数据库数据恢复-Syabse数据库存储页底层数据杂乱的数据恢复案例
数据库恢复环境: Sybase版本:SQL Anywhere 8.0。 数据库故障: 数据库所在的设备意外断电后,数据库无法启动。 错误提示: 使用Sybase Central连接后报错: 数据库故障分析: 经过北亚企安数据恢复…...

移远通信推出新一代高算力智能模组SG885G-WF,为工业和消费级IoT应用带来全新性能标杆
2023年7月24日,全球领先的物联网整体解决方案供应商移远通信宣布,正式推出其新一代旗舰级安卓智能模组SG885G-WF。该智能模组具有高达48 TOPS 的AI综合算力、强大性能及丰富的多媒体功能,非常适用于需要高处理能力和多媒体功能的工业和消费者…...

微信小程序开发,小程序类目符合,线上版本无权限申请wx.getLocation接口
我开发 的小程序类目符合wx.getLocation接口的申请标准 但是却还是显示无权限申请 后来研究好久才发现,小程序需要在发布线上版本时提交用户隐私保护指引 如未设置也可以在 设置-服务内容声明-用户隐私保护指引-声明处理用户信息项并补充填写后提交用户隐私协议审核…...

vue2企业级项目(五)
vue2企业级项目(五) 页面适配、主题切换 1、适配 项目下载插件 npm install --save-dev style-resources-loader vue-cli-plugin-style-resources-loader修改vue.config.js部分内容 const path require("path");module.exports {pluginOpt…...

【HTML5】拖放详解及实现案例
文章目录 效果预览代码实现 效果预览 代码实现 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>一颗不甘坠落的流星</title><style>#div1,#div2 {float: left;width: 100px;height: 27px;margin: 10px;paddin…...

Codeforces Round 888 (Div. 3)(视频讲解全部题目)
[TOC](Codeforces Round 888 (Div. 3)(视频讲解全部题目)) Codeforces Round 888 (Div. 3)(A–G)全部题目详解 A Escalator Conversations #include<bits/stdc.h> #define endl \n #define INF 0x3f3f3f3f using namesp…...

MySQL之深入InnoDB存储引擎——物理文件
文章目录 一、参数文件二、日志文件三、表结构定义文件四、InnoDB 存储引擎文件1、表空间文件2、重做日志文件 一、参数文件 当 MySQL 实例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数。在默认情况…...

Jquery操作html常用函数
1. text() 获取元素的文本内容:$("#element").text(); 设置元素的文本内容:$("#element").text("New Text"); 2. html() 获取元素的 HTML 内容:$("#element").html(); 设置元素的 HTML 内容&am…...

【Lua学习笔记】Lua进阶——Table,迭代器
文章目录 官方唯一指定数据结构--tabletable的一万种用法字典和数组 迭代器ipairs()pairs() 回到Table 在【Lua学习笔记】Lua入门中我们讲到了Lua的一些入门知识点,本文将补充Lua的一些进阶知识 官方唯一指定数据结构–table 在上篇文章的最后,我们指出…...

重庆市北斗新型智慧城市政府项目
技术栈:使用vue2JavaScriptElementUIvuexaxiosmapboxcesium 项目描述:重庆市北斗新型智慧城市政府项目是基于千寻孪界开发的一款智慧城市项目,包含车辆实时位置定位,智能设备的报警,基础设施的部设等等功能 工作内容&a…...

FANUC机器人SRVO-217故障报警原因分析及参考解决办法
FANUC机器人SRVO-217故障报警原因分析及参考解决办法 如下图所示,示教器提示:SRVO-217紧急停止电路板未找到, 查阅手册可以看到以下的报警说明: 故障原因: 通电时未能识别紧急停止电路板或者增设的安全I/O装置。连接有多个安全I/O装置的系统中,在报警信息的最后,会显示发…...

统信UOS安装mysql数据库(mariadb)-统信UOS安装JDK-统信UOS安装nginx(附安装包)
统信UOS离线全套安装教程(手把手教程) 银河麒麟的各种离线全套安装教程: https://blog.csdn.net/ACCPluzhiqi/article/details/131988147 1.统信UOS桌面系统安装mysql(mariadb) 2.统信UOS桌面系统安装JDK 3.统信UOS桌…...

上门小程序开发|上门服务小程序|上门家政小程序开发
随着移动互联网的普及和发展,上门服务成为了许多人生活中的一部分。上门小程序是一种基于小程序平台的应用程序,它提供了上门服务的在线平台,为用户提供了便捷的上门服务体验。下面将介绍一些适合开发上门小程序的商家。 家政服务商家&am…...

1000道网络安全必备面试题合集,秋招金九银十必看!!!
以下为网络安全各个方向涉及的面试题,星数越多代表问题出现的几率越大,祝各位都能找到满意的工作。 注:本套面试题,已整理成pdf文档,但内容还在持续更新中,因为无论如何都不可能覆盖所有的面试问题&#x…...

从0-1实现简易Raft分布式共识算法
一、Raft前置简介 Raft目前是最著名的分布式共识性算法,被广泛的应用在各种分布式框架、组件中,如Redis、RocketMq、Kafka、Nacos(CP)等 根据Raft论文,可将Raft拆分为如下4个功能模块: 领导者选举日志同…...

Spring 创建和使用
Spring 是⼀个包含了众多⼯具⽅法的 IoC 容器。既然是容器那么它就具备两个最基本的功能: 将对象存储到容器(Spring)中; 从容器中将对象取出来。 在 Java 语⾔中对象也叫做 Bean 1.创建 Spring 项目 接下来使⽤ Maven ⽅式来创…...

Javadoc comment自动生成
光标放在第二行 按下Alt Shift j 下面是Java doc的生成 Next Next-> Finish...

vue3 +ts 报错 index.vue 不是模块
那是因为index.vue中创建了一个空的script标签,而且语法使用的是ts语法。vue-cli会用ts语法解析和校验 如果是无状态组件,删掉 如果是有状态组件,导出该组件的实例 去掉null的script后:...

win10 hadoop报错 unable to load native-hadoop library
win10 安装hadoop执行hdfs -namenode format 和运行hadoop的start-all报错 unable to load native-hadoop library 验证: hadoop checknative -a 这个命令返回都是false是错的 返回下图是正确的 winutils: true D:\soft\hadoop-3.0.0\bin\winutils.exe Native li…...

前端(九)——探索微信小程序、Vue、React和Uniapp生命周期
🙂博主:小猫娃来啦 🙂文章核心:探索微信小程序、Vue、React和Uniapp生命周期 文章目录 微信小程序、Vue、React和Uniapp的基本定义和应用领域微信小程序生命周期生命周期概述页面生命周期应用生命周期组件和API的生命周期钩子 Vu…...

MyBatis查询数据库(2)
目录 前言🍭 一、增删查改操作 1、查 Ⅰ、mapper接口: Ⅱ、UserMapper.xml 查询所有用户的具体实现 SQL: Ⅲ、进行单元测试 2、增、删、改操作 Ⅰ、增 添加用户 添加用户并且返回自增 id Ⅱ、改 根据id修改用户名 开启 MyBatis …...

Jenkins构建完成后发送消息至钉钉
钉钉群的最终效果: 1、jenkins安装DingTalk插件,安装完成后重启 2、配置钉钉插件 参考官网文档:快速开始 | 钉钉机器人插件 系统管理 拉到最下面,可以看到钉钉配置 按照如下配置钉钉机器人 配置完成可以点击测试按钮࿰…...

从浏览器输入url到页面加载(六)前端必须了解的路由器和光纤小知识
前言 上一章我们说到了数据包在网线中的故事,说到了双绞线,还说到了麻花。这一章继续沿着这条线路往下走,说一些和cdn以及路由器相关,运营商以及光纤相关的小知识,前端同学应该了解一下的 目录 前言 1. CDN和路由器…...

C语言假期作业 DAY 06
题目 一、选择题 1、以下叙述中正确的是( ) A: 只能在循环体内和 switch 语句体内使用 break 语句 B: 当 break 出现在循环体中的 switch 语句体内时,其作用是跳出该 switch 语句体,并中止循环体的执行 C: continue 语句的作用是&…...

[nlp] tokenizer加速:fast_tokenizer=True
fast_tokenizer 是一个布尔值参数,用于指定是否使用快速的 tokenizer。在某些情况下,使用快速的 tokenizer 可以加快模型训练和推理速度。如果 fast_tokenizer 参数为 True,则会使用快速的 tokenizer;否则,将使用默认的 tokenizer。 快速的 tokenizer 通常使用一些技巧来减…...

基于OpenCV solvePnP函数估计头部姿势
人脸识别 文章目录 人脸识别一、姿势估计概述1、概述2、姿态估计3、在数学上表示相机运动4、姿势估计需要什么5、姿势估计算法6、Levenberg-Marquardt 优化 二、solvePnP函数1、函数原型2、参数详解 三、OpenCV源码1、源码路径 四、效果图像示例参考链接 一、姿势估计概述 1、…...

STC12C5A系列单片机内部 EEPROM 的应用
参考范例程序。 eeprom.c #include "eeprom.h"/*---------------------------- Disable ISP/IAP/EEPROM function Make MCU in a safe state ----------------------------*/ void IapIdle() {IAP_CONTR 0; //Close IAP functionIAP_CMD 0; …...

搭建测试平台开发(一):Django基本配置与项目创建
一、安装Django最新版本 1 pip install django 二、创建Django项目 首先进入要存放项目的目录,再执行创建项目的命令 1 django-admin startproject testplatform 三、Django项目目录详解 1 testplatform 2 ├── testplatform # 项目的容器 3 │ ├──…...