普冉(PUYA)单片机开发笔记(9): FLASH 读写

2023-12-12 01:52

本文主要是介绍普冉(PUYA)单片机开发笔记(9): FLASH 读写,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

单片机的 ROM 容量虽然不大,PY32F003 有 64K 字节的 ROM,但实际应用中会在 MCU 中存储持久化的数据,例如:在物联网应用中,需要把物模型持久化,作为非易失性数据,掉电了也要保存。这就要用到在 FLASH 保存这些数据。

PY32F003 支持 FLASH 读写。

PY32F003 的 FLASH 写入支持“按页写入”、“按扇区写入”和“全部写入”三种方式,实用中常会用到前两种方式。PY32F003 的 FLASH 页(Page)是一块 128 字节的 ROM 区域,可以直接寻址;扇区(Sector)是一块 4096 字节的 ROM 区域,可以直接寻址。

数据手册上列出了 FLASH 的可寻址空间和访问限制(后面有数据手册的截图)。

好啦,干货奉上 ;)

实现代码

老样子,以下几个步骤,就能搞好。

在 main.h 中声明 FLASH 读写的函数

/** ----------------------------------------------------------------------------
* @name   : uint32_t* Flash_Read(void);
* @brief  : 从预设的FLASH地址读取1页(128 Byte)的数据,保存在 data 中
* @param  : None.
* @retval : NULL 或者数据的首地址
* @remark : 
*** ----------------------------------------------------------------------------
*/
uint32_t* Flash_Read(uint16_t* buf_size);/** ----------------------------------------------------------------------------
* @name   : HAL_StatusTypeDef Flash_Write(uint32_t *data);
* @brief  : 从预设的FLASH地址写入1页(128Byte)的数据,data是要写入的数据
* @param  : [in] data: 要写入的数据指针.
* @param  : [in] data_size: 要写入的数据长度
* @retval : HAL_OK: 写入成功; 其它: 错误
* @remark : 上级函数必须检查操作返回值, 只有 HAL_OK 时才是有效数据
*** ----------------------------------------------------------------------------
*/
HAL_StatusTypeDef Flash_Write(uint32_t* data, const uint16_t data_size);

在 app_flash.c 中实现 FLASH 读写的函数

/********************************************************************************* @file    app_flash.c* @brief   Application level Flash read/write/erase codes.******************************************************************************* @attention** Copyright (c) 2023 CuteModem Intelligence.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/#include "main.h"/* 定义用户数据在 FLASH 中存储的首地址, 这里指定了扇区号8, 页号256的首地址 */
#define FLASH_USER_START_ADDR 0x08007000
#define FLASH_USER_BUFF_SIZE  32/* 定义用户数据: 32*4=128 Bytes, 1 page */
uint32_t WD_BUF[FLASH_USER_BUFF_SIZE] = { 0 };
uint32_t RD_BUF[FLASH_USER_BUFF_SIZE] = { 0 };/** ----------------------------------------------------------------------------
* @name   : HAL_StatusTypeDef app_Flash_Erase(void);
* @brief  : 擦除从预设的FLASH地址的1页(128Byte)FLASH
* @param  : None.
* @retval : HAL_StatusTypeDef. 操作成功返回 HAL_OK, 错误返回错误码
* @remark : 上级函数必须检查操作返回值, 只有 HAL_OK 时才能继续操作
*** ----------------------------------------------------------------------------
*/
static HAL_StatusTypeDef app_Flash_Erase(void)
{uint32_t PAGEError = 0;FLASH_EraseInitTypeDef EraseInitStruct;EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGEERASE;        // 擦写类型: 按页擦EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;            // 擦写起始地址EraseInitStruct.NbPages  = sizeof(WD_BUF) / FLASH_PAGE_SIZE;    // 需要擦写的页数量if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)  // 执行page擦除,PAGEError返回擦写错误的page,return HAL_ERROR;                                           // 返回0xFFFFFFFF, 表示擦写成功return HAL_OK;
}/** ----------------------------------------------------------------------------
* @name   : HAL_StatusTypeDef Local_Flash_Check_Blank(void);
* @brief  : 查空 FLASH 中已被擦除的地址
* @param  : None.
* @retval : HAL_StatusTypeDef. 操作成功返回 HAL_OK, 错误返回错误码
* @remark : 上级函数必须检查操作返回值, 只有 HAL_OK 时才能继续操作
*** ----------------------------------------------------------------------------
*/
static HAL_StatusTypeDef Local_Flash_Check_Blank(void)
{uint32_t addr = 0;while (addr < sizeof(WD_BUF)){if (0xFFFFFFFF != HW32_REG(FLASH_USER_START_ADDR + addr))return HAL_ERROR;addr += 4;}return HAL_OK;
}/** ----------------------------------------------------------------------------
* @name   : HAL_StatusTypeDef Local_Flash_Program(void);
* @brief  : 写预设地址的 FLASH
* @param  : None.
* @retval : HAL_StatusTypeDef. 操作成功返回 HAL_OK, 错误返回错误码
* @remark : 上级函数必须检查操作返回值, 只有 HAL_OK 时才能继续操作
*** ----------------------------------------------------------------------------
*/
static HAL_StatusTypeDef Local_Flash_Program(void)
{uint32_t flash_program_start = FLASH_USER_START_ADDR ;                 // flash写起始地址uint32_t flash_program_end = (FLASH_USER_START_ADDR + sizeof(WD_BUF)); // flash写结束地址uint32_t *src = (uint32_t *)WD_BUF;                                    // 数组指针while (flash_program_start < flash_program_end){if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, flash_program_start, src) != HAL_OK){return HAL_ERROR;}flash_program_start += FLASH_PAGE_SIZE; //flash 起始指针指向下一个 pagesrc += FLASH_PAGE_SIZE / 4;             //更新数据指针}return HAL_OK;
}/** ----------------------------------------------------------------------------
* @name   : HAL_StatusTypeDef Flash_Read(void);
* @brief  : 校验预设的FLASH地址开始的1页(128Byte)的数据
* @param  : None.
* @retval : HAL_StatusTypeDef. 操作成功返回 HAL_OK, 错误返回错误码。
* @remark : 上级函数必须检查操作返回值, 只有 HAL_OK 时才是有效数据
*** ----------------------------------------------------------------------------
*/
static HAL_StatusTypeDef Local_Flash_Verify(void)
{uint32_t addr = 0;while (addr < sizeof(WD_BUF)){if (WD_BUF[addr / 4] != HW32_REG(FLASH_USER_START_ADDR + addr)){return HAL_ERROR;}addr += 4;}return HAL_OK;
}/** ----------------------------------------------------------------------------
* @name   : Local_Flash_Print(const uint32_t* data, const uint16_t data_size);
* @brief  : 打印 data_size 个 data
* @param  : None.
* @retval : NULL 或者数据的首地址
* @remark : 
*** ----------------------------------------------------------------------------
*/
static void Local_Flash_Print(const uint32_t* data, const uint16_t data_size)
{printf("%d bytes of data in FLASH:\r\n", data_size*sizeof(uint32_t));for(int i = 0; i < data_size; i++){printf("0x%08X ", data[i]);if((i + 1) % 4 == 0) printf("\r\n");}printf("\r\n");
}/** ----------------------------------------------------------------------------
* @name   : uint32_t* Flash_Read(void);
* @brief  : 从预设的FLASH地址读取1页(128Byte)的数据,保存在 data 中
* @param  : None.
* @retval : NULL 或者数据的首地址
* @remark : 
*** ----------------------------------------------------------------------------
*/
uint32_t* Flash_Read(uint16_t* buf_size)
{uint32_t addr = 0;while (addr < sizeof(RD_BUF)){RD_BUF[addr / 4] = HW32_REG(FLASH_USER_START_ADDR + addr);addr += 4;}*buf_size = FLASH_USER_BUFF_SIZE;Local_Flash_Print((uint32_t*)(&RD_BUF[0]), *buf_size);return (uint32_t*)(&RD_BUF[0]);
}/** ----------------------------------------------------------------------------
* @name   : Flash_Write(uint32_t* data, const uint16_t data_size);
* @brief  : 从预设的FLASH地址写入1页(128Byte)的数据,data是要写入的数据
* @param  : [in] data, 一个 uint32_t 的数据缓冲区的首地址, 128字节
* @retval : HAL_HandleTypeDef. 操作成功返回 HAL_OK, 错误则返回错误码。
* @remark : 上级函数必须检查操作返回值, 只有 HAL_OK 时才是正确的操作
*** ----------------------------------------------------------------------------
*/
HAL_StatusTypeDef Flash_Write(uint32_t* data, const uint16_t data_size)
{HAL_StatusTypeDef res = HAL_BUSY;int i = 0;uint16_t w_size = data_size;if(data_size > FLASH_USER_BUFF_SIZE) w_size = FLASH_USER_BUFF_SIZE;for(i = 0; i < w_size; i++) WD_BUF[i] = data[i];for(i = w_size; i< FLASH_USER_BUFF_SIZE; i++) WD_BUF[i] = 0U;res = HAL_FLASH_Unlock(); // 解锁 FLASHif(res != HAL_OK ) return res;res = app_Flash_Erase();if(res != HAL_OK ) return res;res = Local_Flash_Check_Blank();if(res != HAL_OK ) return res;res = Local_Flash_Program();if(res != HAL_OK ) return res;res = Local_Flash_Verify();if(res != HAL_OK ) return res;res = HAL_FLASH_Lock();   // 锁定 FLASHif(res != HAL_OK ) return res;return HAL_OK;
}

说明:

  1. 参考厂家的数据手册,选择 FLASH 地址空间的最后一个扇区( Sector 8)的第一页作为存储区域。通过 #define FLASH_USER_START_ADDR 0x08007000 进行定义,同时定义 FLASH_USER_BUFF_SIZE 为 32,把这个页占满。
  2. 定义写数据缓冲区(WD_BUF )和读数据缓冲区(RD_BUF)变量,缓冲区长度设置为 128 字节:32 个 uint32_4 类型整数,占用 FLASH 容量等于 32 X 4 = 128。
  3. 完成“擦写”、“查空”、“编程(写入)”和“校验” 4 个函数的编码。
  4. 写了一个测试用的格式化打印函数。以上这五个函数是 FLASH 操作的底层函数,对上级调用 FLASH 读写功能的函数不必可见,因此都定义成了 static 类型。
  5. 完成 Flash_Read 函数。直接访问预定义的 FLASH 内存空间首地址开始的一页数据,存放在缓冲区 RD_BUF 中,Flash_Read 函数返回 RD_BUF 的首地址。
  6. 完成 Flash_Write 函数。FLASH 写的顺序是“解锁 --> 擦除 --> 查空 --> 写入 --> 校验 --> 锁定”,本文采取了全部检查的方式进行写操作,只要中间任何一步出错就返回。如果“信得过” MCU 的话,“查空”这一步可以省区。

在 main.c 中完成调用

/********************************************************************************* @file    main.c* @brief   Main program entry.******************************************************************************* @copyright** Copyright (c) 2023 CuteModem Intelligence.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************//* Private includes*/
#include "main.h"
#include <stdio.h>
/* Private define ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
struct Student_t {uint32_t pri_id;char stu_id[13];char name[25];uint8_t grade;uint8_t class;char performance[17];
};/* Private function prototypes -----------------------------------------------*/
/* Private user code ---------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*//**
* -------------------------------------------------------------------------
* @file   : int main(void)
* @brief  : main函数
* @param  : 无
* @retval : 无限循环,无返回值
* @remark : 
* -------------------------------------------------------------------------
*/
int main(void)
{HAL_Init();             // systick初始化SystemClock_Config();   // 配置系统时钟GPIO_Config();if(USART_Config() != HAL_OK) Error_Handler();         printf("[SYS_INIT] Debug port initilaized.\r\n");printf("\r\n+---------------------------------------+""\r\n|        PY32F003 MCU is ready.         |""\r\n+---------------------------------------+""\r\n         10 digits sent to you!          ""\r\n+---------------------------------------+""\r\n");HAL_Delay(0);if (DBG_UART_Start() != HAL_OK) Error_Handler();HAL_Delay(0);struct Student_t stu1, stu2;uint16_t stu_rec_size = sizeof(stu1);uint16_t data_size = 0;uint32_t* flash_data = Flash_Read(&data_size);stu2 = *((struct Student_t *)flash_data);printf("Previous saved student profile: %d bytes \r\n""  Primary ID = %d\r\n""  Student ID = '%s'\r\n""        Name = '%s'\r\n""       Grade = %d\r\n""       Class = %d\r\n"" Performance = '%s'\r\n", data_size * 4,stu2.pri_id, stu2.stu_id, stu2.name, stu2.grade, stu2.class,stu2.performance);memset(&stu1, 0, sizeof(stu1));stu1.pri_id = 24506;strcpy(stu1.stu_id, "CSTU-2020-02");strcpy(stu1.name, "Zhang Lao 4");stu1.grade = 2;stu1.class = 11;strcpy(stu1.performance,"A+A-B+B++");printf("Current student profile: %d bytes.\r\n"" Primary ID = %d\r\n"" Student ID = '%s'\r\n""       Name = '%s'\r\n""      Grade = %d\r\n""      Class = %d\r\n"" Performance = '%s'\r\n", stu_rec_size,stu1.pri_id, stu1.stu_id, stu1.name, stu1.grade, stu1.class,stu1.performance);if(Flash_Write((uint32_t*)(&stu1), stu_rec_size) != HAL_OK ) {printf("Data updating error.\r\n");Error_Handler();}while (1){ BSP_LED_Toggle(LED3);HAL_Delay(500);}
}/**
* -------------------------------------------------------------------------
* @brief  : void Error_Handler(void)
* @detail : 错误陷阱函数,提示错误,然后死循环
* @param  : 无
* @retval : 无
* @remark : 
* -------------------------------------------------------------------------
*/
void Error_Handler(void)
{Debug_Info("[__ERROR_] System halt.");while (1) {}
}#ifdef USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* User can add his own implementation to report the file name and line number,tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
}
#endif /* USE_FULL_ASSERT */

说明:

  1. 首先定义了一个简单的“学生档案”的结构体,结构体的尺寸不能超过128字节。考虑到可能的“四字节”对齐,这个结构体的尺寸不一定等于各个元素尺寸的算术和,需要使用 sizeof() 运算符事先打印一下这个结构体的尺寸。
  2. 然后是和以前的实验相同的时钟选择、LED 和串口的初始化。
  3. 从 FLASH 中读取上一次写入的数据(uint32_t*),使用强制类型转换,得到学生档案结构体的数据,并打印出来。
  4. 更新这个结构体一些元素的数值,使用强制类型转换,重新写入 FLASH。

实验结果

利用主程序的顺序,用硬代码方式修改第3步的数据,观察打印结果。如果修改了数据,在下一次编译运行时可以看到打印信息的相应变化。连续两次运行,然后 RESET 一次,运行结果如下所示:第二次编译前,将该学生的评分从“A+A-B+B+”修改成了“A+A-B+B++”(多了一个+号),可以看出数据已经更新。

[SYS_INIT] Debug port initilaized.+---------------------------------------+
|        PY32F003 MCU is ready.         |
+---------------------------------------+10 digits sent to you!          
+---------------------------------------+
1234567890
128 bytes of data in FLASH:
0x00005FBA 0x55545343 0x3230322D 0x32302D30 
0x61685A00 0x4C20676E 0x34206F61 0x00000000 
0x00000000 0x00000000 0x0B020000 0x2D412B41 
0x2B422B42 0x00000000 0x00000000 0x00000000 
0x0800331C 0x00000001 0x0800331C 0x08000469 
0x08002852 0x21000000 0x2000032C 0x2000032C 
0x00000040 0x00000000 0x0000015C 0x2000032C 
0x200007F0 0x200007F1 0x00000001 0x08001FE5 Previous saved student profile: 128 bytes Primary ID = 24506Student ID = 'CSTU-2020-02'Name = 'Zhang Lao 4'Grade = 2Class = 11Performance = 'A+A-B+B+'
Current student profile: 64 bytes.Primary ID = 24506Student ID = 'CSTU-2020-02'Name = 'Zhang Lao 4'Grade = 2Class = 11Performance = 'A+A-B+B+'
[SYS_INIT] Debug port initilaized.+---------------------------------------+
|        PY32F003 MCU is ready.         |
+---------------------------------------+10 digits sent to you!          
+---------------------------------------+
1234567890
128 bytes of data in FLASH:
0x00005FBA 0x55545343 0x3230322D 0x32302D30 
0x61685A00 0x4C20676E 0x34206F61 0x00000000 
0x00000000 0x00000000 0x0B020000 0x2D412B41 
0x2B422B42 0x00000000 0x00000000 0x00000000 
0x0800331C 0x00000001 0x0800331C 0x08000469 
0x08002852 0x21000000 0x2000032C 0x2000032C 
0x00000040 0x00000000 0x0000015C 0x2000032C 
0x200007F0 0x200007F1 0x00000001 0x08001FE5 Previous saved student profile: 128 bytes Primary ID = 24506Student ID = 'CSTU-2020-02'Name = 'Zhang Lao 4'Grade = 2Class = 11Performance = 'A+A-B+B+'
Current student profile: 64 bytes.Primary ID = 24506Student ID = 'CSTU-2020-02'Name = 'Zhang Lao 4'Grade = 2Class = 11Performance = 'A+A-B+B++'
[SYS_INIT] Debug port initilaized.+---------------------------------------+
|        PY32F003 MCU is ready.         |
+---------------------------------------+10 digits sent to you!          
+---------------------------------------+
1234567890
128 bytes of data in FLASH:
0x00005FBA 0x55545343 0x3230322D 0x32302D30 
0x61685A00 0x4C20676E 0x34206F61 0x00000000 
0x00000000 0x00000000 0x0B020000 0x2D412B41 
0x2B422B42 0x0000002B 0x00000000 0x00000000 
0x0800331C 0x00000001 0x0800331C 0x08000469 
0x08002852 0x21000000 0x2000032C 0x2000032C 
0x00000040 0x00000000 0x0000015C 0x2000032C 
0x200007F0 0x200007F1 0x00000001 0x08001FE5 Previous saved student profile: 128 bytes Primary ID = 24506Student ID = 'CSTU-2020-02'Name = 'Zhang Lao 4'Grade = 2Class = 11Performance = 'A+A-B+B++'
Current student profile: 64 bytes.Primary ID = 24506Student ID = 'CSTU-2020-02'Name = 'Zhang Lao 4'Grade = 2Class = 11Performance = 'A+A-B+B++'

总结

  • 读写 PY32F003 的 FLASH 很简单,利用 HAL 库,按照规定的顺序(解锁-擦除-查空-写入-校验-锁定)操作即可完成 FLASH 的写入。FLASH 解锁要顺序地使用既定的两个标志字。
// Defined in py32f003x8.h
#define FLASH_KEY1_Msk                    (0x45670123UL << FLASH_KEY1_Pos)     /*!< 0x45670123 */
#define FLASH_KEY1                        FLASH_KEY1_Msk                       /*!< Flash program erase key1 */
#define FLASH_KEY2_Pos                    (0U)
#define FLASH_KEY2_Msk                    (0xCDEF89ABUL << FLASH_KEY2_Pos)     /*!< 0xCDEF89AB */
#define FLASH_KEY2                        FLASH_KEY2_Msk                       /*!< Flash program erase key2: used with FLASH_PEKEY1// Defined in py32f0xx_hal_flash.c
/*** @brief  Unlock the FLASH control register access.* @retval HAL Status*/
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
{HAL_StatusTypeDef status = HAL_OK;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){status = HAL_ERROR;}}return status;
}
  • FLASH 读操作时不需要 Unlock/Lock,可以当作“普通”的内存访问读取 FLASH 相应地址的数据。
#define HW32_REG(ADDRESS) (*((volatile unsigned int *)(ADDRESS)))
  • FLASH 写必须被视为一个完整的过程,五个步骤要完整地、顺序地执行,不能中断,要不的话会导致系统卡死。在主程序的循环中运行 FLASH 写操作时,如果还有其它定时器中断服务程序也要执行 FLASH 写操作的话,要用类似互斥量的方式防止某一个正在进行的 FLASH 写操作的过程被中断(FLASH 读写过程中卡死的情况还是不少的,有兴趣的可以多看一点数据手册的第4章中的内容)。

探索性的开发,差错难免。谬误之处,欢迎在评论区批评指正。

这篇关于普冉(PUYA)单片机开发笔记(9): FLASH 读写的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/482831

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

10. 文件的读写

10.1 文本文件 操作文件三大类: ofstream:写操作ifstream:读操作fstream:读写操作 打开方式解释ios::in为了读文件而打开文件ios::out为了写文件而打开文件,如果当前文件存在则清空当前文件在写入ios::app追加方式写文件ios::trunc如果文件存在先删除,在创建ios::ate打开文件之后令读写位置移至文件尾端ios::binary二进制方式

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。