当前位置: 首页 > news >正文

STM32内置Flash

一、原理

 利用flash存储用户数据需要注意查看,用户数据是否会覆盖芯片运行程序。

IAP(在程序中编程)利用程序修改程序本身,和OTA是一个原理。IAP在程序中编程支持任意一种通信下载。

ICP(在电路中编程,通过外接引脚下载),每次下载会将程序完全更新。JTAG和SWD为仿真器下载程序,例如JLINK-JTAG和STLNIK-SWD。串口下载(手册中系统Bootload硬件有说明)使用的时系统存储器的Bootload。

 1、STM32的存储器映像

2、个人理解的Bootload原理

 3、STM32中容量产品闪存容量分布情况

可以看到的主存储器和信息块属于flash,闪存存储器不属于flash,相当于单独的外设。闪存存储器相当于上面信息块和主存储器的管理员,用于管理擦除和编程(读取flash直接进行指针读取即可,无需借用存储器)。

  1. STM32内部的flash只分成了页,起始地址为0x0800 0000,直到0x0801 FFFF,一共128K,每K一页,可以看到,以000、400、800、C00结尾的都是页起始地址。
  2. 系统存储区容量为2K,起始地址,存储系统Bootload内容。容量2K。
  3. 用户选项字节为16Byte,起始地址为0x1FFF F800 ,容量16Byte
  4. 用户选项字节和启动程序代码(系统存储区)也是flash,但是不计算在闪存容量中,闪存容量一般指程序存储区flash。
  5. 闪存存储器接口寄存器起始地址为0x4002 2000,属于外设,在外设存储区内

 

4、flash基本结构

5、flash擦除和编程详细内容

5.1、flash解锁

通过键寄存器写入指定的键值实现。RDPRT是解除读保护的密钥。将flash_cr重新置lock=1可锁住flash_cr。

5.2、使用指针访问存储器

volatile:

  1. 在c语言中表示易变的数据,防止编译器优化(编译器自动去除无用的繁杂代码)。
  2. STM32中有工作组寄存器,类似cache,工作速度快,但是使用的变量可能是程序中变量的映射。若程序为多线程或者中断,改变了此变量,会造成工作组寄存器和源变量值不一致,导致程序异常。通过volatile可以高速编译器变量需要实时注意是否更改。

通过*((__IO uint16_t *)(0x0800 0000))通过程序取出地址0x0800 0000地址的寄存器的数据,并通过uint16_t类型(可根据具体需求)返还。也可通过此形式直接指定指定地址的值。flash安全程度较高,需要提前解锁。若写入SRAM则不需要。

5.3、程序存储区编程

写入只能通过地址防止,进行半字的写入,一次2byte。写入32bit需要分两次,写入8bit可以先进行读出在使用读改写的方式写入。

5.4、程序存储区页擦除,flash写入前必须全擦除为1,只能写入0,不能写入1,根据手册的擦除最小单位进行。

5.5、全擦除

6、选项字节的组织和用途

可以看到表中,有数据和n数据,表示写入正常数据时要在对应的n位写入反码,这样才能够正常有效写入。 写入反码的过程,硬件会自动计算并写入。

WRP:配置flash程序存储区写保护,每位对应保护4个存储页,4*8*4 = 128页,刚好对应中容量的最大字节128K。

 

6.1 、选项字节编程

解锁flash锁后还需要解锁选项字节的锁(也需要先写入Key1,再写入Key2),之后才能操作选项字节。

6.2、选项字节擦除

 7、期间的电子签名

可以通过指定签名运行指定程序来限制程序被盗。 

8、手册

在SystemInit已经打开了HSI。

 

 

 

因为flash的原因,默认写保护使能为0,不使能写保护为1。

 

9、编程

在库文件.c的头部有说明,库中后期增加了XL加大容量的芯片,部分函数只能使用于加大容量的芯片。

9.1存储格式

  •  Intel存储格式为小端存储:即低字节在低地址,高字节在高地址。即L_Byte(低地址) +H_Byte(高地址) ,例如0x482A = 18594。小端存储为 0x48 0x2A。
intel格式(小端存储)bit
Byte10x2A(L_Byte)
76543210
20x48(H_Byte)
15141312111098
  • Motorola存储格式为大端存储:即高字节在低地址,低字节在高地址。即H_Byte(低地址) +L_Byte(高地址) ,例如0x482A = 18594。大端存储为 0x2A 0x48。
Motorola格式(大端存储)bit
Byte10x48(H_Byte)
15141312111098
20x2A(L_Byte)
76543210
  • 字节内部相同高bit在左,低bit在右。例如大端存储和小端字节内存储格式相同。
大端小端相同(bit位相同)
1514131211109876543210
0x48(H_Byte)0x2A(L_Byte)

 9.2为了区分程序存储空间和使用flash存储用户数据的空间大小,限制程序flash。

如果想写一个自定义的Bootload程序在尾部,也可以通过此处更改烧写程序的起始位置,但是要计算Bootload程序的大小、正式程序的大小,防止空间不足 。

右边是片上ram的内存。

9.3 下载配置,根据需要配置下载时如何擦除程序。使用IAP选择页擦除(STM32为扇区擦除选项)

前三个数为程序占用闪存的大小,后面两个相加为占用SRAM的大小。

目前可以看到我这个程序占用flash的大小为5.03KB=5150.72B,flash地址为0x0800 0000,偏移5148B,实际存储空间到0x0800 141C左右。

使用软件核实程序的确存储到了0x0800141C左右。

二、程序实例,STM32 ST-LINK Utility使用见主页文章

1、测试程序中的Flash基本操作单元的功能,flash页写入、flash读取、页擦除、全部擦除。(按键1用PB11、按键2用PB10)

1.1 测试1  (程序中#if (1))

1、程序烧写完成上电,查看OLED显示内容,是否为flash首地址的32bit、16bit、8bit(小端存储,低字节在低地址)

 

2、按下按键PB11可以看到和程序中相同flash程序存储区全部擦除,注意再次烧写程序时需要关闭STM32 ST-LINK Utility,防止冲突

3、重新烧写程序,按下按键PB12可以看到程序存储区中flash中0x0800 0400的页被删除,直到0x0800 0800(每个扇区1K),擦除后为FF

1.2、测试2 (程序中改#if (0))

可以看到0x0800FC00页地址原来的数据。

按下按键PB11或PB10,0x0800FC00和0x0800FC10所在地址的数据写为0x00000000(32bit)和0x0F0F(16bit)。

程序

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Button.h"
#include "MyFlash.h"
int main(void){OLED_Init();ButtonPB11PB10_Init();//测试程序存储区flash数据读取OLED_ShowString(1,1,"Flash:");//OLED_ShowHexNum(2,1,MyFlash_ReadWord(0x08000000),8);OLED_ShowHexNum(3,1,MyFlash_ReadHalfWord(0x08000000),4);OLED_ShowHexNum(4,1,MyFlash_ReadByte(0x08000000),2);while(1){#if (0)  //为真运行//测试程序存储区flash全部擦除和页擦除if(GetButtonPB11PB10() == 1){MyFlash_EraseAll();}else if(GetButtonPB11PB10() == 2){MyFlash_ErasePage(0x08000400);//擦除第二页数据}#else  //测试程序存储区flash写入字和半字if((GetButtonPB11PB10() == 1) || (GetButtonPB11PB10() == 2)){MyFlash_ErasePage(0x0800FC00);MyFlash_ProgramWord(0x0800FC00,0x00000000);//地址0x0800FC00写入半字0x00000000MyFlash_ProgramHalfWord(0x0800FC10,0x0F0F);//地址0x0800FC00写入半字0x0F0FOLED_ShowString(4,4,"W");Delay_ms(500);OLED_ShowString(4,4," ");}#endif}return 0;
}

MyFlash.c

#include "stm32f10x.h"                  // Device header
/*选项字节配置可通过外部的STM32 ST-Link Utility,用户自行使用选项字节容易出现问题*//*** @brief 读取Flash指定地址的字* @param  Address:32位地址*     @arg * @param  *     @arg * @retval None*/
uint32_t MyFlash_ReadWord(uint32_t Address){//对于Address,通过(__IO uint32_t *)变为uint32_t类型数据的指针,通过*取该地址的值return *((__IO uint32_t *)(Address)) ;
}/*** @brief 读取Flash指定地址的半字* @param  Address:32位地址*     @arg * @param  *     @arg * @retval None*/
uint16_t MyFlash_ReadHalfWord(uint32_t Address){//对于Address,通过(__IO uint16_t *)变为uint16_t类型数据的指针,通过*取该地址的值返回return *((__IO uint16_t *)(Address)) ;//uint16_t *表示指向uint16_t数据的指针
}/*** @brief 读取Flash指定地址的字* @param  Address:32位地址*     @arg * @param  *     @arg * @retval None*/
uint8_t MyFlash_ReadByte(uint32_t Address){//对于Address,通过(__IO uint32_t *)变为uint32_t的指针,通过*取该地址的值return *((__IO uint8_t *)(Address)) ;
}/*** @brief 程序存储区flash全部擦除* @param  *     @arg * @param  *     @arg * @retval None*/
void MyFlash_EraseAll(void){FLASH_Unlock();//程序存储区flash页编程解锁FLASH_EraseAllPages();//全部擦除FLASH_Lock();//程序存储区flash页编程关锁
}/*** @brief 程序存储区flash页擦除* @param  Address:需要擦除的页地址*     @arg * @param  *     @arg * @retval None*/
void MyFlash_ErasePage(uint32_t PageAddress){FLASH_Unlock();//程序存储区flash页编程解锁FLASH_ErasePage(PageAddress);//全部擦除FLASH_Lock();//程序存储区flash页编程关锁
}/*** @brief 程序存储区flash指定地址写字* @param  *     @arg * @param  *     @arg * @retval None*/
void MyFlash_ProgramWord(uint32_t Address,uint32_t WriteWord){FLASH_Unlock();//程序存储区flash页编程解锁FLASH_ProgramWord(Address,WriteWord);//指定地址写字FLASH_Lock();//程序存储区flash页编程关锁
}/*** @brief 程序存储区flash指定地址写半字* @param  *     @arg * @param  *     @arg * @retval None*/
void MyFlash_ProgramHalfWord(uint32_t Address,uint16_t WriteWord){FLASH_Unlock();//程序存储区flash页编程解锁FLASH_ProgramHalfWord(Address,WriteWord);//指定地址写半字,写入32bit地址的低地址,STM32flash小端存储,低字节在低位FLASH_Lock();//程序存储区flash页编程关锁
}

MyFlash.h

#ifndef __MYFLASH_H
#define __MYFLASH_H
#include "stm32f10x.h"                  // Device header
uint32_t MyFlash_ReadWord(uint32_t Address);
uint16_t MyFlash_ReadHalfWord(uint32_t Address);
uint8_t MyFlash_ReadByte(uint32_t Address);
void MyFlash_EraseAll(void);
void MyFlash_ErasePage(uint32_t PageAddress);
void MyFlash_ProgramWord(uint32_t Address,uint32_t WriteWord);
void MyFlash_ProgramHalfWord(uint32_t Address,uint16_t WriteWord);#endif

 Button.c

/*** @brief 初始化引脚PB11地开信号接收Button,用于辅助测试看门狗* @param  *     @arg * @param  *     @arg * @retval None*/
void ButtonPB11PB10_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef  GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);
}/*** @brief 获取PB11的Button是否按下* @param  *     @arg * @param  *     @arg * @retval None*/
uint8_t GetButtonPB11PB10(void){if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == RESET){Delay_ms(10);while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == RESET);Delay_ms(10);return 1;}if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) == RESET){Delay_ms(10);while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) == RESET);Delay_ms(10);return 2;}return 0;
}

Button.h

#ifndef __BUTTON_H
#define __BUTTON_H
#include "stm32f10x.h"                  // Device headeruint8_t GetButtonPB11PB10(void);
void ButtonPB11PB10_Init(void);
#endif

2、 读写内部Flash,通过Flash最后一页内存进行数据存储(上电读取内容、按键更新并写入内容)(按键1用PB11、按键2用PB10)

测试方法:

1、烧写程序后可以看到程序持续运行,此时、OLED显示程序存储区flash的最后一页存储的8Byte数据,第一次使用为0x00000000,可以看到指定的flash第一次读写标志位0xA5A5和0x00等数据已写入。

2、按键PB10可以看到程序存储区flash最后一页存储的前5字节当前数据变为0x1111;0x2222;0x3333;0x4444;按键PB11可以看到数据会自增。

程序

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Button.h"
#include "Store.h"
int main(void){OLED_Init();ButtonPB11PB10_Init();Store_Init();//显示当前Flash最后一页的数据OLED_ShowString(1,1,"Flash:");//while(1){uint8_t Key_Num = GetButtonPB11PB10();//测试按键控制Flash数据更新if(Key_Num == 1){//PB11for(uint8_t i=1;i<5;i++){Store_Data[i]++;}Store_Write();Store_Read();OLED_ShowString(4,1,"PB11");}else if(Key_Num == 2){//PB10Store_Data[1] = 0x1111;Store_Data[2] = 0x2222;Store_Data[3] = 0x3333;Store_Data[4] = 0x4444;Store_Write();Store_Read();OLED_ShowString(4,1,"PB10");}//显示Flash数据OLED_ShowHexNum(2,1,Store_Data[1],4);OLED_ShowHexNum(2,6,Store_Data[2],4);OLED_ShowHexNum(3,1,Store_Data[3],4);OLED_ShowHexNum(3,6,Store_Data[4],4);}return 0;
}

Store.c

#include "stm32f10x.h"                  // Device header
#include "MyFlash.h"#define STORE_START_ADDRESS 0x0800FC00 //写入页的起始地址
#define STORE_COUNT 512
#define STORE_FLAG  0xA5A5
uint16_t Store_Data[STORE_COUNT] = {STORE_FLAG,0};//用RAM对应存储Flash最后一页的数据/*** @brief flash最后一页数据初始化,第一次使用的话默认为0x00* @param  *     @arg * @param  *     @arg * @retval None*/
void Store_Init(void){//对于存储过数据的Flash我们默认使用最后一页的起始地址16bit作为标志if(MyFlash_ReadHalfWord(STORE_START_ADDRESS) == STORE_FLAG){//若不是第一次使用,读出数据for(uint16_t i=0;i<STORE_COUNT;i++){Store_Data[i] = MyFlash_ReadHalfWord(STORE_START_ADDRESS+i*2);}}else{//若是第一次使用,写入0xA5A5标志位和剩余的0x00MyFlash_ErasePage(STORE_START_ADDRESS);//擦除最后一页for(uint16_t i=0;i<STORE_COUNT;i++){MyFlash_ProgramHalfWord(STORE_START_ADDRESS+i*2,Store_Data[i]);//写入}}
}/*** @brief 将SAM的数据(Store_Data)写入flash最后一页* @param  *     @arg * @param  *     @arg * @retval None*/
void Store_Write(void){MyFlash_ErasePage(STORE_START_ADDRESS);//擦除最后一页for(uint16_t i=0;i<STORE_COUNT;i++){MyFlash_ProgramHalfWord(STORE_START_ADDRESS+i*2,Store_Data[i]);//写入}
}/*** @brief 将Flash的数据读出到将SAM的数据(Store_Data)* @param  *     @arg * @param  *     @arg * @retval None*/
void Store_Read(void){for(uint16_t i=0;i<STORE_COUNT;i++){Store_Data[i] = MyFlash_ReadHalfWord(STORE_START_ADDRESS+i*2);}
}

Store.h

#ifndef __STORE_H
#define __STORE_H
#include "stm32f10x.h"                  // Device headerextern uint16_t Store_Data[];
void Store_Init(void);
void Store_Write(void);
void Store_Read(void);#endif

Button.c

/*** @brief 初始化引脚PB11地开信号接收Button,用于辅助测试看门狗* @param  *     @arg * @param  *     @arg * @retval None*/
void ButtonPB11PB10_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef  GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);
}/*** @brief 获取PB11的Button是否按下* @param  *     @arg * @param  *     @arg * @retval None*/
uint8_t GetButtonPB11PB10(void){if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == RESET){Delay_ms(10);while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == RESET);Delay_ms(10);return 1;}if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) == RESET){Delay_ms(10);while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) == RESET);Delay_ms(10);return 2;}return 0;
}

Button.h

#ifndef __BUTTON_H
#define __BUTTON_H
#include "stm32f10x.h"                  // Device headeruint8_t GetButtonPB11PB10(void);
void ButtonPB11PB10_Init(void);
#endif

 MyFlash.c

#include "stm32f10x.h"                  // Device header
/*选项字节配置可通过外部的STM32 ST-Link Utility,用户自行使用选项字节容易出现问题*//*** @brief 读取Flash指定地址的字* @param  Address:32位地址*     @arg * @param  *     @arg * @retval None*/
uint32_t MyFlash_ReadWord(uint32_t Address){//对于Address,通过(__IO uint32_t *)变为uint32_t类型数据的指针,通过*取该地址的值return *((__IO uint32_t *)(Address)) ;
}/*** @brief 读取Flash指定地址的半字* @param  Address:32位地址*     @arg * @param  *     @arg * @retval None*/
uint16_t MyFlash_ReadHalfWord(uint32_t Address){//对于Address,通过(__IO uint16_t *)变为uint16_t类型数据的指针,通过*取该地址的值返回return *((__IO uint16_t *)(Address)) ;//uint16_t *表示指向uint16_t数据的指针
}/*** @brief 读取Flash指定地址的字* @param  Address:32位地址*     @arg * @param  *     @arg * @retval None*/
uint8_t MyFlash_ReadByte(uint32_t Address){//对于Address,通过(__IO uint32_t *)变为uint32_t的指针,通过*取该地址的值return *((__IO uint8_t *)(Address)) ;
}/*** @brief 程序存储区flash全部擦除* @param  *     @arg * @param  *     @arg * @retval None*/
void MyFlash_EraseAll(void){FLASH_Unlock();//程序存储区flash页编程解锁FLASH_EraseAllPages();//全部擦除FLASH_Lock();//程序存储区flash页编程关锁
}/*** @brief 程序存储区flash页擦除* @param  Address:需要擦除的页地址*     @arg * @param  *     @arg * @retval None*/
void MyFlash_ErasePage(uint32_t PageAddress){FLASH_Unlock();//程序存储区flash页编程解锁FLASH_ErasePage(PageAddress);//全部擦除FLASH_Lock();//程序存储区flash页编程关锁
}/*** @brief 程序存储区flash指定地址写字* @param  *     @arg * @param  *     @arg * @retval None*/
void MyFlash_ProgramWord(uint32_t Address,uint32_t WriteWord){FLASH_Unlock();//程序存储区flash页编程解锁FLASH_ProgramWord(Address,WriteWord);//指定地址写字FLASH_Lock();//程序存储区flash页编程关锁
}/*** @brief 程序存储区flash指定地址写半字* @param  *     @arg * @param  *     @arg * @retval None*/
void MyFlash_ProgramHalfWord(uint32_t Address,uint16_t WriteWord){FLASH_Unlock();//程序存储区flash页编程解锁FLASH_ProgramHalfWord(Address,WriteWord);//指定地址写半字,写入32bit地址的低地址,STM32flash小端存储,低字节在低位FLASH_Lock();//程序存储区flash页编程关锁
}

 MyFlash.h

#ifndef __MYFLASH_H
#define __MYFLASH_H
#include "stm32f10x.h"                  // Device header
uint32_t MyFlash_ReadWord(uint32_t Address);
uint16_t MyFlash_ReadHalfWord(uint32_t Address);
uint8_t MyFlash_ReadByte(uint32_t Address);
void MyFlash_EraseAll(void);
void MyFlash_ErasePage(uint32_t PageAddress);
void MyFlash_ProgramWord(uint32_t Address,uint32_t WriteWord);
void MyFlash_ProgramHalfWord(uint32_t Address,uint16_t WriteWord);#endif

3、读写芯片ID

读取STM32指定地址下的原厂id号,和容量。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
int main(void){OLED_Init();//显示当前Flash最后一页的数据OLED_ShowString(1,1,"F_Size:");//OLED_ShowHexNum(1,8,*((__IO uint16_t *)(0x1FFFF7E0)),4);//我的芯片显示0x80-Flash容量128kBOLED_ShowString(2,1,"UID:");//OLED_ShowHexNum(2,5,*((__IO uint16_t *)(0x1FFFF7E8+0x02)),4);OLED_ShowHexNum(2,9,*((__IO uint16_t *)(0x1FFFF7E8)),4);OLED_ShowHexNum(3,1,*((__IO uint32_t *)(0x1FFFF7E8+0x04)),8);OLED_ShowHexNum(4,1,*((__IO uint32_t *)(0x1FFFF7E8+0x08)),8);while(1){}return 0;
}

感谢江协科技!!!

相关文章:

STM32内置Flash

一、原理 利用flash存储用户数据需要注意查看&#xff0c;用户数据是否会覆盖芯片运行程序。 IAP&#xff08;在程序中编程&#xff09;利用程序修改程序本身&#xff0c;和OTA是一个原理。IAP在程序中编程支持任意一种通信下载。 ICP&#xff08;在电路中编程&#xff0c;通…...

面试:C++类成员初始化顺序

1、非静态数据成员&#xff1a;按它们在类定义的声明顺序初始化&#xff0c;不会按它们在初始化列表的顺序。 2、静态数据成员&#xff1a;在main函数启动之前&#xff0c;并且只初始化一次 3、基类构造函数&#xff1a;如果类从一个或多个基类继承而来&#xff0c;基类的构造…...

约束的笔记

约束的分类 为什么需要约束 为了保证数据的完整性 ①实体完整性&#xff08;Entity Integrity&#xff09;(同一个表中&#xff0c;不能存在两条完全相同无法区分的记录) ②域完整性&#xff08;Domain Integrity&#xff09; ③引用完整性&#xff08;Referential Integ…...

【Docker】安装registry本地镜像库,开启Https功能

下载镜像 docker pull registry:2 需要启动https功能&#xff0c;就要生成服务端的自签名的证书和私钥&#xff0c;以及在docker客户端安装这个经过签名的证书。 第一步&#xff1a;生成公私钥信息&#xff0c;第二步&#xff0c;制作证书签名申请文件&#xff0c; 第三步&…...

el-tree拖拽光标错位问题

背景&#xff1a;el-tree实现的分类树增加拖拽功能后&#xff0c;当分类树由于数量较多产生滚动条&#xff0c;如果分类树已滚动&#xff0c;进行拖拽时会造成光标错位的问题: 原因&#xff1a;el-tree拖拽光标定位的高度并未加上滚动的高度解决&#xff1a;将滚动的样式属性放…...

Linux权限

目录 一.Linux权限的概念 二.Linux权限管理 1.文件访问者的分类 2.文件类型和访问权限 1.文件类型 2.基本权限 3.文件权限的表示方法 1.字符表示法 2.八进制表示法 4.文件权限的相关访问方法 1.chmod 2.chown 3.chgrp 4.粘滞位 三.权限总结 一.Linux权限的概念 …...

mysql binlog 日志分析查找

文章目录 前言一、分析 binlog 内容二、编写脚本结果总结 前言 高效快捷分析 mysql binlog 日志文件。 mysql binlog 文件很大 怎么快速通过关键字查找内容 一、分析 binlog 内容 通过 mysqlbinlog 命令可以看到 binlog 解析之后的大概样子 二、编写脚本 编写脚本 search_…...

win32汇编环境,窗口程序中对按钮控件常用操作的示例

;运行效果 ;win32汇编环境&#xff0c;窗口程序中对按钮控件常用操作的示例 ;常用的操作&#xff0c;例如创建按钮控件&#xff0c;使其无效&#xff0c;改变文本&#xff0c;得到文本等。 ;将代码复制进radasm软件里&#xff0c;直接就可以编译运行。重点部分加备注。 ;>&g…...

风水算命系统架构与功能分析

系统架构 服务端&#xff1a;Java&#xff08;最低JDK1.8&#xff0c;支持JDK11以及JDK17&#xff09;数据库&#xff1a;MySQL数据库&#xff08;标配5.7版本&#xff0c;支持MySQL8&#xff09;ORM框架&#xff1a;Mybatis&#xff08;集成通用tk-mapper&#xff0c;支持myb…...

如何在 Ubuntu 22.04 上安装和配置邮件服务器教程

简介&#xff1a; 在本指南中&#xff0c;我们将演示如何在 Ubuntu 22.04 上安装和配置邮件服务器&#xff0c;因为大中型公司可以从拥有私人邮件服务器中获益匪浅。通过使用邮件服务器&#xff0c;可以密切监视所有电子邮件流量。此外&#xff0c;自定义设置的灵活性使得建立…...

后门原理与实践

实验目录 windows主机与kali虚拟机实现互联互通使用netcat获取主机操作Shell&#xff0c;cron启动使用socat获取主机操作Shell, 任务计划启动使用MSF meterpreter生成可执行文件&#xff0c;利用ncat或socat传送到主机并运行获取主机Shell使用MSF meterpreter生成获取目标主机…...

代理模式详解与应用

代理模式&#xff08;Proxy Pattern&#xff09;&#xff0c;也称为委托模式或 surrogate 模式&#xff0c;是一种结构型设计模式。它为其他对象提供一个代理以控制对这个对象的访问。通过引入代理对象&#xff0c;可以在不改变原始对象接口的前提下&#xff0c;添加额外的功能…...

C#,动态规划问题中基于单词搜索树(Trie Tree)的单词断句分词( Word Breaker)算法与源代码

1 分词 分词是自然语言处理的基础&#xff0c;分词准确度直接决定了后面的词性标注、句法分析、词向量以及文本分析的质量。英文语句使用空格将单词进行分隔&#xff0c;除了某些特定词&#xff0c;如how many&#xff0c;New York等外&#xff0c;大部分情况下不需要考虑分词…...

基于单片机的智能家居排气扇系统设计

1系统方案设计 本设计基于单片机的智能家居排气扇系统采用STM32单片机作为主控制器&#xff0c;通过DHT11温湿传感器和MQ-2烟雾传感器实现温度、湿度、烟雾检测&#xff0c;在自动模式下&#xff0c;可以根据烟雾浓度通过PWM调速的方式自动调节排气扇的速度&#xff0c;而在手…...

基于JAVA+SpringBoot+Vue的二手车交易系统

基于JAVASpringBootVue的二手车交易系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; 哈喽…...

【JVM-2.2】使用JConsole监控和管理Java应用程序:从入门到精通

在Java应用程序的开发和运维过程中&#xff0c;监控和管理应用程序的性能和资源使用情况是非常重要的。JConsole是Java Development Kit&#xff08;JDK&#xff09;自带的一款图形化监控工具&#xff0c;它可以帮助开发者实时监控Java应用程序的内存、线程、类加载以及垃圾回收…...

windows及linux 安装 Yarn 4.x 版本

1. 确保系统环境准备 a. 安装 Node.js Yarn 依赖于 Node.js,所以需要先安装 Node.js。前往 Node.js 官网 下载并安装适合你的 Windows 版本的 Node.js(推荐 LTS 版本)。安装完成后,打开命令提示符(CMD)或 PowerShell,验证安装:node -v npm -v如果显示版本号,则表示安…...

VS2015 + OpenCV + OnnxRuntime-Cpp + YOLOv8 部署

近期有个工作需求是进行 YOLOv8 模型的 C 部署&#xff0c;部署环境如下 系统&#xff1a;WindowsIDE&#xff1a;VS2015语言&#xff1a;COpenCV 4.5.0OnnxRuntime 1.15.1 0. 预训练模型保存为 .onnx 格式 假设已经有使用 ultralytics 库训练并保存为 .pt 格式的 YOLOv8 模型…...

1.两数之和--力扣

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1…...

MySQL库表的操作

目录 一、库的操作 1.1库的创建 1.2字符集和校验规则 1.2.1 查看系统默认字符集以及校验规则 1.2.2 查看数据库支持的字符集 1.2.3 查看数据库支持的字符集校验规则 1.2.4 校验规则对数据库的影响 1.3操纵数据库 1.3.1显示库 1.3.2显示创建语句 1.3.3修改数据库 1.3…...

【强化学习】深度确定性策略梯度算法(DDPG)详解(附代码)

&#x1f4e2;本篇文章是博主强化学习&#xff08;RL&#xff09;领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅…...

单片机实物成品-011 火灾监测

火灾监测&#xff08;20个版本&#xff09; 版本20&#xff1a; oled显示温湿度烟雾浓度火焰传感器天然气浓度窗户风扇水泵排气系统声光报警语音播报按键WIFI模块 ----------------------------------------------------------------------------- https://www.bilibili.com…...

牛客网刷题 ——C语言初阶(6指针)——BC106 上三角矩阵判定

1. 题目描述——BC106 上三角矩阵判定 牛客网OJ题链接 描述 KiKi想知道一个n阶方矩是否为上三角矩阵&#xff0c;请帮他编程判定。上三角矩阵即主对角线以下的元素都为0的矩阵&#xff0c;主对角线为从矩阵的左上角至右下角的连线。 示例 输入&#xff1a; 3 1 2 3 0 4 5 0 0…...

Mysql--重点篇--索引(索引分类,Hash和B-tree索引,聚簇和非聚簇索引,回表查询,覆盖索引,索引工作原理,索引失效,索引创建原则等)

索引是数据库中用于加速查询操作的重要机制。通过索引&#xff0c;MySQL可以快速定位到满足查询条件的数据行&#xff0c;而不需要扫描整个表。合理的索引设计可以显著提高查询性能&#xff0c;但不合理的索引可能会导致性能下降和磁盘空间浪费。因此&#xff0c;理解索引的工作…...

Vue3框架核心功能点响应式数据reactive、组合式API setup、computed、组件通信、路由导航,状态管理vuex、pinia等的实战示例代码

记录几个Vue3框架核心功能点&#xff0c;例如响应式数据reactive、组合式API setup、computed、组件通信、路由导航&#xff0c;状态管理vuex、pinia……等实战示例代码&#xff1a; 一、响应式数据&#xff08;Reactive Data&#xff09; 创建响应式对象 使用reactive函数创建…...

Gitlab-Runner配置

原理 Gitlab-Runner是一个非常强大的CI/CD工具。它可以帮助我们自动化执行各种任务&#xff0c;如构建、测试和部署等。Gitlab-Runner和Gitlab通过API通信&#xff0c;接收作业并提交到执行队列&#xff0c;Gitlab-Runner从队列中获取作业&#xff0c;并允许在不同环境下进行作…...

多台PC共用同一套鼠标键盘

当环境中有多个桌面 pc 需要操作的时候&#xff0c;在 多台 pc 之间切换会造成很多的不方便 可以通过远程进行连接&#xff0c;但是有一个更好的方案是让多台机器之间共用同一套键盘鼠标 常用的解决方案 synergy 和 sharemouse&#xff0c;通过移动光标在不同的 pc 间切换 s…...

学会使用computed计算属性与watch监听(小白学习笔记)

1. 使用不同方法实现 姓名案例 需求: 根据data中 firstName 和 lastName 的值 来动态地展示全名 1.1. 插值语法 如果只使用学过的插值语法 那可以在模板中直接使用两个变量 . 但是如果需要对数据进行计算等处理 就需要在插值语法里写复杂的js表达式. 这样就违背了vue风格指…...

atoi函数的概念和使用案例

atoi 函数是 C 语言标准库中的一个函数&#xff0c;它用于将字符串转换为整数。atoi 的名称是 “ASCII to integer” 的缩写。该函数定义在 <stdlib.h> 头文件中。 概念 atoi 函数会从字符串的开始位置开始转换&#xff0c;直到遇到第一个非数字字符或遇到字符串结束符…...

unittest VS pytest

以下是 unittest 和 pytest 框架的对比表格&#xff1a; 特性unittestpytest设计理念基于类的设计&#xff0c;类似于 Java 的 JUnit更简洁&#xff0c;基于函数式编程设计&#xff0c;支持类和函数两种方式测试编写需要继承 unittest.TestCase 类&#xff0c;方法以 test_ 开…...

B2C API安全警示:爬虫之外,潜藏更大风险挑战

在数字化时代&#xff0c;B2C&#xff08;Business-to-Consumer&#xff09;电子商务模式已成为企业连接消费者、推动业务增长的重要桥梁。而B2C API&#xff08;应用程序编程接口&#xff09;作为企业与消费者之间数据交互的桥梁&#xff0c;其安全性更是至关重要。然而&#…...

大型语言模型(LLM)中的tokens是什么

大型语言模型(LLM)中的tokens是什么 在大型语言模型(LLM)中,tokens是文本处理的基本单位,它可以是一个单词、一个字符、一个标点符号,或者是一个特殊的标记。以下是关于tokens的详细介绍及举例: 一、tokens的定义和作用 定义:tokens是将文本分割成的一个个有意义的…...

自动驾驶---E2E架构演进

1 背景 模型最早应用的自动驾驶模块就是感知层面&#xff0c;随着技术的发展&#xff0c;逐渐开始应用到决策规划等其它模块。端到端自动驾驶架构是一种基于深层神经网络模型和方法的自动驾驶技术模式。目前一段式端到端系统只有在英伟达早期所做的demo中实现&#xff0c;再者就…...

w~自动驾驶~合集16

我自己的原文哦~ https://blog.51cto.com/whaosoft/12765612 #SIMPL 用于自动驾驶的简单高效的多智能体运动预测基准 原标题&#xff1a;SIMPL: A Simple and Efficient Multi-agent Motion Prediction Baseline for Autonomous Driving 论文链接&#xff1a;https://ar…...

python学opencv|读取图像(三十)使用cv2.getAffineTransform()函数倾斜拉伸图像

【1】引言 前序已经学习了如何平移和旋转缩放图像&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;二十七&#xff09;使用cv2.warpAffine&#xff08;&#xff09;函数平移图像-CSDN博客 python学opencv|读取图像&#xff08;二十八&#xff0…...

Java异常处理

1.异常是程序运行过程中出现的非正常现象&#xff0c;例如输入错误、需要处理的文件不存在&#xff0c;在网络上传输数据但是网络没有连接等2.在java中我们把异常分为&#xff1a;错误&#xff08;Error&#xff09;和异常&#xff08;Exception&#xff09;Exception类有自己的…...

STM32-DMA数据转运

注&#xff1a;DMA对应的库函数文件讲解 DMA_GetITStatus(uint32_t DMAy_IT) 是一个用于检查DMA&#xff08;直接存储器访问&#xff09;中断状态的库函数。它通常在使用STM32系列微控制器及其标准外设库时被调用。此函数的主要作用是返回指定DMA通道的特定中断标志的状态&…...

ASP.NET Core 实现微服务 - Elastic APM

这次要给大家介绍的是Elastic APM &#xff0c;一款应用程序性能监控组件。APM 监控围绕对应用、服务、容器的健康监控&#xff0c;对接口的调用链、性能进行监控。在我们实施微服务后&#xff0c;由于复杂的业务逻辑&#xff0c;服务之间的调用会像蜘蛛网一样复杂。有了调用链…...

Stable Diffusion本地部署教程(附安装包)

想使用Stable Diffusion需要的环境有哪些呢? python3.10.11(至少也得3.10.6以上):依赖python环境NVIDIA:GPUgit:从github上下载包(可选,由于我已提供安装包,你可以不用git)Stable Diffusion安装包工具包: NVIDIA:https://developer.nvidia.com/cuda-toolkit-archiv…...

图片和短信验证码(头条项目-06)

1 图形验证码接口设计 将后端⽣成的图⽚验证码存储在redis数据库2号库。 结构&#xff1a; {img_uuid:0594} 1.1 创建验证码⼦应⽤ $ cd apps $ python ../../manage.py startapp verifications # 注册新应⽤ INSTALLED_APPS [django.contrib.admin,django.contrib.auth,…...

天气app的收获

天气app的收获 无论如何&#xff0c;是基于MVC模式&#xff0c;但都是从UI页面开始设计&#xff0c;然后根据输入的城市名称&#xff0c;将其传入到model层&#xff0c;进行相对应的处理。 对于controler层&#xff0c;需要通过一些协议完成一些输入的反馈&#xff0c;例如输…...

软件自动定时启动器

点击添加软件&#xff0c;可以添加可执行文件软件&#xff0c;设置启动的时间&#xff0c;也可以设置关闭的时间 注意&#xff0c;时间为00&#xff1a;00&#xff1a;00 等于没设置&#xff0c;这个时间不在设置范围&#xff0c;其他任何时间都可以 1.1更新 1&#xff1a;修复…...

k8s部署rocketmq踩坑笔记

给团队部署一个rocketmq4.8.0. k8s上部署的broker&#xff0c;注册到nameserver上是自己的pod ip&#xff0c;导致本机连接到的broker的pod ip&#xff0c;这个ip k8s集群外的机器是无法联通的。 nameserver上注册的是这个pod ipv4 尝试将broker的配置brokerIP1修改为注册到na…...

从项目代码看 React:State 和 Props 的区别及应用场景实例讲解

在 React 中&#xff0c;state 和 props 是组件的两个重要概念&#xff0c;它们有不同的作用和应用场景。理解它们之间的区别对于开发 React 应用至关重要。 1. state 和 props 的区别 props (属性)&#xff1a; props 是由父组件传递给子组件的数据或函数。props 是只读的&am…...

深度学习中的优化算法

深度学习中的优化算法&#xff0c;是模型训练期间微调神经网络参数的关键元素。其主要作用是最小化模型的误差或损失&#xff0c;从而提高性能。各种优化算法(称为优化器)采用不同的策略来收敛到最佳参数值&#xff0c;从而有效地提高预测效果。 在深度学习的背景下&#xff0c…...

python3GUI--大屏可视化-传染病督导平台 By:PyQt5

文章目录 一&#xff0e;前言二&#xff0e;预览三&#xff0e;软件组成&开发心得1.样式&使用方法2.左侧表格实现3.设计4.学习5.体验效果 四&#xff0e;代码分享1.环形渐变进度组件2.自定义图片的背景组件 五&#xff0e;总结 大小&#xff1a;60.9 M&#xff0c;软件…...

设计模式——单例模式

单例模式 实现单例模式的方法前置条件懒汉式&#xff08;Lazy Initialization&#xff09;饿汉式&#xff08;Eager Initialization&#xff09;双重锁式&#xff08;Double-Checked Locking&#xff09;静态内部类式&#xff08;Static Inner Class&#xff09;枚举式&#xf…...

【01】AE特效开发制作特技-Adobe After Effects-AE特效制作快速入门-制作飞机,子弹,爆炸特效以及导出png序列图-优雅草央千澈

【01】AE特效开发制作特技-Adobe After Effects-AE特效制作快速入门-制作飞机&#xff0c;子弹&#xff0c;爆炸特效以及导出png序列图-优雅草央千澈 开发背景 优雅草央千澈所有的合集&#xff0c;系列文章可能是不太适合完全初学者的&#xff0c;因为课程不会非常细致的系统…...

docker一键安装脚本(docker安装)

第一种方法一键安装命令 curl -O --url http://luyuanbo79.south.takin.cc/wenjian/docker_install.sh && chmod x docker_install.sh && ./docker_install.sh 备用方法 curl -O --url https://file.gitcode.com/4555247/releases/untagger_0896d4789937405…...

Python的Matplotlib库应用(超详细教程)

目录 一、环境搭建 1.1 配置matplotlib库 1.2 配置seaborn库 1.3 配置Skimage库 二、二维图像 2.1 曲线&#xff08;直线&#xff09;可视化 2.2 曲线&#xff08;虚线&#xff09;可视化 2.3 直方图 2.4 阶梯图 三、三维图像 3.1 3D曲面图 3.2 3D散点图 3.3 3D散…...