设备树(配合LED驱动说明)
目录
一、起源
二、基本组成
三、基本语法
四、特殊节点
4.1 根节点
4.2 /memory
4.3 /chosen
4.4 /cpus 多核CPU支持
五、常用属性
5.1 phandle
5.2 地址 --------------- 重要
5.3 compatible --------------- 重要
5.4 中断 --------------- 重要
5.5 gpio --------------- 重要
5.6 属性设置套路
六、常用接口
6.1 of_find_node_by_path
6.2 of_find_property
6.3 of_get_named_gpio
6.4 irq_of_parse_and_map
6.5 读属性值
七、GPIO接口
7.1 向内核申请GPIO
7.2 设置GPIO方向
7.3 读写GPIO数据
八、led驱动设备树版
一、起源
减少垃圾代码
减轻驱动开发工作量
驱动代码和设备信息分离
参考Open Fireware设计
用来记录硬件平台中各种硬件设备的属性信息
二、基本组成
两种源文件:
1. xxxxx.dts dts是device tree source的缩写
2. xxxxx.dtsi dtsi是device tree source include的缩写,意味着这样源文件用于被dts文件包含用
实际使用时,需要把dts文件编译成对应的二进制文件(.dtb文件,dtb是device tree binary的缩写 )便于运行时存放在内存加快读取信息的速度
(这些源文件还要经过dtc编译成可执行文件才能使用)
三、基本语法
dts文件主体内容由多个节点组成
每个节点可以包含0或多个子节点,形成树状关系
每个dts文件都有一个根节点,其它节点都是它的子孙
根节点一般来描述整个开发板硬件平台,其它节点用来表示具体设备、总线的属性信息
各个节点可以有多个属性,每个属性用key-value键值对来表示
节点语法:
```c[label:] node-name[@unit-address] { [properties definitions]; [child nodes];};label: 可选项,节点别名,为了缩短节点访问路径,后续节点中可以使用 &label 来表示引用指定节点node-name: 节点名unit-address: 设备地址,一般填写该设备寄存器组或内存块的首地址properties definitions:属性定义child nodes:子节点```
属性语法:
```c[label:] property-name = value;[label:] property-name;属性可以无值有值的属性,可以有三种取值:1. arrays of cells(1个或多个32位数据, 64位数据使用2个32位数据表示,空格分隔),用尖括号表示(< >)2. string(字符串), 用双引号表示(" ")3. bytestring(1个或多个字节,空格分隔),用方括号表示([])4. 用,分隔的多值```
属性值可以是三种混合的。
四、特殊节点
4.1 根节点
根节点表示整块开发板的信息
```c
#address-cells // 在子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells // 在子节点的reg属性中, 使用多少个u32整数来描述大小(size)
compatible // 定义一系列的字符串, 用来指定内核中哪个machine_desc可以支持本设备,即描述其兼容哪些平台
model // 比如有2款板子配置基本一致, 它们的compatible是一样的,那么就通过model来分辨这2款板子
```
4.2 /memory
SOC内部有一些ROM、SRAM等存储器件,都很小并且有他特定的作用,所以为了跑更多的程序都要外界一些内存,一般为SDRAM。这个节点就是描述这些外界内存的。
所有设备树文件的必需节点,它定义了系统物理内存的 layout
```
device_type = "memory";
reg //用来指定内存的地址、大小
```
4.3 /chosen
传递内核启动时使用的参数parameter
```
bootargs //字符串,内核启动参数, 跟u-boot中设置的bootargs作用一样
```
4.4 /cpus 多核CPU支持
/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性用来标明自己是哪一个cpu
所以 /cpus 中有以下2个属性:
```
#address-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size) 必须设置为0
```
一个新的开发板和芯片被造出来后第一次进行Linux移植叫初次移植。这个工作量是很大的。我们一般工作时都是二次移植 (初次移植一般都是SOC的生产商去做)咱们国内的SOC芯片厂商太少了,很难有机会进行初次移植。大多都是二次移植。我们只需要修改初次移植时的设备树文件就行。不需要从零开始写。参考原理图和芯片手册改改就行。
五、常用属性
5.1 phandle
数字形式的节点标识,在后续节点中属性值性质表示某节点时,可以引用对应节点
如:
```
pic@10000000 {
phandle = <1>;
interrupt-controller;
};
another-device-node {
interrupt-parent = <1>; // 使用phandle值为1来引用上述节点
};
```
5.2 地址 --------------- 重要
reg属性:表示内存区域region,语法:
```
reg = <address1 length1 [address2 length2] [address3 length3]>;
```
#address-cells:reg属性中, 使用多少个u32整数来描述地址(address),语法:
```
#address-cells = <数字>;
```
#size-cells:reg属性中, 使用多少个u32整数来描述大小(size),语法:
```
#size-cells = <数字>;
```
5.3 compatible --------------- 重要
驱动和设备(设备节点)的匹配依据,compatible(兼容性)的值可以有不止一个字符串以满足不同的需求,语法:
```
compatible = "字符串1","字符串2",...;
```
5.4 中断 --------------- 重要
a. 中断控制器节点用的属性:
interrupt-controller 一个无值空属性用来声明这个node接收中断信号,表示该节点是一个中断控制器
#interrupt-cells 这是中断控制器节点的属性,用来标识这个控制器需要几个单位做中断描述符
b. 中断源设备节点用的属性:
interrupt-parent:标识此设备节点属于哪一个中断控制器,如果没有设置这个属性,会自动依附父节点的,语法:
```
interrupt-parent = <引用某中断控制器节点>
```
interrupts 一个中断标识符列表,表示每一个中断输出信号,语法:
```
interrupts = <中断号 触发方式>
1 low-to-high 上升沿触发
2 high-to-low 下降沿触发
4 high level 高电平触发
8 low level 低电平触发
```
5.5 gpio --------------- 重要
gpio也是最常见的IO口,常用的属性有:
a. 对于GPIO控制器:
gpio-controller,无值空属性,用来说明该节点描述的是一个gpio控制器
#gpio-cells,用来表示要用几个cell描述一个 GPIO引脚
b. 对于GPIO使用者节点:
gpio使用节点的属性
```
xxx-gpio = <&引用GPIO控制器 GPIO标号 工作模式>
工作模式:
1 低电平有效 GPIO_ACTIVE_HIGH
0 高电平有效 GPIO_ACTIVE_LOW
```
5.6 属性设置套路
一般来说,每一种设备的节点属性设置都会有一些套路,比如可以设置哪些属性?属性值怎么设置?那怎么知道这些套路呢,有两种思路:
1. 抄类似的dts,比如我们自己项目的平台是4412,那么就可以抄exynos4412-tiny4412.dts、exynos4412-smdk4412.dts这类相近的dts
2. 查询内核中的文档,比如Documentation/devicetree/bindings/i2c/i2c-imx.txt就描述了imx平台的i2c属性设置方法;Documentation/devicetree/bindings/fb就描述了lcd、lvds这类属性设置方法
六、常用接口
struct device_node 对应设备树中的一个节点
struct property 对应节点中一个属性
6.1 of_find_node_by_path
```c/**include/of.hof_find_node_by_path - 通过路径查找指定节点@path - 带全路径的节点名,也可以是节点的别名成功:得到节点的首地址;失败:NULL*/struct device_node * of_find_node_by_path(const char *path);```
6.2 of_find_property
```c/*include/of.hof_find_property - 提取指定属性的值@np - 设备节点指针@name - 属性名称@lenp - 属性值的字节数成功:属性值的首地址;失败:NULL*/struct property *of_find_property(const struct device_node *np, const char *name, int *lenp);```
6.3 of_get_named_gpio
```c/*** include/of_gpio.h* of_get_named_gpio - 从设备树中提取gpio口* @np - 设备节点指针* @propname - 属性名* @index - gpio口引脚标号 * 成功:得到GPIO口编号;失败:负数,绝对值是错误码*/int of_get_named_gpio(struct device_node *np, const char *propname, int index);```
6.4 irq_of_parse_and_map
```c/*功能:获得设备树中的中断号并进行映射参数:node:设备节点index:序号返回值:成功:中断号 失败:错误码*/unsigned int irq_of_parse_and_map(struct device_node *node, int index);```
6.5 读属性值
of_property_read_string
```c/*of_property_read_string - 提取字符串(属性值)@np - 设备节点指针@propname - 属性名称@out_string - 输出参数,指向字符串(属性值)成功:0;失败:负数,绝对值是错误码*/int of_property_read_string(struct device_node *np, const char *propname, const char **out_string);```
读数值
```cint of_property_read_u8(const struct device_node *np,const char *propname,u8 *out_value)int of_property_read_u16(const struct device_node *np,const char *propname,u16 *out_value)int of_property_read_u32(const struct device_node *np,const char *propname,u32 *out_value)```
判断属性是否存在
```c
int of_property_read_bool(const struct device_node *np,const char *propname)
```
读数组
```c
int of_property_read_u32_array(const struct device_node *np,const char *propname,u32 *out_value,size_t sz)
```
七、GPIO接口
7.1 向内核申请GPIO
int gpio_request(unsigned gpio,const char *label)
功能:其实就是让内核检查一下该GPIO引脚是否被其它设备占用,如果没有占用则返回0并用label做一下标记,表示被本设备占用,否则返回负数
void gpio_free(unsigned gpio)
功能:去除本设备对该GPIO的占用标记,表示本设备向内核归还对该GPIO引脚的使用权,此后其它设备可占用该GPIO引脚
7.2 设置GPIO方向
int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio,int value)
7.3 读写GPIO数据
int gpio_get_value(unsigned gpio)
int gpio_set_value(unsigned gpio,int value)
八、led驱动设备树版
1. 在设备树源文件的根节点下添加本设备的节点(该节点中包含本设备用到的资源信息)
..../linux3.14/arch/arm/boot/dts/exynos4412-fs4412.dts
```
fs4412-leds {
compatible = "fs4412,led2-5";
led2-gpio = <&gpx2 7 0>;
led3-gpio = <&gpx1 0 0>;
led4-gpio = <&gpf3 4 0>;
led5-gpio = <&gpf3 5 0>;
};
```
2. 在linux内核源码的顶层目录下执行:make dtbs (生成对应的dtb文件)
3. cp ?????.dtb /tftpboot
4. 编写驱动代码:
a. 通过本设备在设备树中的路径找到对应节点(struct device_node类型的地址值)
b. 调用 of_get_named_gpio 函数得到某个GPIO的编号
c. struct leddev结构体中记录所有用到的GPIO编号
d. 使用某个GPIO引脚前需先通过gpio_request函数向内核申请占用该引脚,不用该引脚时可通过gpio_free归还给内核
e. 通过gpio_direction_input和gpio_direction_output函数来设置某个GPIO的作用
f. 通过gpio_get_value函数可以获取某个GPIO引脚的当前电平
g. 通过gpio_set_value函数可以改变某个GPIO引脚的电平
make dtbs
cp arch/arm/boot/dts/exynos4412-fs4412.dtb ~/tftpboot/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/of_gpio.h>
#include "leddrv.h"int major = 11;
int minor = 0;
int myled_num = 1;struct myled_dev
{struct cdev mydev;unsigned int led2gpio; unsigned int led3gpio; unsigned int led4gpio; unsigned int led5gpio; };struct myled_dev *pgmydev = NULL;int myled_open(struct inode *pnode, struct file *pfile)
{pfile->private_data = container_of(pnode->i_cdev, struct myled_dev, mydev);return 0;
}int myled_close(struct inode *pnode, struct file *pfile)
{//printk("myled_close\n");/*C90 requires printk after the variable declaration*///struct myled_dev *pmydev = (struct myled_dev *)pfile->private_data;return 0;
}void led_on(struct myled_dev *pmydev,int ledno)
{switch(ledno){case 2:gpio_set_value(pmydev->led2gpio,1);break;case 3:gpio_set_value(pmydev->led3gpio,1);break;case 4:gpio_set_value(pmydev->led4gpio,1);break;case 5:gpio_set_value(pmydev->led5gpio,1);break;}
}void led_off(struct myled_dev *pmydev,int ledno)
{switch(ledno){case 2:gpio_set_value(pmydev->led2gpio,0);break;case 3:gpio_set_value(pmydev->led3gpio,0);break;case 4:gpio_set_value(pmydev->led4gpio,0);break;case 5:gpio_set_value(pmydev->led5gpio,0);break;}
}long myled_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
{struct myled_dev *pmydev = (struct myled_dev *)pfile->private_data;if(arg < 2 || arg > 5){return -1;}switch(cmd){case MY_LED_ON:led_on(pmydev,arg);break;case MY_LED_OFF:led_off(pmydev,arg);break;default:return -1;}return 0;
}struct file_operations myops = {.owner = THIS_MODULE,.open = myled_open,.release = myled_close,.unlocked_ioctl = myled_ioctl,
};void request_leds_gpio(struct myled_dev *pmydev,struct device_node *pnode)
{pmydev->led2gpio = of_get_named_gpio(pnode, "led2-gpio", 0);gpio_request(pmydev->led2gpio, "led2");pmydev->led3gpio = of_get_named_gpio(pnode, "led3-gpio", 0);gpio_request(pmydev->led3gpio, "led3");pmydev->led4gpio = of_get_named_gpio(pnode, "led4-gpio", 0);gpio_request(pmydev->led4gpio, "led4");pmydev->led5gpio = of_get_named_gpio(pnode, "led5-gpio", 0);gpio_request(pmydev->led5gpio, "led5");}void set_leds_gpio_output(struct myled_dev *pmydev)
{gpio_direction_output(pmydev->led2gpio,0);gpio_direction_output(pmydev->led3gpio,0);gpio_direction_output(pmydev->led4gpio,0);gpio_direction_output(pmydev->led5gpio,0);
}void free_leds_gpio(struct myled_dev *pmydev)
{gpio_free(pmydev->led2gpio);gpio_free(pmydev->led3gpio);gpio_free(pmydev->led4gpio);gpio_free(pmydev->led5gpio);
}int __init myled_init(void)
{dev_t devno = MKDEV(major,minor);int ret = 0;struct device_node *pnode = NULL;pnode = of_find_node_by_path("/fs4412-leds");if(NULL == pnode){printk("find node by path failed\n");return -1;}/*Apply for device number*/ret = register_chrdev_region(devno,myled_num,"myled");if(ret){ret = alloc_chrdev_region(&devno,minor,myled_num,"myled");if(ret){printk("get devno failed\n");return -1;}major = MAJOR(devno);//Easy to miss *****}pgmydev = (struct myled_dev *)kmalloc(sizeof(struct myled_dev),GFP_KERNEL);if(pgmydev == NULL){unregister_chrdev_region(devno, myled_num);printk("kmalloc failed\n");return -1;}memset(pgmydev, 0, sizeof(struct myled_dev));/*Assign the 'struct cdev' a set of operation functions*/cdev_init(&pgmydev->mydev, &myops);/*Add 'struct cdev' to the kernel's data structure*/pgmydev->mydev.owner = THIS_MODULE;cdev_add(&pgmydev->mydev, devno, myled_num);//add to Hash./*ioremap*///ioremap_ledreg(pgmydev);request_leds_gpio(pgmydev,pnode);/*con-register set output*///set_output_ledconreg(pgmydev);set_leds_gpio_output(pgmydev);return 0;
}
void __exit myled_exit(void)
{dev_t devno = MKDEV(major,minor);/*iounmap*///iounmap_ledreg(pgmydev);free_leds_gpio(pgmydev);cdev_del(&pgmydev->mydev);//printk("myled will exit\n");unregister_chrdev_region(devno, myled_num);kfree(pgmydev);pgmydev = NULL;
}
MODULE_LICENSE("GPL");module_init(myled_init);
module_exit(myled_exit);
相关文章:

设备树(配合LED驱动说明)
目录 一、起源 二、基本组成 三、基本语法 四、特殊节点 4.1 根节点 4.2 /memory 4.3 /chosen 4.4 /cpus 多核CPU支持 五、常用属性 5.1 phandle 5.2 地址 --------------- 重要 5.3 compatible --------------- 重要 5.4 中断 --------------- 重要 5.5 …...

(二十六)大白话如何从底层原理解决生产的Too many connections故障?
今天我们继续讲解昨天的那个案例背景,其实就是经典的Too many connections故障,他的核心就是linux的文件句柄限制,导致了MySQL的最大连接数被限制,那么今天来讲讲怎么解决这个问题。 其实核心就是一行命令: ulimit -H…...

ASEMI高压MOS管60R380参数,60R380特征,60R380应用
编辑-Z ASEMI高压MOS管60R380参数: 型号:60R380 漏极-源极电压(VDS):600V 栅源电压(VGS):20V 漏极电流(ID):11A 功耗(PD&#x…...

Python期末试卷
《Python程序设计基础》期末试题 班级 学号 姓名 一.选择题(须知:答案写到下方的表格中,其它一律无效.每题2分,共40分) 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 1.在Python交互…...

Linux | 网络通信 | http协议介绍 | cookie策略讲解
文章目录url统一资源定位符http协议介绍GET vs POSThttp状态码http常见headercookie session上篇博客定制了一个协议,该协议用来进行简单的计算,其包含了数据的序列化和反序列化,编码和解码的定制,并且该协议基于TCP通信…...

招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…...

winapi获取和修改camera raw界面元素数据
camera raw 界面如下: 需求就是根据 windows api 来操作界面右边的色温、色调、曝光等属性,进而对图片进行调色。根据 spy 捕获的窗口信息,理论上是可以拿到并修改值的。 根据 class 可以先拿到窗口句柄: #define CAMERA_RAW_CLA…...

C++问答汇总_2023自用
C是一种通用编程语言,具有高级抽象、强类型和编译性能等特点。C语言具有许多特性,包括面向对象编程、模板、多态、运算符重载等等。它广泛应用于各种领域,如系统软件、嵌入式系统、游戏开发、科学计算等等。 1、C11相对于C98的新特性…...

IDA 实战--(2)熟悉工具
布局介绍 软件启动后会 有几个选项,一般直接选择Go 即可 之后的工作台布局如下 开始分析 分析的第一个,将PE 文件拖入工作区 刚开始接触,我们先保持默认选项,其它选项后面会详细讲解,点击OK 后,等待分析…...

Deep Unsupervised Learning using Nonequilibrium Thermodynamics论文翻译学习
Deep Unsupervised Learning using Nonequilibrium Thermodynamics Author: Jascha Sohl-Dickstein Link: http://proceedings.mlr.press/v37/sohl-dickstein15.pdf Score: ⭐️⭐️⭐️⭐️⭐️ Status: Done Type: Academic Journal 备注: 首篇扩散模型论文 A central prob…...

使用Autoware标定工具包联合标定相机和激光雷达
前面文章介绍了,安装autoware标定工具包、ros驱动usb相机、robosense-16线激光雷达的使用,本文记录使用Autoware标定工具包联合标定相机和激光雷达的过程。1.ros驱动相机,启动相机;启动激光雷达2.联合录制bag包rosbag record -a 参…...

了解线程安全
线程安全是多线程的重点和难点。 线程安全概念 线程安全:在多线程的各种随机调度顺序下,代码没有bug,都能够符合预期的方式来执行,此时认为线程安全 线程不安全:如果在多线程随机调度下代码出现bug,此时…...

【git】git版本控制
目录 1.在合适的位置打开bush,创建仓库 2.检查:跳转到当前文件夹,显示当前文件夹的相对路径 3.初始化 4.创建一个文本文件readme.txt 5.手动向readme文件中添加一些内容 6.把文件添加到暂存区 7.把文件提交到git仓库 8.手动修改readme.txt文件 9.查看当前…...

模电学习7. 三极管特性曲线与静态工作点
模电学习7. 三极管特性曲线与静态工作点一、三极管的伏安特性曲线1. 三极管的伏安特性曲线2. 三极管的静态工作点二、合适的静态工作点选择1. 合适静态工作点条件2. 静态工作点的确定三、使用立创EDA仿真查看静态工作点1. 搭建如下图所示测试电路2. 点击菜单仿真、仿真设置3. 运…...

LeetCode题解:633. 平方数之和,双指针,JavaScript,详细注释
原题链接: https://leetcode.cn/problems/sum-of-square-numbers/ 解题思路: a和b一定是000到c\sqrt cc之间的某个值。将a的初始值设为0。b的初始值设为c\sqrt cc,b必须为整数。a和b向中间逼近,查找满足条件的值。由于a和b是…...

Keil编译头文件iec_std_functions.h错误解决
Keil 编译IEC61131-3库,头文件,大量出现以下错误; cast to type ? is not allowed compiling resource1.c... ..\PLC\rts\matiec\lib\C\iec_std_functions.h(192): error: #119: cast to type "TIME" is not allowed…...

2022 赣育杯 CTF --- Crypto Lost_N wp
文章目录前言题目解题过程解题代码前言 这是去年江西省赛一道有点小坑的密码题,当时没做出来,今天回想起来重新做一下并且记录一下。 题目 Lost_N.py import gmpy2 from Crypto.Util.number import * # part1 flag bSangFor{} d getPrime(435) cou…...

【趋势分析方法三】MATLAB代码实现TFPW-MK检验
目前水文时间序列趋势分析的方法很多,主要分为参数检验和非参数检验两大类: 参数检验中常用的有线性回归法、滑动平均法、累积距平法等非参数检验则主要包括Mann-Kendal(MK)法和 Spearman 秩次相关法等 虽然从理论上讲ÿ…...

一文学会 Spring 整合 MyBatis
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

ElasticSearch - 文档 | 索引文档 | 检索文档 | 创建索引并指明映射
文章目录1. ElasticSearch是面向文档的2. 索引员工文档3. 检索员工文档4. 映射1. ElasticSearch是面向文档的 在应用程序中对象很少只是一个简单的键和值的列表。通常,它们拥有更复杂的数据结构,可能包括日期、地理信息、其他对象或者数组等。 Elastic…...

SQL中的DML、DDL、DCL分别是什么意思
SQL命令的分类 数据定义语言 DDL(DataDefinition Language) 是 SQL 语言集中负责数据结构定义。 DDL 的核心指令是CREATE、ALTER、DROP。 操作的对象包括:库、表、视图、索引等。 如:CREATE TABLE ; ALTER INDEX; DROP VIEW; 数据…...

kubeasz部署k8s高可用集群
前言:如无特殊说明,所有操作都用root账号在所有节点执行。 说明:kubeasz是一款国产开源的k8s部署软件,采用ansible role的部署方式,部署k8s二进制集群。熟悉ansible role的用该软件部署k8s方便快捷。 一、机器 deplo…...

2022年工程机械出口专题研究【重工】
文章目录2022年工程机械出口专题研究1、中国是全球工程机械第一大市场,竞争力逐步提升2、工程机械出口高增,市场分布趋于多元,企业营收获益3、海外市场高速增长原因为何?4、海外市场增长动能预测附件:2022年工程机械出…...

[python入门(51)] - python时间日期格式time和datetime
目录 ❤ 预备知识 ❤ UTC time Coordinated Universal Time ❤ epoch time ❤ timestamp(时间戳) ❤ stamptime时间戳 ❤ struct_time时间元组 ❤ format time 格式化时间 ❤ time模块编辑 ❤ 获取当前时间的方法 ❤ 当传入默认参…...

别担心ChatGPT距离替代程序猿还有距离
经过多天对chat-GPT在工作的使用,我得出一个结论,它睁眼瞎说就算了,它还积极认错,绝不改正,错误答案极具误导性,啥也不说了,请看图。 经过N次较量它固执的认为 0011 1101 0110 0101在最高位是左…...

SpringBoot项目打包部署到阿里云服务器、通过Maven插件制作Docker镜像、部署项目容器、配置生产环境
制作通用模块jar包 通用模块不是运行的,而且要被其他模块引入的,所以该模块不能采用springboot打包方式制作jar包,否则其他模块无法引入通用模块。 1、修改通用模块,设置模块为非Springboot项目 <?xml version"1.0&qu…...

OpenGov的首个方案已上线Moonriver
随着公投128的通过,作为Runtime 2100的一部分,Moonbeam在Moonriver上推出了OpenGov。Moonbeam上的OpenGov部署将从Moonriver开始,以获得社区反馈。未来将举行公投,让社区来决定OpenGov如何发展并转移至Moonbeam。 Moonriver上的O…...

(三十一)大白话MySQL如果事务执行到一半要回滚怎么办?再探undo log回滚日志原理
之前我们已经给大家深入讲解了在执行增删改操作时候的redo log的重做日志原理,其实说白了,就是你对buffer pool里的缓存页执行增删改操作的时候,必须要写对应的redo log记录下来你做了哪些修改 如下图所示: 这样万一要是你提交事…...

机器学习-基于KNN及其改进的汉字图像识别系统
一、简介和环境准备 knn一般指邻近算法。 邻近算法,或者说K最邻近(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。而lmknn是局部均值k最近邻分类算法。 本次实验环境需要用的是Google Colab和Google Dr…...

Zebec生态持续深度布局,ZBC通证月内翻倍或只是开始
“Zebec生态近日利好不断,除了推出了回购计划外, Nautilus Chain 、Zebec Labs等也即将面向市场,都将为ZBC通证深度赋能。而ZBC通证涨幅月内突破100%,或许只是开始。”近日,流支付生态Zebec生态通证ZBC迎来了大涨&…...