RP2040 C SDK GPIO和IRQ 唤醒功能使用
RP2040 C SDK GPIO和中断功能使用
SIO介绍
- 手册27页:
The Single-cycle IO block (SIO) contains several peripherals that require low-latency, deterministic access from the processors. It is accessed via each processor’s IOPORT: this is an auxiliary bus port on the Cortex-M0+ which can perform rapid 32-bit reads and writes. The SIO has a dedicated bus interface for each processor’s IOPORT, as shown in Figure 7. Processors access their IOPORT with normal load and store instructions, directed to the special IOPORT address segment, 0xd0000000…0xdfffffff. The SIO appears as memory-mapped hardware within the IOPORT space.
单周期IO块(SIO)包含几个外设,它们需要从处理器中进行低延迟的、确定性的访问。它可以通过每个处理器的IOPORT进行访问:这是Cortex-M0+上的一个辅助总线端口,它可以执行快速的32位读取和写操作。SIO为每个处理器的IOPORT都有一个专用的总线接口,如图7所示。处理器使用正常负载和存储指令访问他们的IOPORT,指向特殊的IOPORT地址段0xd0000000…0xdfffffff。SIO显示为IOPORT空间中的内存映射硬件。 - NOTE:The SIO is not connected to the main system bus due to its tight timing requirements. It can only be accessed by the processors, or by the debugger via the processor debug ports.由于其严格的定时要求,SIO没有连接到主系统总线。它只能由处理器或调试器通过处理器调试端口进行访问。
上图.单周期IO块包含记忆映射硬件,处理器必须能够快速访问。FIFOs和自旋锁支持两个核之间的消息传递和同步。共享的GPIO寄存器提供快速和并发的安全的直接访问。一些核心-本地算术硬件可以用来加速处理器上的常见任务。
- 所有的IOPORT读取和写入(因此所有的SIO访问)都在一个周期内发生,这与主AHB-Lite系统总线不同,其中Cortex-M0+需要两个周期来加载或存储,并且由于来自其他系统总线主服务器的争用,可能需要等待更长的时间。这对于像GPIO这样的接口至关重要,它们有严格的时间要求。
- SIO寄存器被映射到0xd0000000…0xd000017c范围内的单词对齐地址。IOPORT空间的其余部分被保留以供将来使用。
- 下面的节将详细描述SIO外围设备。
GPIO控制
处理器可以访问GPIO寄存器,以快速和直接地控制具有GPIO功能的引脚。有两组完全相同的寄存器:
- • GPIO_x for direct control of IO bank 0 (user GPIOs 0 to 29, starting at the LSB)用于直接控制IO组0(用户GPIO0到29,从LSB开始)
- • GPIO_HI_x for direct control of the QSPI IO bank (in the order SCLK, SSn, SD0, SD1, SD2, SD3, starting at the LSB)GPIO_HI_x,用于直接控制QSPI IO库(按SCLK、SSn、SD0、SD1、SD2、SD3,从LSB开始
- NOTE:To drive a pin with the SIO’s GPIO registers, the GPIO multiplexer for this pin must first be configured to select the SIO GPIO function.要使用SIO的GPIO寄存器驱动引脚,必须首先将此引脚的GPIO复用器配置为选择SIO GPIO功能。
- 这些GPIO寄存器在两个核之间共享,并且两个核可以同时访问它们。每个BANK有三个寄存器:
• Output registers,GPIO_OUT
andGPIO_HI_OUT
, are used to set the output level of the GPIO (1/0 for high/low)
• Output enable registers,GPIO_OE
andGPIO_HI_OE
, are used to enable the output driver. 0 for high-impedance, 1
for drive high/low based onGPIO_OUT
andGPIO_HI_OUT.
• Input registers,GPIO_IN
andGPIO_HI_IN
, allow the processor to sample the current state of the GPIOs
📑RP2040 中断功能简介
Each core is equipped with a standard ARM Nested Vectored Interrupt Controller (NVIC) which has 32 interrupt inputs.
Each NVIC has the same interrupts routed to it, with the exception of the GPIO interrupts: there is one GPIO interrupt per bank, per core. These are completely independent, so e.g. core 0 can be interrupted by GPIO 0 in bank 0, and core 1 by GPIO 1 in the same bank.RP2040
由于是双核,每个核心都配备了一个标准的ARM嵌套的向量中断控制器(NVIC),它有32个中断输入。每个NVIC都有相同的中断路由到它,除了GPIO中断:每个库,每个核心都有一个GPIO中断。这些都是完全独立的,例如,核心0可以被bank0中的GPIO 0中断,而核心1可以被同一银行中的GPIO 1中断。
On RP2040, only the lower 26 IRQ signals are connected on the NVIC, and IRQs 26 to 31 are tied to zero (never firing).
The core can still be forced to enter the relevant interrupt handler by writing bits 26 to 31 in the NVIC ISPR register.
- 中断号:
📗GPIO功能
Pads
Each GPIO is connected to the off-chip world via a “pad”. Pads are the electrical interface between the chip’s internal
logic and external circuitry. They translate signal voltage levels, support higher currents and offer some protection
against electrostatic discharge (ESD) events. Pad electrical behaviour can be adjusted to meet the requirements of the
external circuitry. The following adjustments are available:
• Output drive strength can be set to 2mA, 4mA, 8mA or 12mA
• Output slew rate can be set to slow or fast
• Input hysteresis (schmitt trigger mode) can be enabled
• A pull-up or pull-down can be enabled, to set the output signal level when the output driver is disabled
• The input buffer can be disabled, to reduce current consumption when the pad is unused, unconnected or
connected to an analogue signal.
- 📜 GPIO引脚功能配置,枚举类型:
enum gpio_function {GPIO_FUNC_XIP = 0,GPIO_FUNC_SPI = 1,GPIO_FUNC_UART = 2,GPIO_FUNC_I2C = 3,GPIO_FUNC_PWM = 4,GPIO_FUNC_SIO = 5,GPIO_FUNC_PIO0 = 6,GPIO_FUNC_PIO1 = 7,GPIO_FUNC_GPCK = 8,GPIO_FUNC_USB = 9,GPIO_FUNC_NULL = 0x1f,
};
作为外部中断使用,gpio引脚功能配置
GPIO_FUNC_SIO
。
- 🌿gpio功能配置
void gpio_set_function( uint gpio,enum gpio_function fn )
- 🌿gpio输入输出方式,可以配置为输入模式和输出模式。
static inline void gpio_set_dir(uint gpio, bool out)
- 🌿gpio状态,可以配置为上拉、下拉,上下拉都使能。
void gpio_set_pulls(uint gpio, bool up, bool down);
- 🌿gpio输出模式下,可以配置速度:慢和快。电平变化的斜率(压摆率)
void gpio_set_slew_rate ( uint gpio,enum gpio_slew_rate slew )
enum gpio_slew_rate {GPIO_SLEW_RATE_SLOW = 0, ///< Slew rate limiting enabledGPIO_SLEW_RATE_FAST = 1 ///< Slew rate limiting disabled
};
- 🌿gpio对外驱动能力,可配置驱动电流大小:
void gpio_set_drive_strength(uint gpio, enum gpio_drive_strength drive)
/*! \brief Drive strength levels for GPIO outputs* \ingroup hardware_gpio** Drive strength levels for GPIO outputs.* \sa gpio_set_drive_strength*/
enum gpio_drive_strength {GPIO_DRIVE_STRENGTH_2MA = 0, ///< 2 mA nominal drive strengthGPIO_DRIVE_STRENGTH_4MA = 1, ///< 4 mA nominal drive strengthGPIO_DRIVE_STRENGTH_8MA = 2, ///< 8 mA nominal drive strengthGPIO_DRIVE_STRENGTH_12MA = 3 ///< 12 mA nominal drive strength
};
blink点灯程序
#include "pico/stdlib.h"int main() {
#ifndef PICO_DEFAULT_LED_PIN
#warning blink example requires a board with a regular LED
#elseconst uint LED_PIN = PICO_DEFAULT_LED_PIN;gpio_init(LED_PIN);//gpio_set_dir(LED_PIN, GPIO_OUT);while (true) {gpio_put(LED_PIN, 1);sleep_ms(250);gpio_put(LED_PIN, 0);sleep_ms(250);}
#endif
}
- 🌿gpio初始化:
void gpio_init(uint gpio)
void gpio_init(uint gpio) {gpio_set_dir(gpio, GPIO_IN);//输入模式gpio_put(gpio, 0);//设置为低电平gpio_set_function(gpio, GPIO_FUNC_SIO);//SIO模式
}
- 多个gpio初始化操作:
void gpio_init_mask(uint gpio_mask)
- gpio位操作函数:
static inline void gpio_put(uint gpio, bool value);
- 多个gpio位操作
static inline void gpio_put_masked(uint32_t mask, uint32_t value)
gpio_set_mask(1ul << gpio);//置位
sio_hw->gpio_set = 1ul << gpio;//原子操作
gpio_clr_mask(1ul << gpio);//清零
sio_hw->gpio_clr = 1ul << gpio;//原子操作
gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED
sio_hw->gpio_togl = 1ul << gpio;//状态翻转
从上面的函数可以看出,SDK给出了不同封装层的gpio操作方式。
📘GPIO 中断
GPIO中断函数介绍
void gpio_set_irq_enabled_with_callback(uint gpio, uint32_t events, bool enabled, gpio_irq_callback_t callback)
- 第一个形参,引脚号
- 第二个形参事件可以是设定为下面的一种或多种信号作为触发事件:
enum gpio_irq_level {GPIO_IRQ_LEVEL_LOW = 0x1u,GPIO_IRQ_LEVEL_HIGH = 0x2u,GPIO_IRQ_EDGE_FALL = 0x4u,GPIO_IRQ_EDGE_RISE = 0x8u,
};
- 形参三,是irq使能:
irq_set_enabled(IO_IRQ_BANK0, true);
- 形参四,是要执行的回调函数,✨需要注意:该回调函数可以是默认带2个形参的
typedef void (*gpio_irq_callback_t)(uint gpio, uint32_t event_mask);
这2个形参是gpio中断发生时,传递过来的返回值
,记录了gpio中断发生的引脚和触发响应事件,如果传递过来的形参,用不到的话,自己写也可以不带任何形参作为回调函数填进去。形参不可以是void
类型,如果是void
类型那么就相当于带了一个形参,无法通过编译语法✨
👉该gpio中断配置函数的好处就是,在发生gpio中断事件后,不需要手动再去清除中断事件标志位。类似的函数还有 gpio_set_irq_callback
;另外该gpio中断配置函数的好处就是,会自动使能gpio中断配置函数 irq_set_enabled(IO_IRQ_BANK0, true);
(具体看函数方法实现)
static inline void gpio_add_raw_irq_handler(uint gpio, irq_handler_t handler)
:gpio中断回调,在发生gpio中断事件后,需要手动清除标志事件。
- 形参一,配置gpio引脚
- 形参二,回调函数,
typedef void (*irq_handler_t)(void);
✨需要注意形参是void
类型,形参可以是void
类型或者无形参。
✨另外需要注意的是,使用该函数,在产生gpio中断事件时,需要手动清gpio中断事件标志位,void gpio_acknowledge_irq(uint gpio, uint32_t events)
;在配置时,还需要手动使能gpio中断,才能响应gpio中断。手动使能gpio中断: irq_set_enabled(IO_IRQ_BANK0, true);
- 📝SDK给出的例程:
/*** Copyright (c) 2020 Raspberry Pi (Trading) Ltd.** SPDX-License-Identifier: BSD-3-Clause*/#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"static char event_str[128];void gpio_event_string(char *buf, uint32_t events);void gpio_callback(uint gpio, uint32_t events) {//带2个形参// Put the GPIO event(s) that just happened into event_str// so we can print itgpio_event_string(event_str, events);printf("GPIO %d %s\n", gpio, event_str);
}int main() {stdio_init_all();printf("Hello GPIO IRQ\n");gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &gpio_callback);// Wait foreverwhile (1);
}static const char *gpio_irq_str[] = {"LEVEL_LOW", // 0x1"LEVEL_HIGH", // 0x2"EDGE_FALL", // 0x4"EDGE_RISE" // 0x8
};void gpio_event_string(char *buf, uint32_t events) {for (uint i = 0; i < 4; i++) {uint mask = (1 << i);if (events & mask) {// Copy this event string into the user stringconst char *event_str = gpio_irq_str[i];while (*event_str != '\0') {*buf++ = *event_str++;}events &= ~mask;// If more events add ", "if (events) {*buf++ = ',';*buf++ = ' ';}}}*buf++ = '\0';
}
🛠需要手动清除gpio中断标志位配置使用方法
gpio_init(EXT_INT_PIN);// gpio_set_dir(EXT_INT_PIN, GPIO_IN);// sio_hw->gpio_oe_set = mask;gpio_set_input_enabled(EXT_INT_PIN, true);// 单独中断gpio_set_irq_enabled(EXT_INT_PIN, GPIO_IRQ_EDGE_RISE, true);gpio_add_raw_irq_handler(EXT_INT_PIN, my_irq_handler); irq_set_enabled(IO_IRQ_BANK0, true); // 使能中断控制器......void my_irq_handler()
{if (gpio_get_irq_event_mask(EXT_INT_PIN) & GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL){gpio_acknowledge_irq(EXT_INT_PIN, GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL); //clear irq flag// gpio_xor_mask(1<<LED_PIN); // Toggle the LEDprintf("GPIO %d\n", EXT_INT_PIN);}}
📒GPIO中断清标志位自动配置使用
gpio_set_irq_enabled_with_callback(EXT_INT_PIN, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &my_irq_handler); // 复用中断gpio_set_irq_enabled_with_callback(EXT_INT_PIN2, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &my_irq_handler);//gpio_set_irq_callback(&my_irq_handler);
......void my_irq_handler()
{if (gpio_get_irq_event_mask(EXT_INT_PIN) & GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL){// gpio_xor_mask(1<<LED_PIN); // Toggle the LEDprintf("GPIO %d\n", EXT_INT_PIN);// gpio_clear_irq(EXT_INT_PIN);}if (gpio_get_irq_event_mask(EXT_INT_PIN2) & GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL){// gpio_xor_mask(1<<LED_PIN); // Toggle the LEDprintf("GPIO %d \n", EXT_INT_PIN2);}
}
- 👉一般情况下推荐使用
gpio_set_irq_enabled_with_callback
来配置需要的gpio中断,比较省事。在SDK给出的多种API接口函数,需要熟悉各功能函数的使用差异以及注意事项。
📗GPIO 唤醒功能使用
在芯片进入睡眠模式(DORMANT State
)下,gpio可以用作唤醒。
/*CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"-c "program RP2040_Deep_Sleep_Wake.elf verify reset exit"jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg -c "adapter speed 2000" -c "program RP2040_Deep_Sleep_Wake.elf verify reset exit"*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "hardware/gpio.h"
#include "hardware/xosc.h"
#include "pico/multicore.h"
#include "pico/stdio.h"
#include "pico/time.h"#define LED_PIN 25
#define EXT_INT_PIN 5static void measure_freqs(void);void disable_pll() {clock_configure(clk_sys,CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF,0,12 * MHZ,12 * MHZ);
}void enable_pll() {clock_configure(clk_sys,CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,125 * MHZ,125 * MHZ);
}int main() {// stdio_init_all();gpio_init(PICO_DEFAULT_LED_PIN);gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);gpio_put(PICO_DEFAULT_LED_PIN, true);gpio_init(EXT_INT_PIN);gpio_set_dir(EXT_INT_PIN, GPIO_IN);// sio_hw->gpio_oe_set = mask;gpio_set_pulls(EXT_INT_PIN, false, true); // 下拉gpio_set_dormant_irq_enabled(EXT_INT_PIN, IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_LEVEL_HIGH_BITS, true);disable_pll();xosc_dormant(); // WARNING: This stops the xosc until woken up by an irq
// gpio_acknowledge_irq(EXT_INT_PIN, IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_LEVEL_HIGH_BITS);enable_pll();stdio_init_all();while (true) {measure_freqs();gpio_xor_mask(1ul << PICO_DEFAULT_LED_PIN); // Toggle the LEDsleep_ms(1000);// for (uint32_t i=0; i<3; i++) {// gpio_put(PICO_DEFAULT_LED_PIN, false);// sleep_ms(100);// gpio_put(PICO_DEFAULT_LED_PIN, true);// sleep_ms(100);// }}
}static void measure_freqs(void)
{uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);printf("pll_sys = %dkHz\n", f_pll_sys);printf("pll_usb = %dkHz\n", f_pll_usb);printf("rosc = %dkHz\n", f_rosc);printf("clk_sys = %dkHz\n", f_clk_sys);printf("clk_peri = %dkHz\n", f_clk_peri);printf("clk_usb = %dkHz\n", f_clk_usb);printf("clk_adc = %dkHz\n", f_clk_adc);printf("clk_rtc = %dkHz\n", f_clk_rtc);// Can't measure clk_ref / xosc as it is the ref
}
相关文章:

RP2040 C SDK GPIO和IRQ 唤醒功能使用
RP2040 C SDK GPIO和中断功能使用 SIO介绍 手册27页: The Single-cycle IO block (SIO) contains several peripherals that require low-latency, deterministic access from the processors. It is accessed via each processor’s IOPORT: this is an auxiliary…...
@Transactional导致数据库连接数不够
在Spring中进行事务管理非常简单,只需要在方法上加上注解Transactional,Spring就可以自动帮我们进行事务的开启、提交、回滚操作。甚至很多人心里已经将Spring事务Transactional划上了等号,只要有数据库相关操作就直接给方法加上Transactiona…...
python3中的string 和bytes有什么区别
在Python中,string(字符串)和bytes(字节序列)是两种不同的数据类型,分别用于表示文本和二进制数据。它们的主要区别在于存储的数据类型、编码方式以及使用场景。 1. 存储数据类型 string (字符串,str):用来表示文本数据。string是一个Unicode字符串,其中的每个字符是…...

C~排序算法
在C/C中,有多种排序算法可供选择,每种算法都有其特定的应用场景和特点。下面介绍几种常用的排序算法,包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序,并给出相应的示例代码和解释。 冒泡排序(Bubble …...
基于github创建个人主页
基于github创建个人主页 站在巨人的肩膀上,首先选一个创建主页的仓库进行fork,具体可以参照这篇文章https://blog.csdn.net/qd1813100174/article/details/128604858主要总结下需要修改的地方: 1)仓库名字要和github的名字一致&a…...
apt update时出现证书相关问题,可以关闭apt验证
vi /etc/apt/apt.conf.d/99disable-signature-verification 添加以下内容: Acquire::AllowInsecureRepositories "true"; Acquire::AllowDowngradeToInsecureRepositories "true"; Acquire::AllowUnauthenticated "true"; 参考链…...

进阶数据库系列(十三):PostgreSQL 分区分表
概述 在组件开发迭代的过程中,随着使用时间的增加,数据库中的数据量也不断增加,因此数据库查询越来越慢。 通常加速数据库的方法很多,如添加特定的索引,将日志目录换到单独的磁盘分区,调整数据库引擎的参…...

翻译:Recent Event Camera Innovations: A Survey
摘要 基于事件的视觉受到人类视觉系统的启发,提供了变革性的功能,例如低延迟、高动态范围和降低功耗。本文对事件相机进行了全面的调查,并追溯了事件相机的发展历程。它介绍了事件相机的基本原理,将其与传统的帧相机进行了比较&am…...

车载诊断技术:汽车健康的守护者
一、车载诊断技术的发展历程 从最初简单的硬件设备到如今智能化、网络化的系统,车载诊断技术不断演进,为汽车安全和性能提供保障。 早期的汽车诊断检测技术处于比较原始的状态,主要依靠操作经验和主观评价。随着汽车工业的发展,车载诊断技术也经历了不同的阶段。20 世纪初…...

“天翼云息壤杯”高校AI大赛开启:国云的一场“造林”计划
文 | 智能相对论 作者 | 叶远风 2024年年初《政府工作报告》中明确提到了“人工智能”行动,人工智能的发展被提到前所未有的高度。 如何落实AI在数字经济发展中引擎作用,是业界当下面临的课题。 9月25日,“2024年中国国际信息通信展览会”…...
【怎样基于Okhttp3来实现各种各样的远程调用,表单、JSON、文件、文件流等待】
HTTP客户端工具 okhttp3 form/json/multipart 提供表达、json、混合表单、混合表单文件流传输等HTTP请求调用支持自定义配置默认客户端,参数列表如下: okhtt3.config.connectTimeout 连接超时,TimeUnit.SECONDSokhtt3.config.readTimeOut 读…...

excel统计分析(3): 一元线性回归分析
简介 用途:研究两个具有线性关系的变量之间的关系。 一元线性回归分析模型: ab参数由公式可得: 判定系数R2:评估回归模型的拟合效果。值越接近1,说明拟合效果越好;值越接近0,说明拟合效果越…...

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(一)-概述
简介 此前的专栏介绍onesearch1.0和2.0,详情参看4 参考资料,本文解释onesearch 3.0,从Elasticsearch6升级到Elasticsearch8代码实现 ,Elasticsearch8 废弃了high rest client,使用新的ElasticsearchClient,…...

ArcGIS Pro高级地图可视化—双变量符号地图
ArcGIS Pro高级地图可视化 ——双变量符号地图 1 背景 “我不是双变量,但我很好奇。”出自2013 年南卡罗来纳州格林维尔举行的 NACIS 会议上,双变量地图随着这句俏皮的话便跳跃在人们的视角下,在讨论二元映射之后,它不仅恰逢其…...
rust属性宏
1. #[repr(xxx)] repr全称是 “representation”,即表示、展现的意思。在#[repr(u32)]中,u32表示无符号 32 位整数。这意味着被这个属性修饰的类型将以 32 位无符号整数的形式在内存中存储和布局。例如,如果有一个枚举类型被#[repr(u32)]修饰: #[repr(u32)] enum MyEnum {…...

《pyqt+open3d》open3d可视化界面集成到qt中
《pyqtopen3d》open3d可视化界面集成到qt中 一、效果显示二、代码三、资源下载 一、效果显示 二、代码 参考链接 main.py import sys import open3d as o3d from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget from PyQt5.QtGui import QWindow from PyQt5.Qt…...

学习记录:js算法(四十七):相同的树
文章目录 相同的树我的思路网上思路队列序列化方法 总结 相同的树 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 图一: 图二&…...
使用Hutool-poi封装Apache POI进行Excel的上传与下载
介绍 Hutool-poi是针对Apache POI的封装,因此需要用户自行引入POI库,Hutool默认不引入。到目前为止,Hutool-poi支持: Excel文件(xls, xlsx)的读取(ExcelReader)Excel文件(xls&…...

asp.net core grpc快速入门
环境 .net 8 vs2022 创建 gRPC 服务器 一定要勾选Https 安装Nuget包 <PackageReference Include"Google.Protobuf" Version"3.28.2" /> <PackageReference Include"Grpc.AspNetCore" Version"2.66.0" /> <PackageR…...
拿到一个新项目,如何开展测试
1. 拿到一个新的项目或者新的需求,首先需要搞清楚他的背景、目标和需求,这个过程需要和产品、开发、客户去沟通。 2. 清楚需求后,首先将业务流程走通,确保项目的基础功能是正常的 3. 根据项目需求明确测试的目标,如&…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...