正点原子嵌入式linux驱动开发——外置RTC芯片PCF8563
上一章学习了STM32MP1内置RTC外设,了解了Linux系统下RTC驱动框架。一般的应用场合使用SOC内置的RTC就可以了,而且成本也低,但是在一些对于时间精度要求比较高的场合,SOC内置的RTC就不适用了。这个时候需要根据自己的应用要求选择合适的外置RTC芯片,正点原子STM32MP1开发板上板载了一个RTC芯片:PCF8563,这是一个IIC接口的外置RTC芯片,本章就来学习一 下如何驱动外置RTC芯片。
PCF8563简介
PCF8563简介
PCF8563是一个CMOS RTC芯片,支持时间和日历功能,支持可编程的时钟输出、中断输出以及低电压检测。PCF8563提供了两线IIC接口来传输时间信息,最大传输速度为400Kbit/S,在读写寄存器的时候地址自增,PCF8563相关特性如下:
- 提供年、月、日、星期,时、分、秒计时,使用外置32.768Khz晶振。
- 低后备电流:0.25uA,VDD=3.0V,温度25℃。
- IIC接口,速度最高400KHz。
- 可编程时钟输出,可以供其他设备使用,可输出的时钟频率有32.768kHz、1.024kHz、32Hz和1Hz。
- 支持闹钟和定时功能。
- IIC读地址为0XA3,写地址为0XA2,也就是IIC器件地址为:0X51。
- 有一个开漏输出的中断引脚。
PCF8563框图如下图所示:
简单分析一下上图中的框图:
- 这是PCF8563的32.768kHz晶振引脚,PCF8563必选要外接32.768kHz晶振。
- 这是PCF8563的IIC引脚,PCF8563通过IIC接口与主控进行通信,因此PCF8563本质是个IIC器件。
- 时钟输出引脚。
- 中断引脚。
- 前面说了,PCF8563是个IIC器件,因此内部就有很多寄存器来实现RTC功能,比如配置芯片,读取时间信息等。这部分就PCF8563的内部寄存器。
PCF8563寄存器详解
PCF8563有16个内部寄存器,这些寄存器都是8位的。前两个寄存器(0x00和0x01)为控
制/状态寄存器。0X02-0X08为时间和日期寄存器,这些寄存器保存着秒、分、时、日、星期、月和年信息。0X09-0X0C为闹钟寄存器,保存闹钟信息。0X0D为时钟输出频率寄存器,0X0E和0X0F这两个寄存器时钟控制寄存器。注意、时分秒、年月日、闹钟等时间信息为BCD格式。
接下来看一下这些寄存器如何使用:
控制状态寄存器1(0X00)
寄存器结构如下图所示:
上图是控制状态寄存器 1,相应的位含义如下:
- TEST1(bit7):0,正常模式;1,测试模式。
- N(bit6,bit4,bit2-0):未使用。
- STOP(bit5):0,RTC时钟运行;1,RTC时钟停止。
- TESTC(bit3):0,正常模式,关闭POR覆写;1,使能POR覆写。
控制状态寄存器2(0X01)
寄存器结构如下图所示:
上图是控制状态寄存器2,相应的位含义如下:
- N(bit7-5):未使用。
- TI_TP(bit4):为0的时候INT引脚取决于TF位,为1的时候INT引脚输出指定频率的脉冲。
- AF(bit3):闹钟标志位,为1的话表示闹钟发生,写0清除,写1无效。
- TF(bit2):定时器标志位,为1的话表示定时发生,写0清除,写1无效。
- AIE(bit1):闹钟中断使能位0,关闭闹钟中断;1,使能闹钟中断。
- TIE(bit0):定时器中断使能位0,关闭定时器中断;1,使能定时器中断。
时间和日期寄存器(0X02-0X08)
接下来看一下时间和日期相关寄存器,一共7个寄存器,结构如下图所示:
依次来看一下上图中的这些寄存器:
- 0X02:此寄存器为秒钟寄存器,PCF8563是有低电压检测的,当VDD电压低于最小允许电压的时候VL(bit)位就会置1,表示时钟异常,如果电压正常的话就为0。SECONDS(bit6-0):这7位表示具体的秒数,范围0~59,为BCD格式。
- 0X03:此寄存器为分钟寄存器,MINUTES(bit6-0)这7位有效,表示具体的分钟数,范围0-59,为BCD格式。
- 0X04:此寄存器为小时寄存器,HOURS(bit5-0)这6位有效,表示具体的小时数,范围0-23,为BCD格式。
- 0X05:此寄存器为日期寄存器,DAYS(bit5-0)这6位有效,表示具体的小时数,范围1-31,为BCD格式。
- 0X06:此寄存器为星期寄存器,WEEKDAYS(bit2-0)这3位有效,表示具体的星期,范围0-6,为BCD格式。0为星期日, ,1为星期一,以此类推,6就是星期六。
- 0X07:此寄存器为月份寄存器,其中C(bit7)为世纪标志位,如果为1的话表示20xx年,为 0的话表示19xx年。MONTHS(bit4-0)这5位有效,表示具体的月份,范围1-12,分别为1-12月,为BCD格式。
- 0X08:此寄存器为年寄存器,YEARS(bit7-0)这8位有效,表示具体的年份,范围0-99。
闹钟寄存器(0X09-0X0C)
接下来看一下闹钟相关寄存器,一共4个寄存器,结构如下图所示:
依次来看一下上图中的这些寄存器:
- 0X09:此寄存器为闹钟分钟寄存器,AE_M(bit7)为分钟闹钟使能位,为0的话使能分钟闹钟,为1的话关闭。MINUTE_ALARM(bit6-0)这7位表示具体的闹钟分钟,范围0-59,为BCD格式。
- 0X0A:此寄存器为闹钟小时寄存器,含义和0X09寄存器类似。
- 0X0B:此寄存器为闹钟日期寄存器,含义和0X09寄存器类似。
- 0X0C:此寄存器为闹钟星期寄存器,含义和0X09寄存器类似。
另外还有时钟输出寄存(0X0D)以及定时器寄存器(0X0E和0X0F),这里不用PFC8563的时钟输出和定时器功能,就不讲解了。
总体来说,PCF8563还是很简单的,这是一个IIC接口的RTC芯片,因此在Linux系统下
就涉及到两类驱动:
- IIC驱动,需要IIC驱动框架来读写PCF8563芯片。
- RTC驱动,因为这是一个RTC芯片,因此要用到RTC驱动框架。
如果要用到中断功能的话,还需要用到Linux系统中的中断子系统,这些前面都有相应的实验讲解。所以PCF8563的Linux驱动并不复杂,而且重点是Linux系统默认就已经集了PCF8563驱动,使用起来非常简单,直接修改设备树,添加PCF8563节点信息,然后使能内核的PCF8563驱动即可。
硬件原理图分析
PCF8563原理图如下图所示:
从上图可以看出,PCF8563连接到了STM32MP157的I2C4接口上,引脚为PZ5、 PZ4。另外, PCF8563的INT引脚连接到了STM32MP157的PI3引脚上。
实验驱动编写
修改设备树
添加/查找PCF8563使用IO的pinmux配置
PCF8563的IIC接口连接到了STM32MP157的I2C4上,对应的引脚为PZ4和PZ5。另外还有一个中断引脚PI3,首先需要在设备树中添加这3个引脚对应的配置信息。
首先添加PZ4和PZ5,打开stm32mp15-pincrtl.dtsi文件,查找一下有没有I2C4的引脚配置信息,默认是有的,内容如下:
示例代码44.3.1.1 i2c4引脚节点
1 i2c4_pins_a: i2c4-0 {
2 pins {
3 pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
4 <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
5 bias-disable;
6 drive-open-drain;
7 slew-rate = <0>;
8 };
9 };
10
11 i2c4_pins_sleep_a: i2c4-1 {
12 pins {
13 pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C4_SCL */
14 <STM32_PINMUX('Z', 5, ANALOG)>; /* I2C4_SDA */
15 };
16 };
从第3、4行可以看出,I2C4默认引脚就是PZ4和PZ5,和本实验一样,所以I2C4的引脚不需要修改,直接使用i2c4_pins_a即可。接下来还需要定义中断引脚PI3的引脚信息,前面讲过了,如果一个引脚作为GPIO功能的话可以不用添加此引脚pinctrl信息。
在I2C4节点下添加pinmux并追加pcf8563子节点
前面说了Linux内核内部已经集成了PCF8563驱动,所以肯定有文档描述如何使用这个驱动。打开Documentation/devicetree/bindings/rtc/pcf8563.txt,此文档描述了如何使用Linux内核自带的pcf8563驱动,也给出了参考设备节点,参考此文档即可。
在stm32mp157d-atk.dts文件,追加I2C4节点,追加如下所示内容:
示例代码 44. 3.1.3 追加 pcf 8563 节点
1 &i2c4 {
2 pinctrl-names = "default", "sleep";
3 pinctrl-0 = <&i2c4_pins_a>;
4 pinctrl-1 = <&i2c4_pins_sleep_a>;
5 status = "okay";
6
7 pcf8563@51{
8 compatible = "nxp,pcf8563";
9 irq_gpio = <&gpioi 3 IRQ_TYPE_EDGE_FALLING>;
10 reg = <0x51>;
11 };
12 };
第2-4行,设置IO要使用的pinmux配置。
第7-10行,pcf8563设备子节点,第8行设置compatible为“nxp,pcf8563”,这个是必须的,否则无法匹配Linux内核自带的pcf8563驱动。从第9行设置pcf8563中断引脚为PI3,下降沿触发。pcf8563的I2C地址为0X51,因此reg为0X51。
PCF8563驱动使能
上一个实验使能了STM32MP157内部RTC,为了防止干扰,所以要先关闭内部RTC!配置路径为:
-> Device Drivers -> Real Time Clock -> STM32 RTC //取消选中 |
如下图所示:
使能Linux内核自带的PCF8563驱动
接下来需要使能Linux内核自带的PCF8563驱动,配置路径如下:
-> Device Drivers -> Real Time Clock -> <*> Philips PCF8563/Epson RTC8564 //选中 PCF8563 |
如下图所示:
配置完成后重新编译内核和设备树,得到新的uImage以及stm32mp157d-atk.dtb。
运行测试
使用上面编译得到的内核和设备树启动开发板。当系统第一次启动,没有设置PCF8563时间的时候,启动过程会提示如下图所示信息:
从上图可以看出,系统已经识别出了PCF8563,说明驱动没问题。但是,这里提示检测到低电压,日期和时间无效。这是因为没有设置时间,等系统启动成功,然后参考上一篇笔记内部RTC的设置方法设置RTC时间,比如这里设置时间为2021年5月21号,下午15:52:00,输入如下命令:
date -s "2021-05-21 15:52:00" //设置时间 hwclock -w //保存 |
时间设置好以后重启系统,此时系统log信息如下图所示:
从上图可以看出,此时PCF8563再没有提示电压低的错误,而且正确的读出了时间信
息,整个开发板掉电以后PCF8563也会继续计时,因为有一个纽扣电池供电。
PCF8563驱动分析
上一小节已经测试了PCF8563,本小节来简单看一下PCF8563驱动源码,根据示例代码44.3.1.3中的第8行的compatible属性值可以找到对应到驱动文件,在Linux源码中搜索字符串“nxp,pcf8563”即可找到对应的驱动文件,驱动文件为drivers/rtc/rtc-pcf8563.c。
PCF8563是个I2C器件,因此基础驱动框架是I2C,在rtc-pcf8563.c文件中找到如下所示内容:
上述示例代码就是个标准的I2C驱动框架,第9-14行的pcf8563_of_match结构体数组就是设备树匹配数组,第10行的compatible属性为“nxp,pcf8563”,和设备树相匹配。匹配以后第23行的pcf8563_probe函数就会执行。
接下来看一下pcf8563_probe函数,函数源码如下(有缩略):
示例代码44.5.2 pcf8563_probe 函数
1 static int pcf8563_probe(struct i2c_client *client,
2 const struct i2c_device_id *id)
3 {
4 struct pcf8563 *pcf8563;
5 int err;
6 unsigned char buf;
......
13 pcf8563 = devm_kzalloc(&client->dev, sizeof(struct pcf8563),
14 GFP_KERNEL);
15 if (!pcf8563)
16 return -ENOMEM;
17
18 i2c_set_clientdata(client, pcf8563);
19 pcf8563->client = client;
20 device_set_wakeup_capable(&client->dev, 1);
21
22 /* Set timer to lowest frequency to save power */
23 buf = PCF8563_TMRC_1_60;
24 err = pcf8563_write_block_data(client, PCF8563_REG_TMRC, 1, &buf);
25 if (err < 0) {
26 dev_err(&client->dev, "%s: write error\n", __func__);
27 return err;
28 }
29
30 /* Clear flags and disable interrupts */
31 buf = 0;
32 err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, &buf);
33 if (err < 0) {
34 dev_err(&client->dev, "%s: write error\n", __func__);
35 return err;
36 }
37
38 pcf8563->rtc = devm_rtc_allocate_device(&client->dev);
39 if (IS_ERR(pcf8563->rtc))
40 return PTR_ERR(pcf8563->rtc);
41
42 pcf8563->rtc->ops = &pcf8563_rtc_ops;
43 /* the pcf8563 alarm only supports a minute accuracy */
44 pcf8563->rtc->uie_unsupported = 1;
45 pcf8563->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
46 pcf8563->rtc->range_max = RTC_TIMESTAMP_END_2099;
47 pcf8563->rtc->set_start_time = true;
48
49 if (client->irq > 0) {
50 err = devm_request_threaded_irq(&client->dev, client->irq,
51 NULL, pcf8563_irq,
52 IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW,
53 pcf8563_driver.driver.name, client);
54 if (err) {
55 dev_err(&client->dev, "unable to request IRQ %d\n",
56 client->irq);
57 return err;
58 }
59 }
60
61 err = rtc_register_device(pcf8563->rtc);
62 if (err)
63 return err;
......
70 return 0;
71 }
第13行,申请内存内存,rtc-pcf8563.c定义了一个pcf8563结构体来描述PCF8563芯片,所以这里就是申请一个pcf8563实例。
第23-36行,初始化PCF8563。
第38行,pcf8563结构体里面有个rtc成员变量,此成员变量是个rtc_device结构体指针。
这个就是上一章讲解的RTC驱动框架最核心的rtc_device。这里需要对这个rtc指针分配内存。
第42行,设置rtc_device的ops成员变量为pcf8563_rtc_ops,pcf8563_rtc_ops包含了PCF8563的具体操作,包括设置时间、读取时间、设置闹钟等。
第44-47行,继续初始化rtc的其他成员变量。
第49-59行,中断初始化,PCF8563有个中断引脚INT,因此可以使用中断功能。这里使用devm_request_threaded_irq函数完成中断申请已经初始化,中断函数为pcf8563_irq。
第61行,调用rtc_register_device函数向系统注册rtc_device,也就是pcf8563。
总结 一下,pcf8563_probe函数的核心就是初始化PCF8563,然后使用上一章讲的RTC驱动框架来设置PCF8563,然后向内核注册。
接下来看一下PCF8563的核心:pcf8563_rtc_ops,内容如下:
pcf8563_rtc_ops提供了PCF8563的时间以及闹钟读写操作函数,应用程序对PCF8563的所有操作最终都是通过这些函数来完成的。以读时间为例,当应用程序读取PCF8563当前时间的时候,.read_time就会执行,在这里就是pcf8563_rtc_read_time,函数源码如下(有省略):
第8行,使用pcf8563_read_block_data函数从PCF8563_REG_ST1寄存器(地址为0X00)开始,连续读取9个寄存器的数据。这样就可以得到PCF8563的控制与状态寄存器1和2,以及事件与日期寄存器的值。
第12行,判断PCF8563的0X02寄存器VL位是否为1,也就是检查PCF8563是否处于低电压模式,事件和日期是否有效。
第28-34行,依次获取PCF8563中的时间和日期值,这里使用bcd2bin函数将原始的BCD值转换为时间值。将获取到的时间和日期打包到参数tm中,tm是个rtc_time结构体指针变量。
第36行,判断0X07寄存器的C位(bit7)的值,此位为1的话表示20xx年,为0的话就是19xx年。
可以看出pcf8563_rtc_read_time函数很简单,就是读取PCF8563内部的时间和日期值,然后将其打包进rtc_time里面。其他的函数大同小异,可以自行分析一下。
至此,PCF8563驱动就简单分析完成了,其他IIC接口的RTC芯片驱动基本都是类似的,可以在实际项目开发中选择合适的RTC芯片。
总结
这里的驱动PCF8563还是比较简单的,因为Linux内核是已经写好了相关驱动的,只要自己在Linux内核配置开启,然后在设备树中添加相应的对应的i2c节点以及GPIO对应的子节点就可以使用了。
相关文章:

正点原子嵌入式linux驱动开发——外置RTC芯片PCF8563
上一章学习了STM32MP1内置RTC外设,了解了Linux系统下RTC驱动框架。一般的应用场合使用SOC内置的RTC就可以了,而且成本也低,但是在一些对于时间精度要求比较高的场合,SOC内置的RTC就不适用了。这个时候需要根据自己的应用要求选择合…...
自动驾驶感知算法面经(20+)
原文链接: https://zhuanlan.zhihu.com/p/656952371 本人2022年4月和2023年7月两次跳槽找工作,面经总结在这里,希望可以帮到需要的朋友。 项目相关的问题主要和经历有关,参考性不大。 2023年7月 1. 文远知行 自动标注算法岗位 项目经历问…...

计算机操作系统重点概念整理-第二章 进程管理【期末复习|考研复习】
第二章 进程管理 【期末复习|考研复习】 计算机操作系统系列文章传送门: 第一章 计算机系统概述 第二章 进程管理 第三章 进程同步 第四章 内存管理 第五章 文件管理 第六章 输出输出I/O管理 文章目录 第二章 进程管理 【期末复习|考研复习】前言二、进程管理2.1进…...

如何学好C++?学习C和C++的技巧是什么?
如何学好C?学习C和C的技巧是什么? 你这三个问题,前两个都是意思是差不多的,那么怎么怎么学习C/C我来问答一下:最近很多小伙伴找我,说想要一些C资料,然后我根据自己从业十年经验,熬夜搞了几个通…...
leetcode_39 组合总和
1. 题意 给定一个数组,和一个目标值;求得所有数组中所有和为目标值的元素序列。 组合总数 2. 题解 回溯列举每一个可能的序列,注意去重。 2.1 我的解法 class Solution { public:void gen(vector<vector<int>> &ans,co…...
【登录安全测试】
登录安全测试是确保系统的用户身份验证机制和登录过程的安全性的重要步骤。以下是一些常见的登录安全测试方面的考虑: 账号密码验证:验证系统是否能有效地验证用户的账号和密码,包括对密码长度、复杂性和有效性的限制。测试应包括正常和异常…...

MySQL -- 数据类型
MySQL – 数据类型 文章目录 MySQL -- 数据类型一、数据类型1.数据类型分类2.数值类型2.1.tinyint2.2.bit2.3小数类型 3.字符串类型3.1.char3.2.varchar 4.时间和日期类型5.enum和set 一、数据类型 1.数据类型分类 2.数值类型 2.1.tinyint tinyint类型的数值范围是-128 ~ 127…...
Windows11搭建kafka-python环境
文章目录 安装软件javazookeeperkafka命令行调试环境python-kafka环境参数解释名词解释定义基础架构同步发送、异步发送消息队列的两种模式消费者与消费组幂等性文件清理策略kafka消费模式offset作用kafka消费顺序如何保证参考文献安装软件 java 下载jdk,配置环境变量JAVA_H…...

一篇了解springboot3请求参数种类及接口测试
SpringBoot3数据请求: 原始数据请求: //原始方式RequestMapping("/simpleParam")public String simpleParam(HttpServletRequest request){//获取请求参数String name request.getParameter("name");String age request.getParam…...
CFD模拟仿真理论知识:流体仿真应用
CFD模拟仿真理论知识:流体仿真应用 本文将介绍CFD(Computational Fluid Dynamics,计算流体动力学)模拟仿真理论知识的原理、方法和应用。通过本文对CFD的深入理解,并了解如何运用这一理论解决实际问题。...
【springboot单元测试,集成测试】
本文介绍一下SpringBoot中的测试方法 集成测试 SpringBootTest 一个普通的web api RequestMapping RestController public class HelloController {AutowiredRestTemplate restTemplate;GetMapping(value "/api/hi")public Map<String,Object> hello() {S…...
【音视频】音视频开发与学习
音视屏开发与学习 时间:2023年8月12日10:09:29 文章目录 音视屏开发与学习1.资料1.资料 1.资料下载: 这是最新的课程视频教程,如有星球过期的朋友,可以在这个群公告或者私聊我拿资料,这个资料会一直发给大家的,已经在星球的就直接在星球获取资料就行:链接:https://pan.…...

软考系统架构之案例篇(架构设计相关概念)
案例篇-架构设计相关概念 1. 架构风格的概念2. 五大架构风格有哪些3. MVC架构含义4. 云计算架构5. 云原生架构设计原则6. ESB的主要功能包括7. 质量属性的含义及其设计策略8. EJB中的 Bean 分三种类型9. 风险点、敏感点、权衡点的含义10. REST 的5个原则 1. 架构风格的概念 软…...

基于大数据的时间序列股价预测分析与可视化 - lstm 计算机竞赛
文章目录 1 前言2 时间序列的由来2.1 四种模型的名称: 3 数据预览4 理论公式4.1 协方差4.2 相关系数4.3 scikit-learn计算相关性 5 金融数据的时序分析5.1 数据概况5.2 序列变化情况计算 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 &…...

APP分发-CDN加速原理
摘要 CDN的全称是(Content Delivery Network),即内容分发网络。其目的是通过在现有的Internet中增加一层新的CACHE(缓存)层,将网站的内容发布到最接近用户的网络”边缘“的节点,使用户可以就近取得所需的内容,提高用户访问网站的…...

【Java 进阶篇】Java Request 继承体系详解
在Java编程中,Request(请求)是一个常见的概念,特别是在Web开发中。Request通常用于获取来自客户端的信息,以便服务器能够根据客户端的需求提供相应的响应。在Java中,Request通常涉及到一系列类和接口&#…...

通过阿里云创建accessKeyId和accessKeySecret
我们想实现服务端向个人发送短信验证码 需要通过accessKeyId和accessKeySecret 这里可以白嫖阿里云的 这里 我们先访问阿里云官网 阿里云地址 进入后搜索并进入短信服务 如果没登录 就 登录一下先 然后在搜索框搜索短信服务 点击进入 因为我也是第一次操作 我们一起点免费开…...
decapoda-research/llama-7b-hf 的踩坑记录
使用transformers加载decapoda-research/llama-7b-hf的踩坑记录。 ValueError: Tokenizer class LLaMATokenizer does not exist or is not currently imported. 解决办法: https://github.com/huggingface/transformers/issues/22222 将tokenizer_config.json中LLa…...

计算机操作系统重点概念整理-第六章 输入输出I/O管理【期末复习|考研复习】
第六章 输入输出I/O管理【期末复习|考研复习】 计算机操作系统系列文章传送门: 第一章 计算机系统概述 第二章 进程管理 第三章 进程同步 第四章 内存管理 第五章 文件管理 第六章 输出输出I/O管理 文章目录 第六章 输入输出I/O管理【期末复习|考研复习】前言六、输…...

uniapp开发小程序—picker结合后台数据实现二级联动的选择
一、效果图 二、完整代码 <template><view><picker mode"multiSelector" change"bindMultiPickerChange" columnchange"bindMultiPickerColumnChange":value"multiIndex" :range"multiArray"><view c…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...