NRF52832学习笔记(2)—— 添加DFU功能(基于SDK15.3)

2023-11-15

前言

SDK版本15.3

评估板:pca10040

在 uart 的例程中添加 DFU 功能,使用 s132 的协议栈,因为官方的 BootLoader 工程用的是s132的协议栈。

一、准备工作

在开始实验之前必须先准备以下软件:

  • gcc-arm-none-eabi-7-2018-q2-update-win32.exe

由于使用加密的dfu需要用到micro-ecc库进行签名验证,需要micro_ecc_lib_nrf52.lib,而官方的sdk中并没有加入micro_ecc_lib_nrf52.lib,所以需要我们自己编译

直接在官网下载或者用我下载好的,

官网下载地址:https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads 

我下载好的:https://download.csdn.net/download/m_pfly_fish/12152291

15.3的sdk用的是7-2018-q2-update版本的gcc,安装这个版本可以跳过编译micro-ecc库时对Makefile.windows文件的修改。用其他版本的gcc时,需要根据版本修改该文件中的gcc路径和版本信息

  • make-3.81.exe

官网下载地址:http://gnuwin32.sourceforge.net/packages/make.htm

我下好的:https://download.csdn.net/download/m_pfly_fish/12153126

Windows系统的gnu编译器,执行make用

  • micro-ecc-master.zip

官网下载地址:https://github.com/kmackay/micro-ecc

Nordic的DFU中采用了micro-ecc实现ECDSA算法,编译micro_ecc_lib_nrf52.lib时所用到的源码

  • python-2.7.12.amd64.msi

官网下载地址:https://www.python.org/downloads/

我下好的:https://download.csdn.net/download/m_pfly_fish/12153141

nrfutil需要用到python-2.7的环境

  • nRFgo Studio

从官网下就行

我下好的:https://download.csdn.net/download/m_pfly_fish/12051047

主要提供nrfjprog.exe和mergehex.exe。这两个软件在nRFgo Studio的安装目录下找到 C:\Program Files (x86)\Nordic Semiconductor\nrf5x\bin 安装之后用cmd输入nrfjprog和mergehex,查看是否安装可用。

  • oreutils-5.3.0.exe

官网下载地址:http://gnuwin32.sourceforge.net/packages/coreutils.htm

我下好的:https://download.csdn.net/download/m_pfly_fish/12153167

二、软件安装

2.1 双击安装 make-3.81.exe

一直next,注意安装目录使用默认的c盘

2.2 双击安装 coreutils-5.3.0.exe

一直next,注意安装目录使用默认的c盘

2.3 双击安装 gcc-arm-none-eabi-7-2018-q2-update-win32.exe

一直next,注意安装目录使用默认的c盘

安装完成后需要将路径C:\Program Files (x86)\GNU Tools ARM Embedded\7 2018-q2-update\bin;和C:\Program Files (x86)\GnuWin32\bin添加到环境变量Path中

我因为之前还安装了 4.9 2015q3 的 gcc 所以Path中多一个4.9版本的路径

2.4 安装 python-2.7.12.amd64.msi

一直next,注意安装目录使用默认的c盘

安装完毕后,同样需要把python的路径加到环境变量中

添加完成后需要安装 nrfutil

打开 cmd 命令行窗口,跳转至 C:\Python27 目录下,输入python -m pip install nrfutil等待安装完成

三、修改编译BootLoader工程

直接编译sdk中的secure_bootloader工程时会出现以下报错,找不到 uECC.h,micro_ecc_lib_nrf52.lib 和 pk

error:  #5: cannot open source input file "uECC.h": No such file or directory

error: L6002U: Could not open file ..\..\..\..\..\external\micro-ecc\nrf52hf_keil\armgcc\micro_ecc_lib_nrf52.lib: No such file or directory

Error: L6218E: Undefined symbol pk (referred from nrf_dfu_validation.o).

3.1 先解决 缺少 uECC.h 的问题

将下载的 micro-ecc-master.zip 解压后修改文件夹名为 micro-ecc,然后拷贝至 nRF5_SDK_15.3.0_59ac345\external\micro-ecc 目录下

在该文件夹中可以找到 uECC.h

3.2 解决缺少 micro_ecc_lib_nrf52.lib 的问题

如果你使用的是15.3的sdk,并且安装了 gcc-arm-none-eabi-7-2018-q2-update-win32.exe 版本的gcc,那么直接双击运行build_all.bat 脚本就可以自动编译出 micro_ecc_lib_nrf52.lib ,在 nRF5_SDK_15.3.0_59ac345\external\micro-ecc\nrf52hf_keil\armgcc 目录中可以找到  micro_ecc_lib_nrf52.lib

假如使用的不是15.3版本的sdk或者使用的不是 gcc-arm-none-eabi-7-2018-q2-update-win32.exe版本的gcc,那么需要修改 nRF5_SDK_15.3.0_59ac345\components\toolchain\gcc 目录下 Makefile.windows 文件

GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Tools ARM Embedded/7 2018-q2-update/bin/

GNU_VERSION := 7.3.1

GNU_PREFIX := arm-none-eabi

将gcc编译器路径更换为实际路径和实际版本

我使用 4.9 2015q3版本的 gcc 时,将修改 Makefile.windows 文件修改为:

GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q3/bin/

GNU_VERSION := 6.3.0

GNU_PREFIX := arm-none-eabi

3.3 解决缺少 pk 的问题

打开cmd命令行,输入一下指令

nrfutil.exe keys generate private.pem

nrfutil.exe keys display --key pk --format code private.pem --out_file public_key.c 

这样生成的秘钥就保存在 public_key.c中,打开public_key.c。把数组pk复制到报错的位置。

3.4 修改BootLoader工程代码

解决完报错后,BootLoader工程还不能正常工作,需要根据情况修改代码

  • 如果LED灯IO口跟secure_bootloader工程默认引脚不同或原来LED引脚用作其他功能,需要将dfu_observer()函数中LED灯相关代码屏蔽,否则会一直运行在bootloader,不跳转到application

3.5 配置sdk_config文件

将进入DFU方式改为无按键的BLE连接发送命令方式

四、修改Application工程

4.1 配置sdk_config文件

  • 使能 dfu service

  • 修改 VS UUID COUNT 值,因为dfu service使用了 128bit 的自定义的 base uuid,所以这里需要在原先的 count 值上+1

4.2 修改ram空间

因为添加了一个自定义的 base uuid,所以需要修改 ram 空间,每增加一个uuid,IRAM1的起始地址就要增加0x10,size 同时减少0x10。

 

4.3 添加Include目录

  • …/…/…/…/…/…/components/libraries/bootloader
  • …/…/…/…/…/…/components/libraries/bootloader/ble_dfu
  • …/…/…/…/…/…/components/libraries/bootloader/dfu
  • …/…/…/…/…/…/components/libraries/svc

4.4 添加源文件

在工程中增加一个文件夹nRF_DFU,并添加以下文件:

  • \components\ble\ble_services\ble_dfu\ble_dfu.c
  • \components\ble\ble_services\ble_dfu\ble_dfu_bonded.c
  • \components\ble\ble_services\ble_dfu\ble_dfu_unbonded.c

在工程中增加一个文件夹nRF_SVC,并添加以下文件:

  • \components\libraries\bootloader\dfu\nrf_dfu_svci.c

4.5添加宏

添加下列项:

  • NRF_DFU_TRANSPORT_BLE=1
  • BL_SETTINGS_ACCESS_ONLY
  • NRF_DFU_SVCI_ENABLED 

4.6 修改 main.c

添加头文件

#include "nrf_dfu_ble_svci_bond_sharing.h"
#include "nrf_svci_async_function.h"
#include "nrf_svci_async_handler.h"
#include "ble_dfu.h"
#include "nrf_power.h"
#include "nrf_bootloader_info.h"

添加代码

/**@brief Handler for shutdown preparation.
 *
 * @details During shutdown procedures, this function will be called at a 1 second interval
 *          untill the function returns true. When the function returns true, it means that the
 *          app is ready to reset to DFU mode.
 *
 * @param[in]   event   Power manager event.
 *
 * @retval  True if shutdown is allowed by this power manager handler, otherwise false.
 */
static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
{
    switch (event)
    {
        case NRF_PWR_MGMT_EVT_PREPARE_DFU:
            NRF_LOG_INFO("Power management wants to reset to DFU mode.");
            // YOUR_JOB: Get ready to reset into DFU mode
            //
            // If you aren't finished with any ongoing tasks, return "false" to
            // signal to the system that reset is impossible at this stage.
            //
            // Here is an example using a variable to delay resetting the device.
            //
            // if (!m_ready_for_reset)
            // {
            //      return false;
            // }
            // else
            //{
            //
            //    // Device ready to enter
            //    uint32_t err_code;
            //    err_code = sd_softdevice_disable();
            //    APP_ERROR_CHECK(err_code);
            //    err_code = app_timer_stop_all();
            //    APP_ERROR_CHECK(err_code);
            //}
            break;

        default:
            // YOUR_JOB: Implement any of the other events available from the power management module:
            //      -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF
            //      -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP
            //      -NRF_PWR_MGMT_EVT_PREPARE_RESET
            return true;
    }

    NRF_LOG_INFO("Power management allowed to reset to DFU mode.");
    return true;
}

//lint -esym(528, m_app_shutdown_handler)
/**@brief Register application shutdown handler with priority 0.
 */
NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);


static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
{
    if (state == NRF_SDH_EVT_STATE_DISABLED)
    {
        // Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
        nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);

        //Go to system off.
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
    }
}

/* nrf_sdh state observer. */
NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) =
{
    .handler = buttonless_dfu_sdh_state_observer,
};

static void advertising_config_get(ble_adv_modes_config_t * p_config)
{
    memset(p_config, 0, sizeof(ble_adv_modes_config_t));

    p_config->ble_adv_fast_enabled  = true;
    p_config->ble_adv_fast_interval = APP_ADV_INTERVAL;
    p_config->ble_adv_fast_timeout  = APP_ADV_DURATION;
}

static void disconnect(uint16_t conn_handle, void * p_context)
{
    UNUSED_PARAMETER(p_context);

    ret_code_t err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: %d", conn_handle, err_code);
    }
    else
    {
        NRF_LOG_DEBUG("Disconnected connection handle %d", conn_handle);
    }
}

// YOUR_JOB: Update this code if you want to do anything given a DFU event (optional).
/**@brief Function for handling dfu events from the Buttonless Secure DFU service
 *
 * @param[in]   event   Event from the Buttonless Secure DFU service.
 */
static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
{
    switch (event)
    {
        case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
        {
            NRF_LOG_INFO("Device is preparing to enter bootloader mode.");

            // Prevent device from advertising on disconnect.
            ble_adv_modes_config_t config;
            advertising_config_get(&config);
            config.ble_adv_on_disconnect_disabled = true;
            ble_advertising_modes_config_set(&m_advertising, &config);

            // Disconnect all other bonded devices that currently are connected.
            // This is required to receive a service changed indication
            // on bootup after a successful (or aborted) Device Firmware Update.
            uint32_t conn_count = ble_conn_state_for_each_connected(disconnect, NULL);
            NRF_LOG_INFO("Disconnected %d links.", conn_count);
            break;
        }

        case BLE_DFU_EVT_BOOTLOADER_ENTER:
            // YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
            //           by delaying reset by reporting false in app_shutdown_handler
            NRF_LOG_INFO("Device will enter bootloader mode.");
            break;

        case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
            NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously.");
            // YOUR_JOB: Take corrective measures to resolve the issue
            //           like calling APP_ERROR_CHECK to reset the device.
            break;

        case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
            NRF_LOG_ERROR("Request to send a response to client failed.");
            // YOUR_JOB: Take corrective measures to resolve the issue
            //           like calling APP_ERROR_CHECK to reset the device.
            APP_ERROR_CHECK(false);
            break;

        default:
            NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
            break;
    }
}

在 int main(void) 中添加以下代码

    ret_code_t err_code; 

    // Initialize the async SVCI interface to bootloader before any interrupts are enabled.
    err_code = ble_dfu_buttonless_async_svci_init();
    APP_ERROR_CHECK(err_code);

在static void services_init(void)中添加以下代码

    ble_dfu_buttonless_init_t dfus_init = {0};

    dfus_init.evt_handler = ble_dfu_evt_handler;

    err_code = ble_dfu_buttonless_init(&dfus_init);
    APP_ERROR_CHECK(err_code);

五、生成烧录固件

直接烧录softdevice、bootloader和application,会发现application并未运行,芯片一直跑在Bootloader中。

芯片启动后先进入Bootloader,检测Bootloader Settings中的数据,如果这些数据指示Flash中有一个有效的Application,则跳转进入Application。Bootloader Settings是Flash中的一段区域,它包含了Application的大小、CRC等数据,执行DFU时也会在这里存储状态信息。

正常执行DFU时,Bootloader自动生成和维护Bootloader Settings信息。而烧录过程不同,需要手动写入。可以根据application.hex生成一个bl_settings.hex,以产生这些数据,然后烧录这个hex,而我们一般将需要烧录的bl_settings.hex、softdevice、bootloader 和 application 文件合并成一个文件,方便量产烧录

5.1 生成bl_settings.hex

打开cmd命令窗口 输入 nrfutil.exe settings generate --family NRF52 --application nrf52832_xxaa_app.hex --application-version 0 --bootloader-version 0 --bl-settings-version 2 bootloader_settings.hex

application-version、bootloader-version、bl-settings-version 分别是 application 版本号、 bootloader 版本号和 bl-settings版本号,可以自定。

5.2 合并 bl_settings.hex、softdevice、bootloader 和 application 文件

合并 BootLoader 文件和 softdevice 文件:mergehex.exe --merge nrf52832_xxaa_s132_bootloader.hex s132_nrf52_6.1.1_softdevice.hex --output production_final1.hex

合并 application 文件:mergehex.exe --merge production_final1.hex nrf52832_xxaa_app.hex --output production_final2.hex

合并 bl_settings.hex 文件:mergehex.exe --merge production_final2.hex bootloader_settings.hex --output production_final.hex

production_final 文件就是最终烧录固件,通过以下指令可以直接烧录固件至开发板中:

  • nrfjprog -f NRF52 --eraseall
  • nrfjprog -f NRF52 --program "production_final.hex" --verify
  • nrfjprog -f NRF52 --reset

六、打包ota固件

打包OTA所需的zip文件。这里只介绍升级 application 的方法

打开cmd命令窗口 输入 nrfutil pkg generate --hw-version 52 --sd-req 0xB7 --application-version 1 --application nrf52832_xxaa_app.hex --key-file private.pem nrf52832_xxaa_app.zip

其中

--sd-req 0xB7,0xB7 是协议栈版本,查看方式可以用nrf go连接板子后查看

--application-version 1 是 application 版本,自定

--key-file private.pem 是之前编译 bootloader 工程时生成的私钥文件

生成的压缩包就是 ota 文件。

七、OTA操作流程

以下用图片来演示操作 ota 流程

发送df命令,控制设备进入BootLoader

BootLoader模式下的设备名可以在BootLoader工程中进行更改

点击右上dfu按钮进行开始ota

ota完成后,设备会自动重启,跳转至 application

参考

https://blog.csdn.net/qq_36347513/article/details/103744653

https://blog.csdn.net/jdsnpgxj/article/details/80772727

(有空再把dfu的原理总结出来)

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NRF52832学习笔记(2)—— 添加DFU功能(基于SDK15.3) 的相关文章

  • 汇承4.0蓝牙BLE串口助手HC-COM的使用方法及出错的原因和改正方法

    本文主要介绍在使用汇承4 0蓝牙BLE串口助手HC COM xff0c 通过手机向蓝牙模块发送数据 或者通过手机向与蓝牙模块连接的单片机发送指令时 xff0c 串口中断函数的编写方法及出错的原因和改正方法 我们怎么把指令发送出去 xff0c
  • [BLE]低功耗蓝牙之GAP、GATT

    一 开篇 本篇主要介绍一下关于BLE开发过程中必须了解的两个协议 xff1a GAP xff08 通用访问协议 xff09 GATT xff08 通用属性协议 xff09 两个协议都隶属于Host层 xff0c 直接关系到应用层开发 xff
  • BLE Mesh(四)BLE Mesh 安全

    BLE Mesh Security 1 Mesh Security is Mandatory2 Mesh Security Fundamentals3 Separation of Concerns and Mesh Security Key
  • 蓝牙5.1的ble那些事儿

    既然要说5 1的那些事儿 那么必须的聊聊蓝牙4 0 本文就不在此长篇大论班门弄斧了 要了解4 0的同学请出门左拐直接去参考蜗窝科技大佬的文章 本人觉得对于想入门全面了解4 0的同学 此文章是不二选择的经典 在此只有膜拜的份了 不是广告哈哈
  • An Ota Package Tool

    文章目录 OtaPackageToolInstallationBinary InstallationInstalling Tool from Source UsagePreparationExamplesFull UpdatesIncrem
  • nRF52 Mesh开发 (3) MESH Sensor Server/Client Models详解与实现

    MESH Sensor Model 实现 MESH Spec规定的 Sensor Model 标准传感器状态传感器描述传感器参数设置传感器cadence传感器数据 传感器可发送和接收的消息Sensor Server Client Model
  • stm32 esp8266 ota升级-自建mqtt和文件服务器全量升级

    stm32 esp8266 ota系列文章 xff1a stm32 esp8266 ota 快速搭建web服务器之docker安装openresty stm32 esp8266 ota升级 tcp模拟http stm32 esp8266 o
  • ESP32-C3 学习测试 蓝牙 篇(四、GATT Server 示例解析)

    了解了蓝牙 GATT 相关概念 趁热打铁 分析一下官方示例 GATT Server 的应用程序架构 目录 前言 一 GATT Server 示例分析 1 1 初始化 1 2 回调函数 gatts event handler gap even
  • 【BLE】蓝牙抓包器 Ellisys 使用说明

    BLE 蓝牙抓包器 Ellisys 使用说明 常用功能 设备过滤 抓包的类型 添加观察的项目 协议解析 连接过程 Connection Indication LLCP Feature Request Response LLCP Length
  • Dialog DA14585+Sensirion SHT3X+SGP30环境温湿度检测设计

    好记性不如烂笔头 既然不够聪明 就乖乖的做笔记 温故而知新 Phosphor IOT Module是以DA14585作为主控的用于环境监测的评估板 DA14585是符合Bluetooth 5 0标准 16M 32位ARM Cortex M0
  • BLE低功耗的设置参数

    广播间隔 连接间隔 扫描间隔 扫描窗口 广播间隔 两个相邻广播事件之间的时间称为广播间隔 可以选择 20ms 10 28s 不等的间隔 通常 一个广播中的设备会每一秒广播一次 必须是 0 625ms 的整数倍 由于设备间的时钟会不同程度的漂
  • BLE蓝牙协议 — 自适应调频算法简单实现

    写在前面 转载文章 若有不妥 通知后我会立即删除 最近看了大神刘权写的 BLE4 0低功耗蓝牙协议总结 感觉收获颇丰 其中有一节是讲解蓝牙的自适应调频算法的 但是代码实现不方便阅读 原文是这样的 小生不才 斗胆做了一下调整 还望大神海涵 下
  • 使用宏来简化,在Nordic52832 的sdk17.0.2中添加自定义Service和attribute

    sdk17 0 2附带的example中 各种类型和函数等都过度包装了 一个很简单的东西 定义了一层又一层 很容易让人看的头皮发麻 为了降低添加Service和处理各种handler的难度 使用宏来简化添加自定义Service和attrib
  • rk3399 Android9.0 ota升级失败

    rk3399 Android9 0 ota升级失败 问题 在rk3399 Android9 0 项目中需要 ota 功能 user版本编译完ota升级包后 在同版本整包升级时遇到如下问题 抓到的logcat内容如下 1044 2343 D
  • Android - BlueTooth BLE 之 Central 与 Peripheral

    一 前言 Andorid 5 0 之前是无法进行 外围设备开发的 在Android 5 0 API 21 android bluetooth le包下 新增加 Scaner相关类和 Advertiser 相关类 目前最后使用Scanner相
  • ESP32-C3 应用 篇(实例二、通过蓝牙将传感器数据发送给手机,手机端控制 SK6812 LED)

    ESP32 C3 蓝牙部分我们学习了GATT 本文尝试使用蓝牙做一个简单的小应用 目录 前言 一 整体框架 二 数据传输部分 2 1 添加温湿度驱动组件 2 2 传感器数据传输程序 再次说明 ESP GATTS READ EVT 事件 2
  • 蓝牙解析(part7):BLE的连接

    转自Wowo大神的http www wowotech net bluetooth ble connection html 1 前言 了解蓝牙的人都知道 在经典蓝牙中 保持连接 Connection 是一个相当消耗资源 power和带宽 的过
  • Telink BLE MESH开发

    一 前言 官网资料介绍建议采用DMA传输 串口数据的接收是放到了fifo中 但是串口发送也是采用的DMA 问题在于串口发送并没有建立缓冲器 而是判断当前DMA是否忙 如果忙数据直接丢弃 这样做显然不合理 如果发送时DMA忙应该将数据放到缓冲
  • win32下Qt5BLE蓝牙开发笔记

    BLE简介 BLE蓝牙是蓝牙2 0以上的蓝牙模块 经典蓝牙是蓝牙2 0以下的蓝牙 蓝牙分为客户端和服务器两端 经典蓝牙可以通过socket编程进行客户端与服务器之间的通信 与网络socket相似 BLE蓝牙则无法使用这种方式进行通信 BLE
  • 使用 itms-services URL 的 iOS8 应用程序无线 (OTA) 安装失败

    对于所有早期版本的 iOS 我都使用 itms services URL 无线安装测试 iOS 应用程序 OTA 现在 我的所有 iOS8 设备在尝试使用这种方法安装应用程序时都会失败 示例网址 itms services action d

随机推荐

  • xssgame靶场通关记录

    文章目录 靶场地址 第一关 第二关 第三关 第四关 第五关 第六关 第七关 第八关 html编码绕过 第九关 href属性js伪协议 第十关 第十一关 第十二关 第十三关 第十四关 Angular JS 第十五关 url编码 靶场地址 国光
  • UI设计原则背后的认知心理学 优漫动游

    了解人的感官和大脑是如何工作的 去衡量及判断那些设计原则更靠谱 UI设计师需要确定哪个设计原则更适用于给定的环境 从而优选应用 UI设计师必须深思熟虑 而不是盲目的应用设计原则 应该理解其基本原则并有过应用经验的人来使用和诠释 UI设计原则
  • vue3中使用echarts实现自定义纹理3d地图

    效果图 npm下载echarts 在main文件中全局引入 npm install echarts S import as Echarts from echarts app config globalProperties Echarts E
  • 使用htmlWebpackPlugin添加代码版本信息

    不知道你是不是这样的场景哈 或者曾经是 你提交完代码 部署然后测试去测 测试说你这个bug改了吗 怎么还是一样 然后你就纳闷 改过了啊代码也提交了 然后你自己去点一遍验证提交的代码有没有部署上去 这是一个痛点 可能也都习惯了哈 其实 这里有
  • OrCAD Capture学习笔记

    1 OrCAD Capture文件类型 OrCAD Capture是Cadence公司用来进行原理图绘制的一个EDA软件 能用这个软件打开的常用的几个文件后缀名为 dsn opj olb lib net 这些文件后缀具体表示的意思如下 这些
  • php 万能密码,网络安全系列之十 万能密码登录网站后台

    在登录网站后台时 有一个比较古老的 万能密码 漏洞 即利用一个我们精心构造的用户名 即使不用输入密码 也可以登录后台 其原理仍属于SQL注入的范畴 假设数据库中存放用户信息的表是admin 其中存放用户名的字段是username 存放密码的
  • git报错ssh: connect to host github.com port 22: Connection timed out

    碰到了git拉代码时报出的一个错误 通过查阅资料尝试了几种方法之后解决了 在这做个记录 首先需要检查一下SSH是否能够连接成功 输入以下命令 ssh T git github com 若还是报这个错ssh connect to host g
  • Solidity中的pure和view修饰符的区别是什么?什么时候添加pure和view修饰符?

    Solidity是一种用于编写智能合约的编程语言 它被广泛应用于以太坊区块链上的智能合约开发 在Solidity中 有两种函数修饰符 即 pure 和 view 它们被用来指示函数的行为 这篇文章将深入探讨 pure 和 view 的含义
  • PyTorch中使用预训练的模型初始化网络的一部分参数(增减网络层,修改某层参数等) 固定参数

    在预训练网络的基础上 修改部分层得到自己的网络 通常我们需要解决的问题包括 1 从预训练的模型加载参数 2 对新网络两部分设置不同的学习率 主要训练自己添加的层 一 加载参数的方法 加载参数可以参考apaszke推荐的做法 即删除与当前mo
  • 查看 elasticsearch版本号

    查看 elasticsearch版本号 输入命令 curl XGET localhost 9200 得到 name OmUcqLr cluster name elasticsearch cluster uuid AQHIcDW Q9K80U
  • 使用U盘重装MacBook Air时用到的工具和镜像

    主要是工具和镜像 非重装教程 前言 工具 镜像 前言 我之前没接触过苹果笔记本 设备是邻居的白苹果 近期因为双系统中的windows出故障了 所以索性帮他重装 用U盘重装MacBook Air教程网上有一堆 大家应该都能搜索到 主要是工具和
  • aanet

    AANet feature extractor AANetFeature conv1 Sequential 0 Conv2d 3 32 kernel size 7 7 stride 3 3 padding 3 3 bias False 1
  • VSCODE:终端界面简洁化和cmd.exe界面显示

    最近在配置vscode 想用来编写一些c和c 算法文件 编写helloword cpp文件 运行发现程序输出结果显示在终端界面 且含有一长串复杂的无用字符 因此考虑简化这个终端界面 在网上查询了众多教程 大部分都是修改launch json
  • 如何使用 Serverless 做架构和项目管理—— 三年全栈经验总结

    本文是从项目工程角度来讲解的 技术角度请参看另一个文章 真实项目代码教你四步扔了传统服务器 让你优雅使用Serverless做全栈开发 https zhuanlan zhihu com p 本文汇总了我的多个Serverless的全栈项目实
  • [c++]力扣303+304 区域和检索 二维区域和检索

    最近开始重新刷题 从链表开始 第一部分是前缀和 分为一维数组前缀和和高维数组前缀和 abandon 前缀和数组是牺牲空间换时间的方法 为了解决频繁访问数组某区间的问题 先构造出从开始到当前位置的元素的和 储存在前缀和数组中 查询的时候直接查
  • 小波神经网络(WNN)的实现(Python,附源码及数据集)

    文章目录 一 理论基础 1 小波神经网络结构 2 前向传播过程 3 反向传播过程 4 建模步骤 二 小波神经网络的实现 1 训练过程 WNN py 2 测试过程 test py 3 测试结果 4 参考源码及实验数据集 一 理论基础 小波神经
  • Java设计模式-单例模式

    模式定义 确保一个类最多只有一个实例 并提供一个全局访问点 单例模式分为饿汉式和懒汉式 懒汉式单例模式 在类加载时不初始化 饿汉式单例模式 在类加载时就完成了初始化 所以类加载比较慢 但获取对象的速度快 饿汉式 线程安全 饿汉式单例模式 线
  • 2022必备react面试题 附答案

    2022必备react面试题 1 React的严格模式如何使用 有什么用处 StrictMode 是一个用来突出显示应用程序中潜在问题的工具 与 Fragment 一样 StrictMode 不会渲染任何可见的 UI 它为其后代元素触发额外
  • 初学者对java数组中栈和堆的认识

    java数组中栈和堆的认识 1 示例 2 结论 3 图例子 1 示例 public static void main String args String Array null Array new String 3 Array 0 安徽合肥
  • NRF52832学习笔记(2)—— 添加DFU功能(基于SDK15.3)

    前言 SDK版本15 3 评估板 pca10040 在 uart 的例程中添加 DFU 功能 使用 s132 的协议栈 因为官方的 BootLoader 工程用的是s132的协议栈 一 准备工作 在开始实验之前必须先准备以下软件 gcc a