STM32FreeRTOS 使用QSPI驱动nandFlash

STM32FreeRTOS 使用QSPI驱动nandFlash

不清楚为什么STM32同时打开3个以上的音频文件时会出现播放问题,所以更换方案。因为SRAM的内存空间过小,用于存储音频文件不适合,所以使用大小为128MByte的nandFlash。

nandFlash使用华邦的W25N01GVZEIG,单片机使用STM32F412ZET6。
在这里插入图片描述
驱动分享:
w25n01g.c

#include "w25n01g.h"
#include "string.h" extern QSPI_HandleTypeDef hqspi;static void my_delay(uint32_t counter){while(counter--);
}
uint8_t W25NXX_Init(){uint32_t quad_bk1;W25NXX_ReadID(& quad_bk1 );if( quad_bk1 != 0xefaa21 ) return 0;W25NXX_Write_SR(W25NXX_StatusReg1,0x00);W25NXX_Write_SR(W25NXX_StatusReg2 , 0x18 );return 1;
}//write enble instruction is neede befor the erase and write 
// set the WEL bit
void W25NXX_Write_Enable(){QSPI_CommandTypeDef cmd = {0};cmd.Instruction = W25NXX_WriteEnable;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);
}
//W25NXX write prohibited
//Clear WEL bit
void W25NXX_Write_Disable(void)   
{  QSPI_CommandTypeDef cmd = {0};cmd.Instruction = W25NXX_WriteDisable;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);
} 
//set rest instruction
//befor initialize
void W25NXX_reset(){QSPI_CommandTypeDef cmd = {0};cmd.Instruction = W25NXX_RESET;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);HAL_Delay(50);
}//Read the status register of W25NXX, W25NXX has 3 status registers
//Status register 1: add = 0xAx
//BIT7 6 5 4 3 2 1 0
//SRP0 BP3 BP2 BP1 BP0 TB WP_E SRP1
//Status register 2: add = 0xBx
//BIT7 6 5 4 3 2 1 0
//OTP-L OTP-E SR1-L BUF (R) (R) (R)
//Status register 3: add = 0xCx
//BIT7 6 5 4 3 2 1 0
//(R) LUT-F ECC1 ECC0 / P-FAIL E-Fail WEL BUSSY
//Return value: status register value
void W25NXX_ReadSR(uint8_t ADD,uint8_t* SR1)   
{  uint8_t byte[2]; QSPI_CommandTypeDef cmd = {0};cmd.Instruction = W25NXX_ReadStatusReg;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_1_LINE;cmd.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;cmd.AlternateBytes = ADD ;cmd.DataMode = QSPI_DATA_1_LINE;cmd.NbData = 1;HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);HAL_QSPI_Receive(&hqspi , byte , W25NXX_QUAD_TIMEOUT);*SR1 = byte[0];
}   
//Write W25NXX status register
void W25NXX_Write_SR(uint8_t ADD,uint8_t sr)   
{ QSPI_CommandTypeDef cmd = {0};uint32_t tick_start;cmd.Instruction = W25NXX_WriteStatusReg;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_1_LINE;cmd.AlternateBytesSize = QSPI_ALTERNATE_BYTES_16_BITS;cmd.AlternateBytes = (uint32_t)((ADD << 8) | sr);HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);//Wait for the end of writingtick_start = HAL_GetTick();while( W25NXX_get_BUSSY() ){if( HAL_GetTick() - tick_start > W25NXX_TIMOUT ){break;}} 
} 
//return 1 if the BUSSY bit is set
uint8_t W25NXX_get_BUSSY(){uint8_t quad_bk1_sr;W25NXX_ReadSR(W25NXX_StatusReg3,& quad_bk1_sr );return (quad_bk1_sr & 0x01);
}
// read manufacture ID of the chip the ID for  W25N01 is 0xEFAA21 
void W25NXX_ReadID(uint32_t * id1 )
{uint8_t temp[6];QSPI_CommandTypeDef cmd = {0};cmd.Instruction = W25NXX_JedecDeviceID;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;cmd.DummyCycles = 8;cmd.DataMode = QSPI_DATA_1_LINE;cmd.NbData = 3;HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);HAL_QSPI_Receive(&hqspi , temp , W25NXX_QUAD_TIMEOUT);*id1 =(temp[0]<<16) | (temp[1]<<8) | temp[2];
}    
// read one page up to 2048 bytes
//	NumByteToRead <= 2048
uint16_t W25NXX_Read_Page(uint8_t* pBuffer,uint32_t SectroReadAddr,uint32_t NumByteToRead)   
{ uint32_t address = SectroReadAddr * W25NXX_SectorSize; // byte addressuint32_t PageAdd = address >> 11;uint32_t tick_start;if( NumByteToRead == 0 ) return 0;if( NumByteToRead > W25N01_PageSize) NumByteToRead = W25N01_PageSize;if( NumByteToRead > W25N01_PageSize - (address & 0x7ff ) ) NumByteToRead = W25N01_PageSize - (address & 0x7ff);QSPI_CommandTypeDef cmd = {0};cmd.Instruction = W25NXX_PageRead;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;
//	cmd.Address =  address >> 11 ; // page address = (address / W25N01_PageSize)
//	cmd.AddressMode = QSPI_ADDRESS_1_LINE;
//	cmd.AddressSize = QSPI_ADDRESS_16_BITS;cmd.DummyCycles = 8;cmd.DataMode = QSPI_DATA_1_LINE;cmd.NbData = 2 ;uint8_t buff[2];buff[0] = (PageAdd >> 8)& 0xff;buff[1] = (PageAdd & 0xff);HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);	HAL_QSPI_Transmit(&hqspi ,buff , W25NXX_QUAD_TIMEOUT);//Wait for the bussytick_start = HAL_GetTick();while( W25NXX_get_BUSSY() ){if( HAL_GetTick() - tick_start > W25NXX_TIMOUT ){return 0;}}  				 cmd.Instruction = W25NXX_FastRead;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;cmd.Address = address &  0x7ff ; // column address = address & ( ( 1 << 11) - 1)cmd.AddressMode = QSPI_ADDRESS_1_LINE;cmd.AddressSize = QSPI_ADDRESS_16_BITS;cmd.DummyCycles = 8;cmd.DataMode = QSPI_DATA_4_LINES;cmd.NbData = NumByteToRead ;HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);HAL_QSPI_Receive_DMA(&hqspi , pBuffer);//Wait for the end of writingtick_start = HAL_GetTick();while( W25NXX_get_BUSSY() ){if( HAL_GetTick() - tick_start > W25NXX_TIMOUT ){return 0;}} 
//	my_delay(2400); // roughly 5usreturn	NumByteToRead; // To check if the number of bytes read is less than expected. if the address is reaches the end of the page
}  
//SPI writes less than 2048 bytes of data in one page (0~65535)
//Write a maximum of (2048) bytes of data at the specified address
//pBuffer: data storage area
//WriteAddr: The address to start writing (maximum 27bit)
uint16_t W25NXX_Write_Page(uint8_t* pBuffer,uint32_t SectorWriteAddr,uint32_t NumByteToWrite)
{uint32_t address = SectorWriteAddr * W25NXX_SectorSize; // byte addressuint32_t PageAdd = address >> 11;uint32_t tick_start;if( NumByteToWrite == 0 ) return 0;if( NumByteToWrite > W25N01_PageSize) NumByteToWrite = W25N01_PageSize;if( NumByteToWrite > W25N01_PageSize - (address & ( ( 1 << 11) - 1)) ) NumByteToWrite = W25N01_PageSize - (address & ( ( 1 << 11) - 1));QSPI_CommandTypeDef cmd = {0};cmd.Instruction = W25NXX_PageRead;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;
//	cmd.Address =  address >> 11 ; // page address = (address / W25N01_PageSize)
//	cmd.AddressMode = QSPI_ADDRESS_1_LINE;
//	cmd.AddressSize = QSPI_ADDRESS_16_BITS;cmd.DummyCycles = 8;cmd.DataMode = QSPI_DATA_1_LINE;cmd.NbData = 2 ;uint8_t buff[2];buff[0] = (PageAdd >> 8)& 0xff;buff[1] = (PageAdd & 0xff);HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);	HAL_QSPI_Transmit(&hqspi ,buff , W25NXX_QUAD_TIMEOUT);//Wait for the bussytick_start = HAL_GetTick();while( W25NXX_get_BUSSY() ){if( HAL_GetTick() - tick_start > W25NXX_TIMOUT ){return 0;}}W25NXX_Write_Enable();	cmd.Instruction = W25NXX_LoadRandomProgramData;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;cmd.Address = (address & 0x7ff ); // column addresscmd.AddressMode = QSPI_ADDRESS_1_LINE;cmd.AddressSize = QSPI_ADDRESS_16_BITS;cmd.DataMode = QSPI_DATA_4_LINES;cmd.NbData = NumByteToWrite ;cmd.DummyCycles = 0;HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);	HAL_QSPI_Transmit(&hqspi , pBuffer , W25NXX_QUAD_TIMEOUT);//Wait for the end of writingtick_start = HAL_GetTick();while( W25NXX_get_BUSSY() ){if( HAL_GetTick() - tick_start > W25NXX_TIMOUT ){return 0;}} 				  cmd.Instruction = W25NXX_ProgramExec;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;
//	cmd.Address = address >> 11;
//	cmd.AddressMode = QSPI_ADDRESS_1_LINE;
//	cmd.AddressSize = QSPI_ADDRESS_16_BITS;cmd.Address = 0;cmd.AddressMode = QSPI_ADDRESS_NONE;cmd.DataMode = QSPI_DATA_1_LINE;cmd.NbData = 2;cmd.DummyCycles = 8;buff[0] = (PageAdd >> 8)& 0xff;buff[1] = (PageAdd & 0xff);HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);HAL_QSPI_Transmit(&hqspi ,buff , W25NXX_QUAD_TIMEOUT);//Wait for the end of writingtick_start = HAL_GetTick();while( W25NXX_get_BUSSY() ){if( HAL_GetTick() - tick_start > W25NXX_TIMOUT ){return 0;}} 
//	my_delay(4800); // roughly 10usreturn NumByteToWrite;// To check if the number of bytes written is less than expected. If the address is reaches the end of the page
} 
//Write SPI FLASH
//Write data of the specified length at the specified address
//This function has erase operation!
//pBuffer: data storage area
//SectorWriteAddr: The address of the satrt page to write
//NumByteToWrite: The number of bytes to be written 
void W25NXX_Write(uint8_t* pBuffer,uint32_t SectorWriteAddr,uint32_t NumByteToWrite)   
{    uint32_t WriteAdd = SectorWriteAddr,ReadAdd;uint32_t EraseAdd , NextBlock;uint8_t buff_read[W25N01_PageSize];uint16_t PageAddMod;uint8_t *pDataRead = pBuffer ;uint16_t NumPageToWrite = NumByteToWrite / W25N01_PageSize;uint8_t NeedErase = 0;uint32_t write_backup_address;uint32_t start;while(NumByteToWrite){EraseAdd = (uint32_t)( WriteAdd / W25N01_BlockSize ) * W25N01_BlockSize;NextBlock = EraseAdd + W25N01_BlockSize;write_backup_address = W25N01_LAST_BLOCK;for(uint16_t i = 0 ; i < NumPageToWrite ; i++){if( ( WriteAdd  + i ) == NextBlock ) break; // reached end of the blockW25NXX_Read_Page(buff_read, WriteAdd  + i , W25N01_PageSize);for( uint16_t j = 0 ; j < W25N01_PageSize ; j++){if( buff_read[ j ] != 0xff ){NeedErase = 1;break;}}if( NeedErase == 1) break;}if(NeedErase){//uint8_t buff_repalce[ W25N01_EraseSize ] ;ReadAdd = EraseAdd;
//			for( uint8_t i = 0 ; i < W25N01_BlockSize ; i++){
//				W25NXX_Read_Page(&buff_repalce[ W25N01_PageSize * i ] , ReadAdd , W25N01_PageSize);
//				ReadAdd++;
//			}//W25NXX_Erase_Block256K(write_backup_address);start = HAL_GetTick();while( W25NXX_Erase_Block128K(write_backup_address) != 1 && HAL_GetTick() - start < 1000);for( uint8_t i = 0 ; i < W25N01_BlockSize ; i++){W25NXX_Read_Page(buff_read , ReadAdd , W25N01_PageSize);ReadAdd++;W25NXX_Write_Page( buff_read , write_backup_address , W25N01_PageSize);write_backup_address++;}//W25NXX_Erase_Block256K(EraseAdd);start = HAL_GetTick();while( W25NXX_Erase_Block128K(EraseAdd) != 1 && HAL_GetTick() - start < 1000);write_backup_address = W25N01_LAST_BLOCK;for(PageAddMod = 0; PageAddMod < W25N01_BlockSize ; PageAddMod++){if( PageAddMod < WriteAdd % W25N01_BlockSize || NumPageToWrite == 0){W25NXX_Read_Page(buff_read , write_backup_address , W25N01_PageSize);W25NXX_Write_Page( buff_read , EraseAdd , W25N01_PageSize);}else{W25NXX_Write_Page( pDataRead , WriteAdd , W25N01_PageSize);pDataRead += W25N01_PageSize;NumByteToWrite -= W25N01_PageSize;NumPageToWrite-- ;WriteAdd++;//if( NumPageToWrite == 0 )  break;}write_backup_address++;EraseAdd++;}//			for(PageAddMod = WriteAdd % W25N01_BlockSize; PageAddMod < W25N01_BlockSize ; PageAddMod++){
				memcpy(&buff_repalce[ W25N01_PageSize * PageAddMod ] , pDataRead , W25N01_PageSize);
//				W25NXX_Write_Page( pDataRead , WriteAdd , W25N01_PageSize);
//
//				pDataRead += W25N01_PageSize;
//				NumByteToWrite -= W25N01_PageSize;
//				NumPageToWrite-- ;
//				WriteAdd++;
//				if( NumPageToWrite == 0 )  break;
//			}//			for( uint8_t i = 0 ; i < W25N01_BlockSize ; i++){
//				W25NXX_Write_Page( &buff_repalce[ W25N01_PageSize * i ] , EraseAdd , W25N01_PageSize);
//				EraseAdd++;
//			}}else{ // does not need erasefor(uint16_t i = 0 ; i < W25N01_BlockSize ; i++){if( ( WriteAdd  ) == NextBlock ) break; // reached end of the blockW25NXX_Write_Page( pDataRead , WriteAdd , W25N01_PageSize);pDataRead += W25N01_PageSize;NumByteToWrite -= W25N01_PageSize;NumPageToWrite-- ;WriteAdd++;if( NumPageToWrite == 0 )  break;}}NeedErase = 0;}
}
//read an desired amount of bytes
void W25NXX_Read(uint8_t* pBuffer,uint32_t SectorReadAddr,uint32_t NumByteToRead)
{uint32_t ReadAdd = SectorReadAddr;uint16_t NumPageToRead = NumByteToRead / W25N01_PageSize;for(uint16_t i =0 ; i < NumPageToRead ; i++){W25NXX_Read_Page( &pBuffer[ W25N01_PageSize * i ] , ReadAdd , W25N01_PageSize);ReadAdd ++;}	
}//Erase a one blocks of. 64 * 2048 byte
//block_add: The sector address is set according to the actual capacity
//Minimum time to block a sector: 150ms
uint8_t W25NXX_Erase_Block128K(uint32_t block_add)   
{   uint32_t tick_start;W25NXX_Write_Enable();	 //Wait for end of earasetick_start = HAL_GetTick();while( W25NXX_get_BUSSY() ){if( HAL_GetTick() - tick_start > W25NXX_TIMOUT ){return 0;}}QSPI_CommandTypeDef cmd = {0};cmd.Instruction = W25NXX_BlockErase;cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;cmd.DummyCycles = 8;cmd.DataMode = QSPI_DATA_1_LINE;cmd.NbData = 2;
//	cmd.Address = block_add;
//	cmd.AddressMode = QSPI_ADDRESS_1_LINE;
//	cmd.AddressSize = QSPI_ADDRESS_16_BITS;uint8_t buff[2];buff[0] = (block_add >> 8)& 0xff;buff[1] = (block_add & 0xff);HAL_QSPI_Command(&hqspi , &cmd , W25NXX_QUAD_TIMEOUT);HAL_QSPI_Transmit(&hqspi ,buff , W25NXX_QUAD_TIMEOUT);//Wait for end of earasetick_start = HAL_GetTick();uint8_t quad_bk1_sr;W25NXX_ReadSR(W25NXX_StatusReg3,& quad_bk1_sr );while( quad_bk1_sr & 0x01 ){W25NXX_ReadSR(W25NXX_StatusReg3,& quad_bk1_sr );if( HAL_GetTick() - tick_start > W25NXX_TIMOUT || (quad_bk1_sr & 0x04) ){return 0;}}HAL_Delay(1);return 1;	
}uint8_t W25NXX_ChipErase(void){for(uint32_t i=0 ; i < W25N01_BlockNum * W25N01_BlockSize ; i += W25N01_BlockSize){//if( W25NXX_Erase_Block128K( i ) == 0) return 0;W25NXX_Erase_Block128K(i) ;}return 1;
}
//Waiting for free
void W25NXX_Wait_Busy(uint8_t blk_no)   
{   while( W25NXX_get_BUSSY() &( 1 << blk_no) );   // Wait for the BUSY bit to clear
}   

“w25n01g.h”

#ifndef __W25NXX_H
#define __W25NXX_H
#include "main.h"   //Instruction list
#define W25NXX_RESET 								0xFF
#define W25NXX_WriteEnable							0x06 
#define W25NXX_WriteDisable							0x04 
#define W25NXX_ReadStatusReg						0x05 
#define W25NXX_WriteStatusReg 				  		0x01
#define W25NXX_StatusReg1 							0xA0
#define W25NXX_StatusReg2 							0xB0
#define W25NXX_StatusReg3 							0xC0
#define W25NXX_LoadProgramData						0x32
#define W25NXX_LoadRandomProgramData				0x34//0x84
#define W25NXX_ProgramExec							0x10
#define W25NXX_PageRead								0x13
#define W25NXX_FastRead								0x6B//0x0B
#define W25NXX_BlockErase							0xD8
#define W25NXX_JedecDeviceID						0x9F #define W25NXX_TIMOUT								5
#define W25NXX_QUAD_TIMEOUT 						10#define W25N01_PageSize								(2048 )
#define W25N01_BlockSize							(64)
#define W25N01_BlockNum								(1024)
#define W25N01_LAST_BLOCK							((W25N01_BlockNum - 1) * W25N01_BlockSize)
#define	W25N01_EraseSize							(64*2048) //128KB#define W25NXX_SectorSize							2048
#define W25NXX_SectorNum							((W25N01_BlockNum * W25N01_BlockSize * W25N01_PageSize)/W25NXX_SectorSize)
#define W25NXX_BlkSecNum							(W25N01_PageSize / W25NXX_SectorSize)
#define W25NXX_EraseSecNum							(W25N01_EraseSize / W25NXX_SectorSize)uint8_t W25NXX_Init(void);					        //Initialize W25NXX
void W25NXX_ReadID(uint32_t * id1);    		        //Read FLASH ID
void W25NXX_ReadSR(uint8_t ADD,uint8_t* SR1);       //Read status register 
void W25NXX_Write_SR(uint8_t ADD,uint8_t sr);       //Write status register
void W25NXX_Write_Enable(void);                     //Write enable 
void W25NXX_Write_Disable(void);                    //Write protection
void W25NXX_Read(uint8_t* pBuffer,uint32_t SectorReadAddr,uint32_t NumByteToRead);          //Read FLASH
uint16_t W25NXX_Read_Page(uint8_t* pBuffer,uint32_t SectorReadAddr,uint32_t NumByteToRead);
void W25NXX_Write(uint8_t* pBuffer,uint32_t SectorWriteAddr,uint32_t NumByteToWrite);       //Write flash
uint16_t W25NXX_Write_Page(uint8_t* pBuffer,uint32_t SectorWriteAddr,uint32_t NumByteToWrite);
uint8_t W25NXX_Erase_Block128K(uint32_t block_add);	    //Sector erase
void W25NXX_Wait_Busy(uint8_t blk_no);        	        //Waiting for chip to be free from erase or write operation
uint8_t W25NXX_ChipErase(void);		                    //erase the entire chip
uint8_t W25NXX_get_BUSSY(void);                         
#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/460744.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode的一些使用心得

问题1&#xff1a;/home目录空间有限 连接wsl或者remote的时候&#xff0c;会在另一端下载一个.vscode-server&#xff0c;vscode的插件都会安装进去&#xff0c;导致空间增加很多&#xff0c;可以选择更换这个文件的位置 参考&#xff1a;https://blog.csdn.net/weixin_4389…

1Panel应用商店开源软件累计下载突破200万次!

2024年10月23日&#xff0c;1Panel应用商店内开源软件累计下载突破200万次。 1Panel&#xff08;github.com/1Panel-dev/1Panel&#xff09;是一款现代化、开源的Linux服务器运维管理面板&#xff0c;它致力于通过开源的方式&#xff0c;帮助用户简化建站与运维管理流程。 为…

基于MATLAB多参数结合火焰识别系统

一、课题介绍 本设计为基于MATLAB的火焰烟雾火灾检测系统。传统的采用颜色的方法&#xff0c;误识别大&#xff0c;局限性强。结合火焰是实时动态跳跃的&#xff0c;采用面积增长率&#xff0c;角点和圆形度三个维度相结合的方式判断是否有火焰。该设计测试对象为视频&#xf…

利用摄像机实时接入分析平台LiteAIServer视频智能分析软件进行视频监控:过亮过暗检测算法详解

视频监控作为一种重要的安全和管理工具&#xff0c;广泛应用于各个领域&#xff0c;如安全监控、交通监管、员工监管、公共场所监控等。然而&#xff0c;在实际应用中&#xff0c;视频监控系统经常面临各种挑战&#xff0c;其中之一便是视频画面过亮或过暗的问题。过亮过暗检测…

python画图|坐标轴比例设置方法

【1】引言 在前序学习进程中&#xff0c;我们通过ax.set_box_aspect()函数掌握了坐标轴等比例设置方法。 担当我在回顾以前的学习文章时&#xff0c;发现ax.axis()函数也可以设置坐标轴比例&#xff0c;比如下述文章&#xff0c;文章可通过点击链接直达&#xff1a; python画…

[前端][基础]JavaScript

1&#xff0c;JavaScript简介 JavaScript 是一门跨平台、面向对象的脚本语言&#xff0c;而Java语言也是跨平台的、面向对象的语言&#xff0c;只不过Java是编译语言&#xff0c;是需要编译成字节码文件才能运行的&#xff1b;JavaScript是脚本语言&#xff0c;不需要编译&…

用于文档理解的局部特征

本文介绍了一种名为DocFormerv2的多模态Transformer模型&#xff0c;它专为视觉文档理解&#xff08;VDU&#xff09;而设计。该模型可以处理视觉、语言和空间特征&#xff0c;利用编码器-解码器架构&#xff0c;并通过不对称地使用新颖的无监督任务进行预训练&#xff0c;以促…

Chromium127编译指南 Linux篇 - 额外环境配置(五)

引言 在成功获取 Chromium 源代码后&#xff0c;接下来我们需要配置适当的编译环境&#xff0c;以便顺利完成开发工作。本文将详细介绍如何设置 Python 和相关的开发工具&#xff0c;以确保编译过程无碍进行。这些配置步骤是开发 Chromium 的必要准备&#xff0c;确保环境设置…

HTTP相关返回值异常原因分析,第二部分

今天我们讲讲HTTP相关返回值异常如何解决&#xff08;实例持续更新中&#xff09; 一、4xx状态码 这些状态码表示请求有问题&#xff0c;通常是由于客户端的错误引起的。 1.1 400 Bad Request: 请求格式不正确&#xff0c;服务器无法理解。 状态码400的含义&#xff1a; …

.NET内网实战:通过白名单文件反序列化漏洞绕过UAC

01阅读须知 此文所节选自小报童《.NET 内网实战攻防》专栏&#xff0c;主要内容有.NET在各个内网渗透阶段与Windows系统交互的方式和技巧&#xff0c;对内网和后渗透感兴趣的朋友们可以订阅该电子报刊&#xff0c;解锁更多的报刊内容。 02基本介绍 03原理分析 在渗透测试和红…

Spring Boot 实现文件分片上传和下载

文章目录 一、原理分析1.1 文件分片1.2 断点续传和断点下载1.2 文件分片下载的 HTTP 参数 二、文件上传功能实现2.1 客户端(前端)2.2 服务端 三、文件下载功能实现3.1 客户端(前端)3.2 服务端 四、功能测试4.1 文件上传功能测试4.2 文件下载功能实现 参考资料 完整案例代码&…

【数据结构】-数组

数组 特点&#xff1a; 数组的地址连续&#xff0c;可以通过下标获取数据。 1. 数组扩容 步骤&#xff1a; $1. 创建一个比原来数组更长的新数组 $2. 让原来数组当中的数据依次复制到新数组当中 $3. 让arr指向新数组&#xff0c;原数组空间释放 2. 数组插入 2.1 最后位置…

智慧小区:科技之光点亮幸福家园

智慧社区的未来发展方向与趋势 从智能化管理到便捷化服务&#xff0c;从环保节能到安全监控&#xff0c;智慧社区正以其前瞻性的视野和创新性的技术&#xff0c;引领着未来城市生活的新方向。从智慧社区的基本概念中通过运用现代科技手段&#xff0c;如物联网、云计算、大数据…

0,国产FPGA(紫光同创)-新建PDS工程

国产FPGA正在蓬勃发展&#xff0c;紫光同创FPGA是大家竞赛时经常遇到的一款国产FPGA&#xff0c;本专栏从IP核开始一直到后续图像处理等。 开发板&#xff1a;盘古50K标准板 1&#xff0c;新建PDS工程 点击File&#xff08;1&#xff09;&#xff0c;然后是New Projects&#…

深入解析Sysmon日志:增强网络安全与威胁应对的关键一环

不断演进的网络安全领域中&#xff0c;保持对威胁的及时了解至关重要。Sysmon日志在这方面发挥了至关重要的作用&#xff0c;通过提供有价值的见解&#xff0c;使组织能够加强其安全姿态。Windows在企业环境中是主导的操作系统&#xff0c;因此深入了解Windows事件日志、它们的…

yocto 下基于SDK的 tcpdump 移植

系列文章目录 【1】yocto系统构建 【2】yocto下mosquitto用户名和密码配置 【3】yocto 下基于SDK的 tcpdump 移植 文章目录 系列文章目录前言一、移植tcpdump的意义二、移植步骤1. 准备Yocto环境2.获取源码&#xff0c;配置和编译3.移植到目标设备4.测试tcpdump 总结 前言 tc…

使用python提取日志里面的role_id、vip字段的值,(vip字段可能为空或者缺失,此时需要给默认值0):

日志样例&#xff1a; 1068 1529597015396 g60-database-380.i.nease.net /home/g60/gamedata/log/g60_GameStatistic_20180622.log 380_game02 G60_GameStatistic 1529596878_35 [2018-06-22 00:01:18][MercLevelUp],{"merc_capacity":2739,"cur_level"…

fastGpt

参考本地部署FastGPT使用在线大语言模型 1 rockylinx 1 ollama安装 在rockylinux中安装的&#xff0c;ollama由1.5G&#xff0c;还是比较大&#xff0c;所有采用在windows下下载&#xff0c;然后安装的方式&#xff0c;linux安装 tar -C /usr -xzf ollama-linux-amd64.tgz #…

记一次踩坑ConcurrentModificationException

这段代码中&#xff0c;oDo 是一个 List 类型的对象&#xff0c;subbedList 是从 oDo 中通过 subList(0, 3) 方法获取的子列表。subList 方法返回的是原列表 oDo 的一个视图&#xff0c;而不是一个独立的列表。这意味着对 subbedList 的任何修改都会反映到 oDo 上&#xff0c;反…