AI嵌入式K210项目(11)-SPI Flash读写

文章目录

  • 前言
  • 一、K210的SPI
  • 二、Flash介绍
  • 三、实验过程
  • 总结


前言

这一章我们来学习下SPI及其应用,SPI 是一种高速的,全双工,同步的通信总线,由于其高速、同步和简单的特性,被广泛应用于各种微控制器和外围设备之间的通信场景,如:EEPROM和Flash存储器、实时时钟(RTC)、数模转换器(ADC)、网络控制器、数字信号处理(DSP)、数字信号解码器;

一、K210的SPI

串行外设接口有 4 组 SPI 接口,其中 SPI0、SPI1、SPI3 只能工作在 MASTER 模式,SPI2 只能工作在SLAVE 模式,他们有如下特性:
• 支持 1/2/4/8 线全双工模式
• SPI0、SPI1、SPI2 可支持 25MHz 时钟(待测更新)
• SPI3 最高可支持 100MHz 时钟(待测更新)
• 支持 32 位宽、32BYTE 深的 FIFO
• 独立屏蔽中断 - 主机冲突,发送 FIFO 溢出,发送 FIFO 空,接收 FIFO 满,接收 FIFO 下溢,接收 FIFO 溢出中断都可以被屏蔽独立
• 支持 DMA 功能
• 支持双沿的 DDR 传输模式
• SPI3 支持 XIP

对应的头文件 spi.h
为用户提供以下接口
• spi_init
• spi_init_non_standard
• spi_send_data_standard
• spi_send_data_standard_dma
• spi_receive_data_standard
• spi_receive_data_standard_dma
• spi_send_data_multiple
• spi_send_data_multiple_dma
• spi_receive_data_multiple
• spi_receive_data_multiple_dma
• spi_fill_data_dma
• spi_send_data_normal_dma
• spi_set_clk_rate
• spi_handle_data_dma

二、Flash介绍

FLASH 芯片是应用非常广泛的存储材料,与之对应的是RAM芯片,区别在于FLASH芯片断电后数据可以保存,而RAM芯片断电后数据不会保存。那么FLASH是如何工作的呢?计算机的储存方式是二进制,也就是0和1,在二进制中,0和1可以组成任何数。FLASH芯片对0和1的处理方式是用物质填充,1则填充,0则不填充,如下图所示,这样就算断电之后,物质的性质也不会因为没有电而改变,所以再次读取数据的时候数据依然不变,这样就可以做到断电保存。
在这里插入图片描述
开发板使用的flash芯片GD25LQ128C是通过SPI串行闪存的芯片,具有128M-bit(16兆字节MByte)空间,能够储存声音、文本和数据等,设备运行电源为2.7V~3.6V,低功耗模式电流低至1uA。

写数据,每次向GD25LQ128C写入数据都需要按照页或者扇区或者簇为单位进行,一页为256个字节,一个扇区为4K个字节(16页),一次最多写一页,也就是一次最多写256个字节,如果超过一页数据长度,则分多次完成。

读数据,可以从任何地址读出。

擦除数据,最小单位为一个扇区,也可以直接擦除整个flash芯片。

flash使用的是SPI的通讯方式,所以对应的头文件是spi.h,而由于各家flash芯片存在差异,往往导致适配起来会存在一定问题,所以kendryte官方对市面上常用的flash做了一些库,对应的头文件是w25qxx.h。

为用户提供以下接口:

• w25qxx_init:初始化flash芯片,主要是设置SPI的设备、通道和速率等。

• w25qxx_read_id:读取flash的ID。

• w25qxx_write_data:向flash写入数据。

• w25qxx_read_data:从flash读取数据。
这里可能部分同学会感觉很疑惑,为什么前面提供了SPI的接口,这里又提供了一些那?可以这样理解,这些接口是对上面那么多接口的封装,简化;这些接口最终还是会调用SPI的标准接口,这样做主要目的还是简化开发者的工作量;

硬件连接:
在这里插入图片描述
在这里插入图片描述

三、实验过程

这个实验我们实现对通过SPI接口对flash芯片进行读写操作,新建flash文件夹,新建main.c文件,然后将w25qxx.h和w25qxx.c放进去
w25qxx.c

/* Copyright 2018 Canaan Inc.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
#include "w25qxx.h"
#include "fpioa.h"
#include "spi.h"
#include "sysctl.h"
#include "dmac.h"
#include <string.h>
#include <stdio.h>uint32_t spi_bus_no = 0;
uint32_t spi_chip_select = 0;static w25qxx_status_t w25qxx_receive_data(uint8_t *cmd_buff, uint8_t cmd_len, uint8_t *rx_buff, uint32_t rx_len)
{spi_init(spi_bus_no, SPI_WORK_MODE_0, SPI_FF_STANDARD, DATALENGTH, 0);spi_receive_data_standard(spi_bus_no, spi_chip_select, cmd_buff, cmd_len, rx_buff, rx_len);return W25QXX_OK;
}static w25qxx_status_t w25qxx_send_data(uint8_t *cmd_buff, uint8_t cmd_len, uint8_t *tx_buff, uint32_t tx_len)
{spi_init(spi_bus_no, SPI_WORK_MODE_0, SPI_FF_STANDARD, DATALENGTH, 0);spi_send_data_standard(spi_bus_no, spi_chip_select, cmd_buff, cmd_len, tx_buff, tx_len);return W25QXX_OK;
}static w25qxx_status_t w25qxx_receive_data_enhanced_dma(uint32_t *cmd_buff, uint8_t cmd_len, uint8_t *rx_buff, uint32_t rx_len)
{spi_receive_data_multiple_dma(DMAC_CHANNEL0, DMAC_CHANNEL1, spi_bus_no, spi_chip_select, cmd_buff, cmd_len, rx_buff, rx_len);return W25QXX_OK;
}static w25qxx_status_t w25qxx_send_data_enhanced_dma(uint32_t *cmd_buff, uint8_t cmd_len, uint8_t *tx_buff, uint32_t tx_len)
{spi_send_data_multiple_dma(DMAC_CHANNEL0, spi_bus_no, spi_chip_select, cmd_buff, cmd_len, tx_buff, tx_len);return W25QXX_OK;
}w25qxx_status_t w25qxx_read_id(uint8_t *manuf_id, uint8_t *device_id)
{uint8_t cmd[4] = {READ_ID, 0x00, 0x00, 0x00};uint8_t data[2] = {0};w25qxx_receive_data(cmd, 4, data, 2);*manuf_id = data[0];*device_id = data[1];return W25QXX_OK;
}static w25qxx_status_t w25qxx_write_enable(void)
{uint8_t cmd[1] = {WRITE_ENABLE};w25qxx_send_data(cmd, 1, 0, 0);return W25QXX_OK;
}static w25qxx_status_t w25qxx_write_status_reg(uint8_t reg1_data, uint8_t reg2_data)
{uint8_t cmd[3] = {WRITE_REG1, reg1_data, reg2_data};w25qxx_write_enable();w25qxx_send_data(cmd, 3, 0, 0);return W25QXX_OK;
}static w25qxx_status_t w25qxx_read_status_reg1(uint8_t *reg_data)
{uint8_t cmd[1] = {READ_REG1};uint8_t data[1] = {0};w25qxx_receive_data(cmd, 1, data, 1);*reg_data = data[0];return W25QXX_OK;
}static w25qxx_status_t w25qxx_read_status_reg2(uint8_t *reg_data)
{uint8_t cmd[1] = {READ_REG2};uint8_t data[1] = {0};w25qxx_receive_data(cmd, 1, data, 1);*reg_data = data[0];return W25QXX_OK;
}static w25qxx_status_t w25qxx_enable_quad_mode(void)
{uint8_t reg_data = 0;w25qxx_read_status_reg2(&reg_data);if (!(reg_data & REG2_QUAL_MASK)){reg_data |= REG2_QUAL_MASK;w25qxx_write_status_reg(0x00, reg_data);}return W25QXX_OK;
}static w25qxx_status_t w25qxx_is_busy(void)
{uint8_t status = 0;w25qxx_read_status_reg1(&status);if (status & REG1_BUSY_MASK)return W25QXX_BUSY;return W25QXX_OK;
}w25qxx_status_t w25qxx_sector_erase(uint32_t addr)
{uint8_t cmd[4] = {SECTOR_ERASE};cmd[1] = (uint8_t)(addr >> 16);cmd[2] = (uint8_t)(addr >> 8);cmd[3] = (uint8_t)(addr);w25qxx_write_enable();w25qxx_send_data(cmd, 4, 0, 0);return W25QXX_OK;
}static w25qxx_status_t w25qxx_quad_page_program(uint32_t addr, uint8_t *data_buf, uint32_t length)
{uint32_t cmd[2] = {0};cmd[0] = QUAD_PAGE_PROGRAM;cmd[1] = addr;w25qxx_write_enable();spi_init(spi_bus_no, SPI_WORK_MODE_0, SPI_FF_QUAD, 32/*DATALENGTH*/, 0);spi_init_non_standard(spi_bus_no, 8/*instrction length*/, 24/*address length*/, 0/*wait cycles*/,SPI_AITM_STANDARD/*spi address trans mode*/);w25qxx_send_data_enhanced_dma(cmd, 2, data_buf, length);while (w25qxx_is_busy() == W25QXX_BUSY);return W25QXX_OK;
}static w25qxx_status_t w25qxx_sector_program(uint32_t addr, uint8_t *data_buf)
{uint8_t index = 0;for (index = 0; index < w25qxx_FLASH_PAGE_NUM_PER_SECTOR; index++){w25qxx_quad_page_program(addr, data_buf, w25qxx_FLASH_PAGE_SIZE);addr += w25qxx_FLASH_PAGE_SIZE;data_buf += w25qxx_FLASH_PAGE_SIZE;}return W25QXX_OK;
}w25qxx_status_t w25qxx_write_data(uint32_t addr, uint8_t *data_buf, uint32_t length)
{uint32_t sector_addr = 0;uint32_t sector_offset = 0;uint32_t sector_remain = 0;uint32_t write_len = 0;uint32_t index = 0;uint8_t *pread = NULL;uint8_t *pwrite = NULL;uint8_t swap_buf[w25qxx_FLASH_SECTOR_SIZE] = {0};while (length){sector_addr = addr & (~(w25qxx_FLASH_SECTOR_SIZE - 1));sector_offset = addr & (w25qxx_FLASH_SECTOR_SIZE - 1);sector_remain = w25qxx_FLASH_SECTOR_SIZE - sector_offset;write_len = ((length < sector_remain) ? length : sector_remain);w25qxx_read_data(sector_addr, swap_buf, w25qxx_FLASH_SECTOR_SIZE);pread = swap_buf + sector_offset;pwrite = data_buf;for (index = 0; index < write_len; index++){if ((*pwrite) != ((*pwrite) & (*pread))){w25qxx_sector_erase(sector_addr);while (w25qxx_is_busy() == W25QXX_BUSY);break;}pwrite++;pread++;}if (write_len == w25qxx_FLASH_SECTOR_SIZE){w25qxx_sector_program(sector_addr, data_buf);}else{pread = swap_buf + sector_offset;pwrite = data_buf;for (index = 0; index < write_len; index++)*pread++ = *pwrite++;w25qxx_sector_program(sector_addr, swap_buf);}length -= write_len;addr += write_len;data_buf += write_len;}return W25QXX_OK;
}static w25qxx_status_t _w25qxx_read_data(uint32_t addr, uint8_t *data_buf, uint32_t length)
{uint32_t cmd[2] = {0};cmd[0] = FAST_READ_QUAL_IO;cmd[1] = addr << 8;spi_init(spi_bus_no, SPI_WORK_MODE_0, SPI_FF_QUAD, 32, 0);spi_init_non_standard(spi_bus_no, 8/*instrction length*/, 32/*address length*/, 4/*wait cycles*/,SPI_AITM_ADDR_STANDARD/*spi address trans mode*/);w25qxx_receive_data_enhanced_dma(cmd, 2, data_buf, length);return W25QXX_OK;
}w25qxx_status_t w25qxx_read_data(uint32_t addr, uint8_t *data_buf, uint32_t length)
{uint32_t v_remain = length % 4;if(v_remain != 0){length = length / 4 * 4;}uint32_t len = 0;while (length){len = ((length >= 0x010000) ? 0x010000 : length);_w25qxx_read_data(addr, data_buf, len);addr += len;data_buf += len;length -= len;}if(v_remain){uint8_t v_recv_buf[4];_w25qxx_read_data(addr, v_recv_buf, 4);memcpy(data_buf, v_recv_buf, v_remain);}return W25QXX_OK;
}w25qxx_status_t w25qxx_init(uint8_t spi_index, uint8_t spi_ss, uint32_t rate)
{spi_bus_no = spi_index;spi_chip_select = spi_ss;spi_init(spi_bus_no, SPI_WORK_MODE_0, SPI_FF_STANDARD, DATALENGTH, 0);spi_set_clk_rate(spi_bus_no, rate);w25qxx_enable_quad_mode();return W25QXX_OK;
}

w25qxx.h

/* Copyright 2018 Canaan Inc.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
#ifndef _W25QXX_H
#define _W25QXX_H#include <stdint.h>/* clang-format off */
#define DATALENGTH                          8#define SPI_SLAVE_SELECT                    (0x01)#define w25qxx_FLASH_PAGE_SIZE              256
#define w25qxx_FLASH_SECTOR_SIZE            4096
#define w25qxx_FLASH_PAGE_NUM_PER_SECTOR    16
#define w25qxx_FLASH_CHIP_SIZE              (16777216 UL)#define WRITE_ENABLE                        0x06
#define WRITE_DISABLE                       0x04
#define READ_REG1                           0x05
#define READ_REG2                           0x35
#define READ_REG3                           0x15
#define WRITE_REG1                          0x01
#define WRITE_REG2                          0x31
#define WRITE_REG3                          0x11
#define READ_DATA                           0x03
#define FAST_READ                           0x0B
#define FAST_READ_DUAL_OUTPUT               0x3B
#define FAST_READ_QUAL_OUTPUT               0x6B
#define FAST_READ_DUAL_IO                   0xBB
#define FAST_READ_QUAL_IO                   0xEB
#define DUAL_READ_RESET                     0xFFFF
#define QUAL_READ_RESET                     0xFF
#define PAGE_PROGRAM                        0x02
#define QUAD_PAGE_PROGRAM                   0x32
#define SECTOR_ERASE                        0x20
#define BLOCK_32K_ERASE                     0x52
#define BLOCK_64K_ERASE                     0xD8
#define CHIP_ERASE                          0x60
#define READ_ID                             0x90
#define ENABLE_QPI                          0x38
#define EXIT_QPI                            0xFF
#define ENABLE_RESET                        0x66
#define RESET_DEVICE                        0x99#define REG1_BUSY_MASK                      0x01
#define REG2_QUAL_MASK                      0x02#define LETOBE(x)     ((x >> 24) | ((x & 0x00FF0000) >> 8) | ((x & 0x0000FF00) << 8) | (x << 24))
/* clang-format on *//*** @brief      w25qxx operating status enumerate*/
typedef enum _w25qxx_status
{W25QXX_OK = 0,W25QXX_BUSY,W25QXX_ERROR,
} w25qxx_status_t;/*** @brief      w25qxx read operating enumerate*/
typedef enum _w25qxx_read
{W25QXX_STANDARD = 0,W25QXX_STANDARD_FAST,W25QXX_DUAL,W25QXX_DUAL_FAST,W25QXX_QUAD,W25QXX_QUAD_FAST,
} w25qxx_read_t;w25qxx_status_t w25qxx_init(uint8_t spi_index, uint8_t spi_ss, uint32_t rate);
w25qxx_status_t w25qxx_read_id(uint8_t *manuf_id, uint8_t *device_id);
w25qxx_status_t w25qxx_write_data(uint32_t addr, uint8_t *data_buf, uint32_t length);
w25qxx_status_t w25qxx_read_data(uint32_t addr, uint8_t *data_buf, uint32_t length);#endif

main.c

/**
* @file         main.c
* @brief        flash实验
* @details      
* @par History  见如下说明
*                 
* version:	V1.0: 先向flash写入数据,然后读取出来,对比写入和读取的数据是否一致,
*                 如果不一致则打印错误信息。
*/
#include <stdio.h>
#include "fpioa.h"
#include "sysctl.h"
#include "w25qxx.h"
#include "uarths.h"
#include "spi.h"#define BUF_LENGTH (40 * 1024 + 5)
#define DATA_ADDRESS 0xB00000uint8_t write_buf[BUF_LENGTH];
uint8_t read_buf[BUF_LENGTH];/**
* Function       flash_init
* @brief         flash初始化
* @param[in]     void
* @param[out]    void
* @retval        void
* @par History   无
*/
int flash_init(void)
{uint8_t manuf_id, device_id;uint8_t spi_index = 3, spi_ss = 0;printf("flash init \n");w25qxx_init(spi_index, spi_ss, 60000000);/* 读取flash的ID */w25qxx_read_id(&manuf_id, &device_id);printf("manuf_id:0x%02x, device_id:0x%02x\n", manuf_id, device_id);if ((manuf_id != 0xEF && manuf_id != 0xC8) || (device_id != 0x17 && device_id != 0x16)){/* flash初始化失败 */printf("w25qxx_read_id error\n");printf("manuf_id:0x%02x, device_id:0x%02x\n", manuf_id, device_id);return 0;}else{return 1;} 
}/**
* Function       flash_write_data
* @brief         flash写入数据
* @param[in]     data_buf
* @param[in]     length
* @param[out]    void
* @retval        void
* @par History   无
*/
void flash_write_data(uint8_t *data_buf, uint32_t length)
{uint64_t start = sysctl_get_time_us();/* flash写入数据 */w25qxx_write_data(DATA_ADDRESS, data_buf, length);uint64_t stop = sysctl_get_time_us();/* 打印写入数据的时间(us) */printf("write data finish:%ld us\n", (stop - start));
}/**
* Function       flash_read_data
* @brief         flash读取数据
* @param[in]     data_buf
* @param[in]     length
* @param[out]    void
* @retval        void
* @par History   无
*/
void flash_read_data(uint8_t *data_buf, uint32_t length)
{uint64_t start = sysctl_get_time_us();/* flash读取数据 */w25qxx_read_data(DATA_ADDRESS, data_buf, length);uint64_t stop = sysctl_get_time_us();/* 打印读取数据的时间(us) */printf("read data finish:%ld us\n", (stop - start));
}/**
* Function       main
* @brief         主函数,程序的入口
* @param[in]     void
* @param[out]    void
* @retval        0
* @par History   无
*/
int main(void)
{/* 设置新PLL0频率 */sysctl_pll_set_freq(SYSCTL_PLL0, 800000000);uarths_init();/* 初始化flash */uint8_t res = 0;res = flash_init();if (res == 0) return 0;/* 给缓存写入的数据赋值 */for (int i = 0; i < BUF_LENGTH; i++)write_buf[i] = (uint8_t)(i);/* 清空读取的缓存数据 */for(int i = 0; i < BUF_LENGTH; i++)read_buf[i] = 0;printf("flash start write data\n");/* flash写入数据 */flash_write_data(write_buf, BUF_LENGTH);/*flash读取数据*/flash_read_data(read_buf, BUF_LENGTH);/* 比较数据,如果有不同则打印错误信息 */for (int i = 0; i < BUF_LENGTH; i++){if (read_buf[i] != write_buf[i]){printf("flash read error\n");return 0;}      }printf("spi3 flash master test ok\n");while (1);return 0;
}

代码写好后,我们开始编译,注意:如果你编译过程中出现错误,可以先make clean掉之前生成的过程文件,重新生成

cd build
//注意这里的目标文件目录改成flash,和刚才新建的文件夹名称一致
cmake .. -DPROJ=flash  -G "MinGW Makefiles"
make

编译完成后,在build文件夹下会生成flash.bin文件。

使用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将程序固件烧录到K210开发板上。
在这里插入图片描述

实验结果如下:
该处使用的url网络请求的数据。


总结

本章介绍了SPI相关内容,开发板使用的Flash芯片GD25LQ128C的一款存储空间为16MB的FLASH芯片,总共有4096个扇区,每个扇区有16页,每页是256字节,FLASH是能够断电保存数据的一种储存方式。

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

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

相关文章

微信小程序防止截屏录屏

一、使用css添加水印 使用微信小程序原生的view和css给屏幕添加水印这样可以防止用户将小程序内的隐私数据进行截图或者录屏分享导致信息泄露&#xff0c;给小程序添加一个水印浮层。这样即使被截图或者拍照&#xff0c;也能轻松地确定泄露的源头。效果图如下&#xff1a; 代码…

MongoDB认证考试小题库

Free MongoDB C100DBA Exam Actual Questions 关于MongoDB C100 DBA 考试真题知识点零散整理 分片架构 应用程序 --> mongos --> 多个mongod对于应用来说&#xff0c;连接分片集群跟连接一台单机mongod服务器一样分片好处&#xff0c; 增加可用RAM、增加可用磁盘空间、…

初识 Elasticsearch 应用知识,一文读懂 Elasticsearch 知识文集(3)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

F-44 显示字段调整补充

F-44 显示字段调整补充 网上有段资料清账格式的设置与账号相关&#xff0c;通过此次设置后&#xff0c;下次F-51付款清账时&#xff0c;系统默认按此格式显示。如果在格式设置中找不到适合的格式&#xff0c;用户可以自定义格式&#xff0c;通过事务代码O7Z4S配置行格式&#…

AI对决:ChatGPT与文心一言的比较

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 引言ChatGPT与文心一言的比较Chatgpt的看法文心一言的看法Copilot的观点chatgpt4.0的回答 模型的自我评价自我评价 ChatGPT的优势在这里插入图片描述 文…

利用c 原生头文件完成JPEG全流程编码

骄傲一下&#xff0c;经过一个多月的努力&#xff0c;终于完成jpeg的全套编码。经验证此程序可以把摄像头yuv信号转为JPG图片。现在的程序还不完美&#xff0c;只能对长和宽尺寸是16倍数的信号转码。而且转码速度太慢&#xff0c;一帧1280720的图片要2秒多。此程序只能对yuv420…

Java生成四位数随机验证码

引言&#xff1a; 我们生活中登录的时候都要输入验证码&#xff0c;这些验证码是为了增加注册或者登录难度&#xff0c;减少被人用脚本疯狂登录注册导致的一系列危害&#xff0c;减少数据库的一些压力。 毕竟那些用脚本生成的账号都是垃圾账号 本次实践&#xff1a;生成这样的…

Docker Consul详解与部署示例

目录 Consul构成 Docker Consul 概述 Raft算法 服务注册与发现 健康检查 Key/Value存储 多数据中心 部署模式 consul-template守护进程 registrator容器 consul服务部署&#xff08;192.168.41.31&#xff09; 环境准备 搭建Consul服务 查看集群信息 registrato…

开源协议概览

身为程序员&#xff0c;我们不可避免的要和开源项目打交道&#xff0c;不管是我们自己做了些开源项目&#xff0c;还是使用开源项目&#xff0c;对各种开源协议的了解是必要的。 OSI(Open Source Initiative) OSI&#xff0c;开发源代码组织&#xff0c;是一个旨在推动开源软件…

【河海大学论文LaTeX+VSCode全指南】

河海大学论文LaTeXVSCode全指南 前言一、 LaTeX \LaTeX{} LATE​X的安装二、VScode的安装三、VScode的配置四、验证五、优化 前言 LaTeX \LaTeX{} LATE​X在论文写作方面具有传统Word无法比拟的优点&#xff0c;VScode作为一个轻量化的全功能文本编辑器&#xff0c;由于其极强的…

ZYNQ 7020 PL feature 解读

1. 组成 CLB, RAM, DSP, IO block,XADC, PCI-E, etc 2. CLK Each device in the Zynq-7000 family has up to 8 clock management tiles (CMTs), each consisting of one mixed-mode clock manager (MMCM) and one phase-locked loop (PLL). See Table 5. 2.1, Clock Distri…

记录下载安装rabbitmq(Linux) 并整合springboot--详细版(全)

下载rabbitmq&#xff08;Linux&#xff09;&#xff1a; erlang压缩包&#xff1a; https://share.weiyun.com/TGhfV8eZ rabbitMq-server压缩包&#xff1a; https://share.weiyun.com/ZXbUwWHD &#xff08;因为RabbitMQ采用 Erlang 实现的工业级的消息队列(MQ)服务器&#…

网络安全技术新手入门:利用永恒之蓝获取靶机控制权限

目录 前言 一、搜索永恒之蓝可用模块 二、使用攻击模块 三、配置攻击模块 四、攻击 五、总结 前言 相关法律声明&#xff1a;《中华人民共和国网络安全法》第二十七条 任何个人和组织不得从事非法侵入他人网络、干扰他人网络正常功能、窃取网络数据等危害网络安全的活动&…

element-ui表单验证同时用change与blur一起验证

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 当审批时不通过审批意见要必须输入&#xff0c; 1&#xff1a;如果用change验证的话删除所有内容时报错是massage的提示&#xff0c;但是在失去焦点的时候报错就成了英文&#xff0c;如下图&#xf…

Qt 国产嵌入式操作系统实现文字转语音功能(TTS)

1.简介 本示例使用的CPU&#xff1a;rk3588。 操作系统&#xff1a;kylin V10 架构&#xff1a;aarch64 在Windows端&#xff0c;我们很容易想到使用Qt自带的类QTextToSpeech来实现文字转语音功能&#xff0c;Qt版本得在5.11.0以上才支持。但是在嵌入式平台&#xff0c;尤其…

Matlab数学建模算法之模拟退火算法(SA)详解

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 &#x1f510;#### 防伪水印——左手の明天 ####&#x1f510; &#x1f497; 大家…

STM32之OLED显示

一、模块介绍 1、常见的显示设备 LED、数码管、点阵、LCD屏(1602/12864)、OLED屏(消费电子) 2、OLED屏的概述 OLED&#xff0c;即有机发光二极管&#xff08;Organic Light-Emitting Diode&#xff09;&#xff0c;又称为有机电激光显示&#xff08;Organic Electroluminesenc…

机器学习算法 - 马尔可夫链

马尔可夫链&#xff08;Markov Chain&#xff09;可以说是机器学习和人工智能的基石&#xff0c;在强化学习、自然语言处理、金融领域、天气预测、语音识别方面都有着极其广泛的应用 > The future is independent of the past given the present 未来独立于过去&#xff…

Linux实操学习

Linux常用操作 一、帮助命令1. man1.1 基本语法1.2 快捷键1.3 注意事项 2. help2.1 基本语法2.2 注意事项 3. 常用快捷键 二、文件目录类1. 常规操作1.1 pwd1.2 cd1.3 ls 2. 文件夹操作2.1 mkdir2.2 rmdir 3. 文件操作3.1 touch3.2 cp3.3 rm3.4 mv 4. 文件查看4.1 cat4.2 more4…

四、任意文件读取漏洞

一、介绍 解释&#xff1a;任意文件读取漏洞就其本身来说就是&#xff0c;攻击者绕过网站防御者设置的防御&#xff0c;读取到了正常使用者不应该读取到的内容。网站开发者使用不同的语言&#xff0c;任意文件读取漏洞利用方式就不同。 二、不同开发语言的不同漏洞点 1.PHP …