Linux学习第16天:Linux设备树下的LED驱动开发:举一反三 专注专心专业

2023-11-18

Linux版本号4.1.15   芯片I.MX6ULL                                     大叔学Linux    品人间百味  思文短情长


         在开题之前,先说一下这次的题目,尤其是后面的“举一反三 专注专心专业”到底想给大家传递什么信息。LED驱动开发,目前为止已经学了好几种方法,包括裸机开发、嵌入式Linux LED驱动开发以及基于API函数的LED驱动开发,再加上今天要学习的基于Linux设备树的LED驱动开发,已经整整学了4种。原因也很简单,除了LED驱动开发是最基础最简单的驱动开发,通过不同方式实现其驱动开发,更便于分析各种方法之间的异同点,更容易消化理解刚学的内容。从这一点来说,举一反三,是也。而专注专心专业三者贵在一个专字。世间知识千千万,学习嵌入式Linux驱动开发,万千江湖,只取一瓢。在当今尤其是社会分工愈来愈细化的今天,保持一个专字,在自己选定的领域保持专注专心和专业,才能使自己变的更强、眼光放的更远,思考的深度更深。

        今天的这篇笔记要学习的内容是基于Linux设备树的LED驱动开发,主要内容包括原理、程序编写和测试,重点是程序的编写,其内容又包含设备树文件的修改、驱动程序编写以及测试APP的编写。

        下图为本笔记的思维导图:

一、设备树LED驱动原理

        使用设备树来向 Linux 内核传递相关的寄存器物理地址, Linux 驱动文件使用上一章讲解的 OF函数从设备树中获取所需的属性值,然后使用获取到的属性值来初始化相关的 IO。

二、实验程序编写

1.修改设备树文件

        在根节点“/”下创建一个名为“alphaled”的子节点,打开 imx6ull-alientek-emmc.dts 文件,在根节点“/”最后面输入如下所示内容:

1 alphaled {
2 #address-cells = <1>;
3 #size-cells = <1>;
4 compatible = "atkalpha-led";
5 status = "okay";
6 reg = < 0X020C406C 0X04 /* CCM_CCGR1_BASE */
7 0X020E0068 0X04 /* SW_MUX_GPIO1_IO03_BASE */
8 0X020E02F4 0X04 /* SW_PAD_GPIO1_IO03_BASE */
9 0X0209C000 0X04 /* GPIO1_DR_BASE */
10 0X0209C004 0X04 >; /* GPIO1_GDIR_BASE */
11 };

        特别关注一下第6-10行,reg 属性设置了驱动里面所要使用的寄存器物理地址。

        输入如下命令,重新编译一下imx6ull-alientek-emmc.dts。

make dtbs

        使用编译后的新的imx6ull-alientek-emmc.dtb启动Linux内核。启动成功后,在/proc/device-tree目录下会看到alphaled这个节点,如下:




2.LED驱动程序编写

        直接上代码吧,如下:

1 #include <linux/types.h>
2 #include <linux/kernel.h>
3 #include <linux/delay.h>
4 #include <linux/ide.h>
5 #include <linux/init.h>
6 #include <linux/module.h>
7 #include <linux/errno.h>
8 #include <linux/gpio.h>
9 #include <linux/cdev.h>
10 #include <linux/device.h>
11 #include <linux/of.h>
12 #include <linux/of_address.h>
13 #include <asm/mach/map.h>
14 #include <asm/uaccess.h>
15 #include <asm/io.h>
16 /***************************************************************
17 Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
18 文件名 : dtsled.c
19 作者 : 左忠凯
20 版本 : V1.0
21 描述 : LED 驱动文件。
22 其他 : 无
23 论坛 : www.openedv.com
24 日志 : 初版 V1.0 2019/7/9 左忠凯创建
25 ***************************************************************/
26 #define DTSLED_CNT 1 /* 设备号个数 */
27 #define DTSLED_NAME "dtsled" /* 名字 */
28 #define LEDOFF 0 /* 关灯 */
29 #define LEDON 1 /* 开灯 */
30
31 /* 映射后的寄存器虚拟地址指针 */
32 static void __iomem *IMX6U_CCM_CCGR1;
33 static void __iomem *SW_MUX_GPIO1_IO03;
34 static void __iomem *SW_PAD_GPIO1_IO03;
35 static void __iomem *GPIO1_DR;
36 static void __iomem *GPIO1_GDIR;
37
38 /* dtsled 设备结构体 */
39 struct dtsled_dev{
40 dev_t devid; /* 设备号 */
41 struct cdev cdev; /* cdev */
42 struct class *class; /* 类 */
43 struct device *device; /* 设备 */
44 int major; /* 主设备号 */
45 int minor; /* 次设备号 */
46 struct device_node *nd; /* 设备节点 */
47 };
48
49 struct dtsled_dev dtsled; /* led 设备 */
50
51 /*
52 * @description : LED 打开/关闭
53 * @param - sta : LEDON(0) 打开 LED, LEDOFF(1) 关闭 LED
54 * @return : 无
55 */
56 void led_switch(u8 sta)
57 {
58 u32 val = 0;
59 if(sta == LEDON) {
60 val = readl(GPIO1_DR);
61 val &= ~(1 << 3);
62 writel(val, GPIO1_DR);
63 }else if(sta == LEDOFF) {
64 val = readl(GPIO1_DR);
65 val|= (1 << 3);
66 writel(val, GPIO1_DR);
67 }
68 }
69
70 /*
71 * @description : 打开设备
72 * @param – inode : 传递给驱动的 inode
73 * @param – filp : 设备文件, file 结构体有个叫做 private_data 的成员变量
74 * 一般在 open 的时候将 private_data 指向设备结构体。
75 * @return : 0 成功;其他 失败
76 */
77 static int led_open(struct inode *inode, struct file *filp)
78 {
79 filp->private_data = &dtsled; /* 设置私有数据 */
80 return 0;
81 }
82
83 /*
84 * @description : 从设备读取数据
85 * @param – filp : 要打开的设备文件(文件描述符)
86 * @param - buf : 返回给用户空间的数据缓冲区
87 * @param - cnt : 要读取的数据长度
88 * @param – offt : 相对于文件首地址的偏移
89 * @return : 读取的字节数,如果为负值,表示读取失败
90 */
91 static ssize_t led_read(struct file *filp, char __user *buf,
size_t cnt, loff_t *offt)
92 {
93 return 0;
94 }
95
96 /*
97 * @description : 向设备写数据
98 * @param - filp : 设备文件,表示打开的文件描述符
99 * @param - buf : 要写给设备写入的数据
100 * @param - cnt : 要写入的数据长度
101 * @param – offt : 相对于文件首地址的偏移
102 * @return : 写入的字节数,如果为负值,表示写入失败
103 */
104 static ssize_t led_write(struct file *filp, const char __user *buf,
size_t cnt, loff_t *offt)
105 {
106 int retvalue;
107 unsigned char databuf[1];
108 unsigned char ledstat;
109
110 retvalue = copy_from_user(databuf, buf, cnt);
111 if(retvalue < 0) {
112 printk("kernel write failed!\r\n");
113 return -EFAULT;
114 }
115
116 ledstat = databuf[0]; /* 获取状态值 */
117
118 if(ledstat == LEDON) {
119 led_switch(LEDON); /* 打开 LED 灯 */
120 } else if(ledstat == LEDOFF) {
121 led_switch(LEDOFF); /* 关闭 LED 灯 */
122 }
123 return 0;
124 }
125
126 /*
127 * @description : 关闭/释放设备
128 * @param – filp : 要关闭的设备文件(文件描述符)
129 * @return : 0 成功;其他 失败
130 */
131 static int led_release(struct inode *inode, struct file *filp)
132 {
133 return 0;
134 }
135
136 /* 设备操作函数 */
137 static struct file_operations dtsled_fops = {
138 .owner = THIS_MODULE,
139 .open = led_open,
140 .read = led_read,
141 .write = led_write,
142 .release = led_release,
143 };
144
145 /*
146 * @description : 驱动入口函数
147 * @param : 无
148 * @return : 无
149 */
150 static int __init led_init(void)
151 {
152 u32 val = 0;
153 int ret;
154 u32 regdata[14];
155 const char *str;
156 struct property *proper;
157
158 /* 获取设备树中的属性数据 */
159 /* 1、获取设备节点: alphaled */
160 dtsled.nd = of_find_node_by_path("/alphaled");
161 if(dtsled.nd == NULL) {
162 printk("alphaled node can not found!\r\n");
163 return -EINVAL;
164 } else {
165 printk("alphaled node has been found!\r\n");
166 }
167
168 /* 2、获取 compatible 属性内容 */
169 proper = of_find_property(dtsled.nd, "compatible", NULL);
170 if(proper == NULL) {
171 printk("compatible property find failed\r\n");
172 } else {
173 printk("compatible = %s\r\n", (char*)proper->value);
174 }
175
176 /* 3、获取 status 属性内容 */
177 ret = of_property_read_string(dtsled.nd, "status", &str);
178 if(ret < 0){
179 printk("status read failed!\r\n");
180 } else {
181 printk("status = %s\r\n",str);
182 }
183
184 /* 4、获取 reg 属性内容 */
185 ret = of_property_read_u32_array(dtsled.nd, "reg", regdata, 10);
186 if(ret < 0) {
187 printk("reg property read failed!\r\n");
188 } else {
189 u8 i = 0;
190 printk("reg data:\r\n");
191 for(i = 0; i < 10; i++)
192 printk("%#X ", regdata[i]);
193 printk("\r\n");
194 }
195
196 /* 初始化 LED */
197 #if 0
198 /* 1、寄存器地址映射 */
199 IMX6U_CCM_CCGR1 = ioremap(regdata[0], regdata[1]);
200 SW_MUX_GPIO1_IO03 = ioremap(regdata[2], regdata[3]);
201 SW_PAD_GPIO1_IO03 = ioremap(regdata[4], regdata[5]);
202 GPIO1_DR = ioremap(regdata[6], regdata[7]);
203 GPIO1_GDIR = ioremap(regdata[8], regdata[9]);
204 #else
205 IMX6U_CCM_CCGR1 = of_iomap(dtsled.nd, 0);
206 SW_MUX_GPIO1_IO03 = of_iomap(dtsled.nd, 1);
207 SW_PAD_GPIO1_IO03 = of_iomap(dtsled.nd, 2);
208 GPIO1_DR = of_iomap(dtsled.nd, 3);
209 GPIO1_GDIR = of_iomap(dtsled.nd, 4);
210 #endif
211
212 /* 2、使能 GPIO1 时钟 */
213 val = readl(IMX6U_CCM_CCGR1);
214 val &= ~(3 << 26); /* 清楚以前的设置 */
215 val |= (3 << 26); /* 设置新值 */
216 writel(val, IMX6U_CCM_CCGR1);
217
218 /* 3、设置 GPIO1_IO03 的复用功能,将其复用为
219 * GPIO1_IO03,最后设置 IO 属性。
220 */
221 writel(5, SW_MUX_GPIO1_IO03);
222
223 /* 寄存器 SW_PAD_GPIO1_IO03 设置 IO 属性 */
224 writel(0x10B0, SW_PAD_GPIO1_IO03);
225
226 /* 4、设置 GPIO1_IO03 为输出功能 */
227 val = readl(GPIO1_GDIR);
228 val &= ~(1 << 3); /* 清除以前的设置 */
229 val |= (1 << 3); /* 设置为输出 */
230 writel(val, GPIO1_GDIR);
231
232 /* 5、默认关闭 LED */
233 val = readl(GPIO1_DR);
234 val |= (1 << 3);
235 writel(val, GPIO1_DR);
236
237 /* 注册字符设备驱动 */
238 /* 1、创建设备号 */
239 if (dtsled.major) { /* 定义了设备号 */
240 dtsled.devid = MKDEV(dtsled.major, 0);
241 register_chrdev_region(dtsled.devid, DTSLED_CNT,
DTSLED_NAME);
242 } else { /* 没有定义设备号 */
243 alloc_chrdev_region(&dtsled.devid, 0, DTSLED_CNT,
DTSLED_NAME); /* 申请设备号 */
244 dtsled.major = MAJOR(dtsled.devid); /* 获取分配号的主设备号 */
245 dtsled.minor = MINOR(dtsled.devid); /* 获取分配号的次设备号 */
246 }
247 printk("dtsled major=%d,minor=%d\r\n",dtsled.major,
dtsled.minor);
248
249 /* 2、初始化 cdev */
250 dtsled.cdev.owner = THIS_MODULE;
251 cdev_init(&dtsled.cdev, &dtsled_fops);
252
253 /* 3、添加一个 cdev */
254 cdev_add(&dtsled.cdev, dtsled.devid, DTSLED_CNT);
255
256 /* 4、创建类 */
257 dtsled.class = class_create(THIS_MODULE, DTSLED_NAME);
258 if (IS_ERR(dtsled.class)) {
259 return PTR_ERR(dtsled.class);
260 }
261
262 /* 5、创建设备 */
263 dtsled.device = device_create(dtsled.class, NULL, dtsled.devid,
NULL, DTSLED_NAME);
264 if (IS_ERR(dtsled.device)) {
265 return PTR_ERR(dtsled.device);
266 }
267
268 return 0;
269 }
270
271 /*
272 * @description : 驱动出口函数
273 * @param : 无
274 * @return : 无
275 */
276 static void __exit led_exit(void)
277 {
278 /* 取消映射 */
279 iounmap(IMX6U_CCM_CCGR1);
280 iounmap(SW_MUX_GPIO1_IO03);
281 iounmap(SW_PAD_GPIO1_IO03);
282 iounmap(GPIO1_DR);
283 iounmap(GPIO1_GDIR);
284
285 /* 注销字符设备驱动 */
286 cdev_del(&dtsled.cdev);/* 删除 cdev */
287 unregister_chrdev_region(dtsled.devid, DTSLED_CNT);/*注销设备号*/
288
289 device_destroy(dtsled.class, dtsled.devid);
290 class_destroy(dtsled.class);
291 }
292
293 module_init(led_init);
294 module_exit(led_exit);
295 MODULE_LICENSE("GPL");
296 MODULE_AUTHOR("jia");

3.编写测试APP

        内容和上一节内容完全一样。

三、运行测试

1.编译驱动程序和测试APP

        Makefile 内容如下:

1 KERNELDIR := /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imxrel_imx_4.1.15_2.1.0_ga_alientek
......
4 obj-m := dtsled.o //特别注意
......
11 clean:
12 $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

        输入如下命令编译出驱动模块文件dtsled.ko:

make -j32

        输入如下指令编译测试ledApp.c这个程序,生成ledAPP这个程序。

arm-linux-gnueabihf-gcc ledApp.c -o ledApp

2.运行测试

        将编译出来的 dtsled.ko 和 ledApp 两个文件拷贝到 对应目录 中,输入如下命令加载dtsled.ko 驱动模块:

depmod //第一次加载驱动的时候需要运行此命令
modprobe dtsled.ko //加载驱动

        如果正常的话,在终端中会输出如下信息:

        驱动加载成功以后就可以使用 ledApp 软件来测试驱动是否工作正常,输入如下命令打开
LED 灯:

./ledApp /dev/dtsled 1

//打开 LED 灯
        输入上述命令以后观察 I.MX6U-ALPHA 开发板上的红色 LED 灯是否点亮,如果点亮的话说明驱动工作正常。在输入如下命令关闭 LED 灯:
./ledApp /dev/dtsled 0

//关闭 LED 灯

        输入上述命令以后观察 I.MX6U-ALPHA 开发板上的红色 LED 灯是否熄灭。如果要卸载驱
动的话输入如下命令即可:

rmmod dtsled.ko

四.总结

        本笔记主要学习了基于设备树的LED驱动开发,重点是程序的编写,其内容又包含设备树文件的修改、驱动程序编写以及测试APP的编写。


本文为参考正点原子开发板配套教程整理而得,仅用于学习交流使用,不得用于商业用途。

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

Linux学习第16天:Linux设备树下的LED驱动开发:举一反三 专注专心专业 的相关文章

  • touch命令在一个目录下创建多个文件(不同名称)

    我想制作一个在 bash 中创建目录和文件结构的脚本 我尝试过这样的事情 mkdir p 1 2 touch 1 2 a b c a b c 应该是在一个命令或其他命令中创建的文件 但由于某种原因 结构是这样的 current folder
  • 将数组传递给函数名称冲突

    Specs GNU bash 版本 3 1 17 无法升级 Premise 我一直在摆弄数组 我想知道是否有任何方法可以让函数的本地变量与所述函数外部的数组同名 Example 在下面的示例中 我将尝试显示该问题 Working bin b
  • 构建 makefile 依赖/继承树

    如果我解释得不好或者问了一些明显的问题 我很抱歉 但我是 Linux 内核的新手 而且有点深入 我们有一个嵌入式 Linux 系统 它附带一个 文档非常糟糕的 SDK 其中包含数百个文件夹stuff 大多数文件夹包含rules make m
  • git在Windows和Linux之间切换后强制刷新索引

    我有一个Windows和Linux共享的磁盘分区 格式 NTFS 它包含一个 git 存储库 约 6 7 GB 如果我只使用Windows or 只使用Linux操作 git 存储库一切正常 但是每次切换系统的时候git status命令将
  • 伊迪德信息

    重新定义问题 有什么方法可以获取所连接显示器的序列号吗 我想收集显示器的Eid信息 当我使用 logverbose 选项运行 X 时 我可以从 xorg 0 log 文件中获取它 但问题是 如果我切换显示器 拔出当前显示器 然后插入另一个显
  • 标准头文件中的 C 编译器错误 - 未定义的 C++ 定义

    我正在尝试编译 C 程序 但收到许多错误 这些错误是在标准 C 头文件 inttypes h stdio h stat h 等 中遇到的 错误的来源是以下未定义的常量 BEGIN DECLS END DECLS BEGIN NAMESPAC
  • 无法执行'x86_64-conda_cos6-linux-gnu-gcc':没有这样的文件或目录(pysam安装)

    我正在尝试安装 pysam 执行后 python path to pysam master setup py build 这个错误的产生是 unable to execute x86 64 conda cos6 linux gnu gcc
  • 如何在特定 systemd 服务重新启动时触发自定义脚本运行

    我想知道如何安排自定义脚本在重新启动服务时运行 我的用例是 每当重新启动 Tomcat 服务时 我都必须运行多个命令 我想知道是否有一种方法可以编写脚本并安排它在重新启动 Tomcat 服务时运行 我已将 tomcat 脚本设置为 syst
  • 设置 Apache POI 的路径

    我想创建 Excel 文件并使用 java 程序在该文件中写入数据 That is here http www techbrainwave com p 554我在 java 文件所在的位置提取了 Apache POI 并将该路径包含在路径变
  • 让 MongoDB 在 Linux 上监听远程连接

    我已在 Windows 本地计算机上 上成功安装 MongoDB 作为服务 但现在我想将 MongoDb 移动到单独的服务器 所以我将 tarball 解压到网络上的虚拟服务器 运行 Linux 当我从本地计算机使用 PuTTY 连接到服务
  • SONAR - 使用 Cobertura 测量代码覆盖率

    我正在使用声纳来测量代码质量 我不知道的一件事是使用 Cobertura 测量代码覆盖率的步骤 我按照以下步骤操作http cobertura sourceforge net anttaskreference html http cober
  • diff 文件仅比较每行的前 n 个字符

    我有2个文件 我们将它们称为 md5s1 txt 和 md5s2 txt 两者都包含a的输出 find type f print0 xargs 0 md5sum sort gt md5s txt 不同目录下的命令 许多文件被重命名 但内容保
  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • Locale.getDefault() 始终返回 en

    unix 机器上的服务器始终使用 en 作为默认区域设置 以下是区域设置输出 LANG en US LC CTYPE C LC NUMERIC C LC TIME C LC COLLATE C LC MONETARY C LC MESSAG
  • 如何修复“iptables:没有该名称的链/目标/匹配”?

    我在我的 Linux 嵌入式系统上构建并安装了 iptables 如果我列出所有规则 则一切正常 iptables list Chain INPUT policy ACCEPT target prot opt source destinat
  • 拆分字符串以仅获取前 5 个字符

    我想去那个地点 var log src ap kernelmodule 10 001 100 但看起来我的代码必须处理 ap kernelmodule 10 002 100 ap kernelmodule 10 003 101 等 我想使用
  • Elasticsearch 无法写入日志文件

    我想激活 elasticsearch 的日志 当我运行 elasticsearch 二进制文件时 我意识到我在日志记录方面遇到问题 无法加载配置 这是输出 sudo usr share elasticsearch bin elasticse
  • awk 子串单个字符

    这是columns txt aaa bbb 3 ccc ddd 2 eee fff 1 3 3 g 3 hhh i jjj 3 kkk ll 3 mm nn oo 3 我可以找到第二列以 b 开头的行 awk if substr 2 1 1
  • 创建 jar 文件 - 保留文件权限

    我想知道如何创建一个保留其内容的文件权限的 jar 文件 我将源代码和可执行文件打包在一个 jar 文件中 该文件将在使用前提取 人们应该能够通过运行批处理 shell 脚本文件立即运行示例和演示 然后他们应该能够修改源代码并重新编译所有内
  • 无法加载 JavaHL 库。- linux/eclipse

    在尝试安装 Subversion 插件时 当 Eclipse 启动时出现此错误 Failed to load JavaHL Library These are the errors that were encountered no libs

随机推荐

  • faster rcnn matlab,Faster rcnn 模型的数据标定的知识求助,matlab2017b自带的函数

    构建CNN网络 输入层 最小检测对象设置为540 960 inputLayer imageInputLayer 10 10 3 中间层 定义卷基层参数 filterSize 3 3 numFilters 32 middleLayers 第一
  • linux驱动:一、字符设备的介绍和demo

    一 字符设备驱动简介 字符设备是 Linux 驱动中最基本的一类设备驱动 字符设备就是一个一个字节 按照字节流进行读写操作的设备 读写数据是分先后顺序的 比如我们最常见的点灯 按键 IIC SPI LCD 等等都是字符设备 这些设备的驱动就
  • 如何清空matlab命令窗口,matlab如何清空命令窗口中的内容

    还有一个常用的clf 清除图形窗口命令www mh456 com防采集 在matlab的命令窗口 输入2113clc命令 即可清空命令窗5261口中的内容 从matlab2012b版本后 还可以4102利用HOME菜单页下的Clear Co
  • MS17-010(永恒之蓝)漏洞复现和分析

    MS17 010 永恒之蓝 漏洞复现和分析 一 漏洞简介 1 永恒之蓝介绍 永恒之蓝是指2017年4月14日晚 黑客团体Shadow Brokers 影子经纪人 公布一大批网络攻击工具 其中包含 永恒之蓝 工具 永恒之蓝 利用Windows
  • PTA天梯赛L1-058 6翻了(c语言实现)

    原题链接 这道题稍微有一点点灵活 乍一想还是有点想不到的 主要还是对6的个数进行计数 如果是6则计数有多少个6 如果不是6的话则要进行判断 如果在此之前6的个数超过了3 gt 3 但是小于等于9那么要输出9 如果在此之前6的个数超过了9 g
  • ctfshow---sql注入(214-253)

    目录 web214 web215 web216 web217 web218 web219 web220 web221 web222 web223 web224 web225 web226 web227 web228 229 230 web2
  • 解决git速度慢的问题

    git clone特别慢是因为github global ssl fastly net域名被限制了 只要找到这个域名对应的ip地址 然后在hosts文件中加上ip gt 域名的映射 刷新DNS缓存便可 github com的ip 打开hos
  • 【Linux实操】vi和vim编辑器的使用(vim三种模式的切换)

    vim三种模式介绍及切换 一 Linux实操vi和vim编辑器的使用 1 正常模式 2 插入模式 编辑模式 3 命令行模式 二 vim的三种模式的相互转换 三 vi vim快捷键一览图 一 Linux实操vi和vim编辑器的使用 所有的 L
  • 获取剪贴板内容

  • MySQL命令alter add:增加表的字段

    alter add命令用来增加表的字段 alter add命令格式 alter table 表名 add字段 类型 其他 例如 在表MyClass中添加了一个字段passtest 类型为int 4 默认值为0 mysql gt alter
  • centos通过rpm包实现内核升级

    一 查看当前内核版本 root lvs uname r 3 10 0 1160 el7 x86 64 二 前往链接 elrepo获取最新的repo包 rpm import https www elrepo org RPM GPG KEY e
  • 高安全等级密码模块安全技术设计

    摘 要 随着金融 大数据等行业的普及和发展 对密码设备的依赖与日俱增 并且业内在数据安全领域提出了多方面更高的要求 例如密码模块的物理安全 抗非入侵式攻击 抗环境失效等 迫切需要更高安全等级的密码模块来支撑行业的实际应用需求 依托安全二级密
  • 【Linux命令—shell】正则表达式

    正则表达式 regular expression 描述一个字符集合的表达方式 模糊匹配 目录 1 基本正则 2 扩展正则 3 兼容的正则 perl 4 综合案例练习 1 基本正则 演示如下 2 扩展正则 注意 grep不支持扩展正则 如果需
  • Python中os.listdir和os.walk的区别

    os listdir和os walk都是获取指定目录下的文件内容 两者有一定的区别 现在举例说明 如下图所示目录结构 os walk import os def file name file site for root dirs files
  • pandas学习笔记(一)---创建dataframe的4种常用方式

    一 使用numpy创建 import pandas as pd import numpy as np df pd DataFrame np arange 16 reshape 4 4 index list abcd columns one
  • 【Python学习笔记】Python中的heapq

    Python中的heapq 1 基本介绍 堆是非线性的树形的数据结构 有两种堆 大根堆与小根堆 大根堆 树中各个父节点的值总是大于或等于任何一个子节点的值 小根堆 树中各个父节点的值总是小于或等于任何一个子节点的值 我们一般使用二叉堆来实现
  • python稳定版本是哪些_python3哪个版本稳定_后端开发

    C语言中关系表达式和逻辑表达式的值是什么 后端开发 关系表达式和逻辑表达式的值是布尔型 分别为真 true 或假 false 即0或1 但c语言没有布尔类型 以0为假 非0即真 python3哪个版本稳定 python3中3 4比较稳定 基
  • android状态栏(沉浸式状态栏,改变状态栏字体颜色,背景颜色)

    通过主题设置状态栏 在API21 android 5 0 之后 设置状态栏透明效果为半透明 并且为了保证在API19 android 4 4 正常使用 所以需要3份不同的style文件 即values v19 android 4 4之后使用
  • ajax请求,进行ajax处理后端特殊字符串

    前端传入officeId的值 将office对应ip地址传入到 function getinipaddress var officeId document getElementById officeId value var isinheri
  • Linux学习第16天:Linux设备树下的LED驱动开发:举一反三 专注专心专业

    Linux版本号4 1 15 芯片I MX6ULL 大叔学Linux 品人间百味 思文短情长 在开题之前 先说一下这次的题目 尤其是后面的 举一反三 专注专心专业 到底想给大家传递什么信息 LED驱动开发 目前为止已经学了好几种方法 包括裸