STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入

news2024/11/8 16:42:10

STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入

  • 参考例程
  • 例程说明
  • 一、存储到Flash中的数据
  • 二、Flash最底层操作(解锁,加锁,擦除,读写)
  • 三、从Flash块中读取数据
  • 五、测试验证

参考例程

STM32G0xx HAL和LL库Flash读写擦除操作
STM32G030Cx HAL库Flash擦除或编程操作出错的解决办法

例程说明

1.Flash存储数据采用页分块方式,实现一次擦除多次写入,每块128Byte总共16块,当存满16块后擦除一次
2.将数据写入Flash前,需要前后对比数据,只有数据发生变化才能写入Flash中
3.从Flash读取数据后,进行CRC校验,校验不通过往前继续读取数据,然后重新校验数据
4.将数据写如Flash前需要确保改块都是0xFF,保证写入数据成功

一、存储到Flash中的数据

说明:

  1. Header用来标识存储的头部信息,在Flash读取或写入时用到
  2. ubRes用来作块对齐使用,默认进行128Byte对齐


#define FLASH_STORE_PARM_HEADER_TAG      (0x6C5A)                                             //固定头信息
#define FLASH_STORE_PARM_BLOCK_SIZE      (128)                                                //块大小
#define FLASH_STORE_PARM_BLOCK_COUNT     (u16)(FLASH_PAGE_SIZE / FLASH_STORE_PARM_BLOCK_SIZE) //1页分块的数量

#pragma pack(1)
typedef struct
{
    ............
    ............
}GlobalParamStore, * GlobalParamStore_t;

typedef struct
{
    ............
    ............
}DemarParamStore, * DemarParamStore_t, * pDemarParamStore;

typedef struct
{
    ............
    ............
}ExceptionTrace;

typedef struct
{
    ............
    ............
}ExtraLibPara;

typedef struct
{
    u16 HeaderTag;
    u16 StoreIndex;
}FlashStoreHeader, * FlashStoreHeader_t;

typedef struct
{
    FlashStoreHeader  Header;
    GlobalParamStore  SysPar;
    DemarParamStore   DemarPar;
    ExceptionTrace    ExpTrace;
    ExtraLibPara      ExtLibPar;

    u8 ubRes[16];
    u8 ubCRC8; 
}SystemParamStore, * SystemParamStore_t;
#pragma pack()

二、Flash最底层操作(解锁,加锁,擦除,读写)

说明:

  1. XSUPER_STM32G0_LL_LIB_ENABLE 被使能使用LL库
  2. Flash相关操作失败可多次尝试,尽可能让操作成功


#define FLASH_OPT_OVERTIMER         										(0x1FFFF)
#define FLASH_OPT_TRY_COUNT         										(5)


/* Unlock the FLASH control register access */
static u8 ubFLASH_Unlock(void)
{
    u8 sta = 0;

    if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
    {
        /* Authorize the FLASH Registers access */
        WRITE_REG(FLASH->KEYR, FLASH_KEY1);
        WRITE_REG(FLASH->KEYR, FLASH_KEY2);

        /* verify Flash is unlock */
        if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
        {
            sta = 1;
        }
    }

    return sta;	
}


/* Lock the FLASH control register access */
static u8 ubFLASH_Lock(void)
{
    u8 sta = 1;

    /* Set the LOCK Bit to lock the FLASH Registers access */
    SET_BIT(FLASH->CR, FLASH_CR_LOCK);

    /* verify Flash is locked */
    if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00u)
    {
        sta = 0;
    }

    return sta;
}


/* Gets the page of a given address */
static u32 ulGetPage(u32 startAddr)
{
    return ((startAddr - FLASH_BASE) / FLASH_PAGE_SIZE);
}


/* Erase the specified FLASH memory page */
static u8 ubFLASH_PageErase(u32 page)
{
    u32 tmp  = 0;
    u32 time = 0;
    u8  res  = 0;

    /* Get configuration register, then clear page number */
    tmp = (FLASH->CR & ~FLASH_CR_PNB);

    /* Set page number, Page Erase bit & Start bit */
    FLASH->CR = (tmp | (FLASH_CR_STRT | (page <<  FLASH_CR_PNB_Pos) | FLASH_CR_PER));

    /* wait for BSY1 in order to be sure that flash operation is ended before allowing prefetch in flash */
    while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U)
    {
        if ((++time) > FLASH_OPT_OVERTIMER)
        {
            res = 1;
            break;
        }
    }

    /* If operation is completed or interrupted, disable the Page Erase Bit */
    CLEAR_BIT(FLASH->CR, FLASH_CR_PER);

    return res;
}


/* Program double-word (64-bit) at a specified address */
/* Must EN PG bit before and DIS PG bit after */
static u8 ubFLASH_Program_DoubleWord(u32 addr, u64 data)
{
    u32 time = 0;

	
    /* Wait for last operation to be completed */
    while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U)
    {
        if ((++time) > FLASH_OPT_OVERTIMER)
        {
            return 1;
        }
    }
	
	/* Set PG bit */
	SET_BIT(FLASH->CR, FLASH_CR_PG);

    /* Program first word */
    *(u32 *)addr = (u32)data;

    /* Barrier to ensure programming is performed in 2 steps, in right order
    (independently of compiler optimization behavior) */
    __ISB();

    /* Program second word */
    *(u32 *)(addr + 4U) = (u32)(data >> 32U);

    /* Wait for last operation to be completed */
    while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U)
    {
        if ((++time) > FLASH_OPT_OVERTIMER)
        {
            return 2;
        }
    }

    return 0;
}


/* Wait for a FLASH operation to complete */
static u8 ubFlash_WaitFor_Operate(u32 timeOut)
{
    u32 timer = 0;
    u32 error = 0;

    while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U)
    {
        if ((++timer) >= timeOut)
        {
            return 1;
        }
    }

#if ( XSUPER_STM32G0_LL_LIB_ENABLE > 0)
    /* check flash errors */
    error = (FLASH->SR & FLASH_FLAG_SR_ERROR);

    /* Clear SR register */
    FLASH->SR = FLASH_FLAG_SR_CLEAR;
#endif
    

#if ( XSUPER_STM32G0_HAL_LIB_ENABLE > 0)
    /* check flash errors */
    error = (FLASH->SR & FLASH_SR_ERRORS);

    /* Clear SR register */
    FLASH->SR = FLASH_SR_CLEAR;
#endif

    
    if (error != 0x00U)
    {
        return 2;
    }

    timer = 0;
    while ((FLASH->SR & FLASH_SR_CFGBSY) != 0x00U)
    {
        if ((++timer) > timeOut)
        {
            return 3;
        }
    }

    return 0;
}


/* Read double-word (64-bit) at a specified address */
void vFlash_Read_DoubleWord(u32 startAddr, u64 * pDat, u16 len)
{
    u16 i = 0;

    for(i = 0; i < len; ++i)
    {
        *pDat++ = *(volatile u64 *)(startAddr + (i << 3));
    }
}






static u8 xSuper_Flash_Unlock(void)
{
    u8 tryCount = 0;



    for (tryCount = 0; tryCount < FLASH_OPT_TRY_COUNT; ++tryCount)
    {
        if (!ubFLASH_Unlock()) return 0;
        ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);
    }

    return 1;
}

static u8 xSuper_Flash_Lock(void)
{
    u8 tryCount = 0;

    for (tryCount = 0; tryCount < FLASH_OPT_TRY_COUNT; ++tryCount)
    {
        if (!ubFLASH_Lock()) return 0;
        ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);
    }

    return 1;
}

static u8 xSuper_Flash_EreasePage(u32 startAddr)
{
    u8 tryCount = 0;
    u32 page = ulGetPage(startAddr);

    for (tryCount = 0; tryCount < FLASH_OPT_TRY_COUNT; ++tryCount)
    {
        if (!ubFLASH_PageErase(page)) return 0;
        ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);
    }

    return 1;
}

static u8 xSuper_Flash_Program(u32 startAddr, u64 * pDat, u16 len)
{
    u64 rData = 0;
    u16 i = 0;
    u8 tryCount = 0;

    for (i = 0; i < len; ++i)
    {
        for (tryCount = 0; tryCount < FLASH_OPT_TRY_COUNT; ++tryCount)
        {
            if(!ubFLASH_Program_DoubleWord(startAddr , pDat[i]))
            {
                rData = *(volatile u64 *)(startAddr);
                if (rData != pDat[i])
                {
                    return 1;
                }
                else
                {
                    startAddr += 8;
                    tryCount = 0;
                    break;
                }
            }
            else
            {
                ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);
            }
        }

        if (tryCount) return 2;
    }

    return 0;
}

u8 ubFlash_Write_DoubleWord_EreasePage(u32 startAddr, u64 * pDat, u16 len, u8 mode)
{
    //避免HardFault,三级流水线
    __asm volatile("NOP"); __asm volatile("NOP"); __asm volatile("NOP");
    __DMB(); __DSB(); __ISB();
    __asm volatile("NOP"); __asm volatile("NOP"); __asm volatile("NOP");

    if (xSuper_Flash_Unlock())
    {
        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Flash Unlock Error...\r\n");
        #endif

        return 1;
    }

    if (mode)
    {
        if (xSuper_Flash_EreasePage(startAddr))
        {
            xSuper_Flash_Lock();
            #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
            dprintf("Flash Erease Error...\r\n");
            #endif

            return 2;
        }

        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Flash Erease OK...\r\n");
        #endif
    }
    
    if (xSuper_Flash_Program(startAddr, pDat, len))
    {
        xSuper_Flash_Lock();
        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Flash Program Error...\r\n");
        #endif

        return 3;
    }

    if (xSuper_Flash_Lock())
    {
        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Flash Lock Error...\r\n");
        #endif

        return 4;
    }

    return 0;
}


三、从Flash块中读取数据

  1. vRead_System_Parameter开始打印每个结构体大小,便于调试对齐使用

t/30e0161f1a734f6b96899354ad4e0cd4.png)


/* 获取读Flash块索引 */
static u16 usGet_Flash_Read_Index(void)
{
    u16 dat = 0, i = 0;
    u8  crc = 0;

    for (i = 0; i < FLASH_STORE_PARM_BLOCK_COUNT; ++i)
    {
        dat = *(volatile u16 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * (FLASH_STORE_PARM_BLOCK_COUNT - 1 - i)));
        if (dat == FLASH_STORE_PARM_HEADER_TAG) 
        {
            crc = ubCheckSum_CRC8((void *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * (FLASH_STORE_PARM_BLOCK_COUNT - 1 - i))), XOFS(SystemParamStore , ubCRC8));
            dat = *(volatile u8 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * (FLASH_STORE_PARM_BLOCK_COUNT - 1 - i)) + (FLASH_STORE_PARM_BLOCK_SIZE - 1));
            if (dat == crc)
            {
                return (FLASH_STORE_PARM_BLOCK_COUNT - 1 - i);
            }
        }
    }

    return FLASH_STORE_PARM_BLOCK_COUNT;
}


static void vRead_GlobalSystem_Parameter(void)
{
    u16 index = usGet_Flash_Read_Index();

    if (index < FLASH_STORE_PARM_BLOCK_COUNT)
    {
        /* 读取块内容 */
        vFlash_Read_DoubleWord(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * index), (u64 *)&SystemParam, (FLASH_STORE_PARM_BLOCK_SIZE >> 3));
        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Read Param OK...%u\r\n", SystemParam.Header.StoreIndex);
        #endif
    }
    else
    {
        /* 块索引无效 恢复默认值 */
        vRestoreDefault_GlobalSystemParam();
        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Restore Param...%u\r\n", SystemParam.Header.StoreIndex);
        #endif
    }

    /* 打印块数据 */
    #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
    dprintf("\r\n");
    dprintf("            00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  \r\n");
    dprintf("-------------------------------------------------------------\r\n");
    for (index = 0; index < FLASH_STORE_PARM_BLOCK_SIZE; ++index)
    {
        if (index && (index % 16 == 0)) dprintf("\r\n");
        if (index % 16 == 0) dprintf("0x%08X  ", (SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * SystemParam.Header.StoreIndex) + index));
        dprintf("%02X ", *(volatile u8 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * SystemParam.Header.StoreIndex) + index));
    }
    dprintf("\r\n\r\n");
    #endif
}



void vRead_System_Parameter(void)
{
    #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
    dprintf("Header Size   :%u\r\n", sizeof(FlashStoreHeader));
    dprintf("SysPar Size   :%u\r\n", sizeof(GlobalParamStore));
    dprintf("DemarPar Size :%u\r\n", sizeof(DemarParamStore));
    dprintf("ExpTrace Size :%u\r\n", sizeof(ExceptionTrace));
    dprintf("ExtLibPar Size:%u\r\n", sizeof(ExtraLibPara));
    dprintf("SystemParamStore Size......%u\r\n", sizeof(SystemParamStore));
    if (sizeof(SystemParamStore) != FLASH_STORE_PARM_BLOCK_SIZE) while (1);
    #endif

    vRead_GlobalSystem_Parameter();
}

四、将数据写入Flash块中


static u16 usGet_Flash_Write_Index(void)
{
    u16 dat = 0, i = 0, x = 0;
    u8 uFlg = 0;

    for (i = 0; i < FLASH_STORE_PARM_BLOCK_COUNT; ++i)
    {
        dat = *(volatile u16 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * i));
        if (dat == 0xFFFFU)
        {
            uFlg = 0;
            for (x = 0; x < FLASH_STORE_PARM_BLOCK_SIZE; ++x)
            {
                dat = *(volatile u8 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * i) + x);
                if (dat != 0xFFU)
                {
                    uFlg = 1;
                    break;
                }
            }

            if (!uFlg) 
            {
                return i;
            }
        }
    }

    return FLASH_STORE_PARM_BLOCK_COUNT;
}

static void vSave_GlobalSystem_Parameter(void)
{
    u8 * pSrc = (u8 *)&SystemParam;
    u8   mode = 0, dat = 0;
    u16  index = 0;

    for (index = 0; index < FLASH_STORE_PARM_BLOCK_SIZE; ++index)
    {
        dat = *(volatile u8 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * SystemParam.Header.StoreIndex) + index);
        if (dat != *pSrc++)
        {
            mode = 1;
            break;
        }
    }

    if (!mode)
    {
        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Flash Pram Same...%u\r\n", SystemParam.Header.StoreIndex);
        #endif

        return;
    }

    mode  = 0;
    index = usGet_Flash_Write_Index();
    if (index < FLASH_STORE_PARM_BLOCK_COUNT)
    {
        SystemParam.Header.StoreIndex = index;
    }
    else
    {
        SystemParam.Header.StoreIndex = 0;
        mode = 1;
    }

    SystemParam.ubCRC8 = ubCheckSum_CRC8((void *)(&SystemParam), XOFS(SystemParamStore , ubCRC8));
    if (ubFlash_Write_DoubleWord_EreasePage((SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * SystemParam.Header.StoreIndex)), (u64 *)&SystemParam, (FLASH_STORE_PARM_BLOCK_SIZE >> 3), mode))
    {
        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Flash Write Error...%u\r\n", SystemParam.Header.StoreIndex);
        #endif
    }
    else
    {
        #if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)
        dprintf("Flash Write OK...%u  CRC:%02X\r\n", SystemParam.Header.StoreIndex, SystemParam.ubCRC8);
        #endif
    }
}


void vSave_System_Parameter(void)
{
    vSave_GlobalSystem_Parameter();
}

五、测试验证

只需调用一下函数即可:

从Flash块中读取数据
void vSave_System_Parameter(void)

将数据写入Flash块中
void vRead_System_Parameter(void)


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

若依管理系统使用已有 Nacos 部署流程整理

背景 玩了一下开源项目 RuoYi 管理系统Cloud 版&#xff0c;卡住的地方是&#xff1a;它用到了 nacos 配置管理&#xff0c;如果用的 nacos 环境是单机且是内置数据库的话&#xff0c;该怎么配置呢&#xff1f; 本文整理本机启动 RuoYi Cloud 应用本地部署的过程&#xff0c;…

快速学习Python框架FastAPI

FastAPI是一种现代、快速&#xff08;高性能&#xff09;的Web框架&#xff0c;用于Python 3.6&#xff0c;使用Python类型提示构建API。它的设计初衷是帮助开发者在短时间内开发出高性能的API服务。FastAPI的灵感来源于许多高性能的编程框架&#xff0c;包括Express、Django R…

scala Map集合

一.Map的概述 Map是一种存储键值对的数据结构&#xff0c;Map中的键都是唯一的。 idea实例 二.Map的常见操作 idea实例 三.Map中的查询元素 idea实例 四.Map的常用方法 idea实例 五.Map的遍历 idea实例

Zabbix监控架构

目录 1. Zabbix监控架构-CS架构 2. Zabbix极速上手指南 主机规划 2.1 部署ngxphp环境并测试 检查安装结果 2.2 部署数据库 2.3 编译安装zabbix-server服务端及后续配置 2.4 部署前端代码代码进行访问 前端的配置文件(连接数据库与主机名等信息) 2.5 欢迎来到zabbix 2…

基于vue+neo4j 的中药方剂知识图谱可视化系统

前言 历时一周时间&#xff0c;中药大数据R02系统中药开发完毕&#xff0c;该系统通过scrapy工程获取中药数据&#xff0c;使用python pandas预处理数据生成知识图谱和其他相关数据&#xff0c;利用vuespringbootneo4jmysql 开发系统&#xff0c;具体功能请看本文介绍。 简要…

Java——》try-with-resource

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

数据结构---二叉树(顺序结构),堆(上)

树 树的概念与结构 树是⼀种⾮线性的数据结构&#xff0c;它是由 n&#xff08;n>0&#xff09; 个有限结点组成⼀个具有层次关系的集合。把它叫做树是因为它看起来像⼀棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;⽽叶朝下的。 PS 有⼀个特殊的结点&#xff…

蓝桥杯-网络安全比赛题目-遗漏的压缩包

小蓝同学给你发来了他自己开发的网站链接&#xff0c; 他说他故意留下了一个压缩包文件&#xff0c;里面有网站的源代码&#xff0c; 他想考验一下你的网络安全技能。 &#xff08;点击“下发赛题”后&#xff0c;你将得到一个http链接。如果该链接自动跳转到https&#xff0c;…

HTB:Busqueda[WriteUP]

目录 连接至HTB服务器并启动靶机 使用nmap对靶机进行开放端口扫描 使用ffuf对该域名进行路径FUZZ 直接使用浏览器访问靶机80端口主页面 直接到Github上寻找相关PoC、EXP USER_FLAG&#xff1a;0f2686aebbdb4c728050281a6fb742cf 特权提升 ROOT_FLAG&#xff1a;dde68ef…

如何创建备份设备以简化 SQL Server 备份过程?

SQL Server 中的备份设备是什么&#xff1f; 在 SQL Server 中&#xff0c;备份设备是用于存储备份数据的物理或逻辑介质。备份设备可以是文件、设备或其他存储介质。主要类型包括&#xff1a; 文件备份设备&#xff1a;通常是本地文件系统中的一个或多个文件。可以是 .bak 文…

c语言-8进制的表示方法

文章目录 一、8进制二、输出格式三、范围限制四、八进制的负数五、程序 一、8进制 在C语言中&#xff0c;表示8进制数需要使用前缀数字0&#xff0c;而不是通常的o或者0x. 8进制数以数字0作为前缀&#xff0c;后面跟着一串八进制数字&#xff08;0-7&#xff09;组成&#xf…

python操作MySQL以及SQL综合案例

1.基础使用 学习目标&#xff1a;掌握python执行SQL语句操作MySQL数据库软件 打开cmd下载安装 安装成功 connection就是一个类&#xff0c;conn类对象。 因为位置不知道&#xff0c;所以使用关键字传参。 表明我们可以正常连接到MySQL 演示、执行非查询性质的SQL语句 pytho…

【含开题报告+文档+源码】基于SSM的物流管理系统设计与实现

开题报告 随着电子商务的迅猛发展和人们生活水平的提高&#xff0c;快递服务行业正经历着前所未有的增长。占航快递公司作为国内知名的快递企业之一&#xff0c;面临着巨大的机遇和挑战。传统的快递服务管理方式已经无法满足日益增长的业务需求&#xff0c;快递服务流程中的问…

外包干了2年,快要废了。。。

先说一下自己的情况&#xff0c;普通本科毕业&#xff0c;在外包干了2年多的功能测试&#xff0c;这几年因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不能够在这样蹉跎下去了&#xff0c;长时间呆在一个舒适的环境真的会…

界面控件DevExpress WPF中文教程:Data Grid——卡片视图设置

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

使用Matlab神经网络工具箱

综述 在大数据和人工智能时代&#xff0c;深度学习是一种最为常见的数据分析和拟合工具。本报告以常用分析软件Matlab为例&#xff0c;介绍如何通过编写代码实现一个简单的CNN卷积神经网络。 Step 1: 打开matlab&#xff0c;新建脚本 1、安装matlab 2018以上版本后&#xff…

【系统设计——认证授权——基本概念知识】

1. 认证和授权的区别 Authentication&#xff08;认证&#xff09; 是验证您的身份的凭据&#xff08;例如用户名/用户 ID 和密码&#xff09;&#xff0c;通过这个凭据&#xff0c;系统得以知道你就是你&#xff0c;也就是说系统存在你这个用户。所以&#xff0c;Authenticat…

区块链技术入门:以太坊智能合约详解

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术入门&#xff1a;以太坊智能合约详解 区块链技术入门&#xff1a;以太坊智能合约详解 区块链技术入门&#xff1a;以太…

【Spring】更加简单的将对象存入Spring中并使用

前言 本期讲解&#xff1a;通过Controller、Service、Repository、Component、Configurtion类注解、Bean方法注解&#xff0c;来更加简单的在Spring中存与读对象。 目录 1. 类注解 1.1 通过标签 1.2 使用类注解 1.3 什么是类注解 1.4 获取Bean对象命名问题 2. 方法注解 …

Vue(JavaScript)读取csv表格并求某一列之和(大浮点数处理: decimal.js)

文章目录 想要读这个表格&#xff0c;并且求第二列所有价格的和方法一&#xff1a;通过添加文件输入元素上传csv完整&#xff08;正确&#xff09;代码之前的错误部分因为价格是小数&#xff0c;所以下面的代码出错。如果把parseFloat改成parseInt&#xff0c;那么求和没有意义…