Linux MISC 驱动实验

2023-10-31

misc 的意思是混合、杂项的,因此MISC 驱动也叫做杂项驱动,也就是当我们板子上的某些外设无法进行分类的时候就可以使用MISC 驱动。MISC 驱动其实就是最简单的字符设备驱动,通常嵌套在platform 总线驱动中,实现复杂的驱动,本章我们就来学习一下MISC 驱动的编写。

MISC 设备驱动简介

所有的MISC 设备驱动的主设备号都为10,不同的设备使用不同的从设备号。随着Linux字符设备驱动的不断增加,设备号变得越来越紧张,尤其是主设备号,MISC 设备驱动就用于解决此问题。MISC 设备会自动创建cdev,不需要像我们以前那样手动创建,因此采用MISC 设备驱动可以简化字符设备驱动的编写。我们需要向Linux 注册一个miscdevice 设备,miscdevice
是一个结构体,定义在文件include/linux/miscdevice.h 中,内容如下:

57 struct miscdevice {
58 int minor; /* 子设备号*/
59 const char *name; /* 设备名字*/
60 const struct file_operations *fops; /* 设备操作集*/
61 struct list_head list;
62 struct device *parent;
63 struct device *this_device;
64 const struct attribute_group **groups;
65 const char *nodename;
66 umode_t mode;
67 };

定义一个MISC 设备(miscdevice 类型)以后我们需要设置minor、name 和fops 这三个成员变量。minor 表示子设备号,MISC 设备的主设备号为10,这个是固定的,需要用户指定子设备号,Linux 系统已经预定义了一些MISC 设备的子设备号,这些预定义的子设备号定义在
include/linux/miscdevice.h 文件中,如下所示:

13 #define PSMOUSE_MINOR 1
14 #define MS_BUSMOUSE_MINOR 2 /* unused */
15 #define ATIXL_BUSMOUSE_MINOR 3 /* unused */
16 /*#define AMIGAMOUSE_MINOR 4 FIXME OBSOLETE */
17 #define ATARIMOUSE_MINOR 5 /* unused */
18 #define SUN_MOUSE_MINOR 6 /* unused */
......
52 #define MISC_DYNAMIC_MINOR 255

我们在使用的时候可以从这些预定义的子设备号中挑选一个,当然也可以自己定义,只要这个子设备号没有被其他设备使用接口。
name 就是此MISC 设备名字,当此设备注册成功以后就会在/dev 目录下生成一个名为name的设备文件。fops 就是字符设备的操作集合,MISC 设备驱动最终是需要使用用户提供的fops操作集合。
当设置好miscdevice 以后就需要使用misc_register 函数向系统中注册一个MISC 设备,此函数原型如下:

int misc_register(struct miscdevice * misc)

函数参数和返回值含义如下:
misc:要注册的MISC 设备。
返回值:负数,失败;0,成功。

以前我们需要自己调用一堆的函数去创建设备,比如在以前的字符设备驱动中我们会使用如下几个函数完成设备创建过程:

1 alloc_chrdev_region(); /* 申请设备号*/
2 cdev_init(); /* 初始化cdev */
3 cdev_add(); /* 添加cdev */
4 class_create(); /* 创建类*/
5 device_create(); /* 创建设备*/

现在我们可以直接使用misc_register 一个函数来完成示例代码57.1.3 中的这些步骤。当我们卸载设备驱动模块的时候需要调用misc_deregister 函数来注销掉MISC 设备,函数原型如下:

int misc_deregister(struct miscdevice *misc)

函数参数和返回值含义如下:
misc:要注销的MISC 设备。
返回值:负数,失败;0,成功。
以前注销设备驱动的时候,我们需要调用一堆的函数去删除此前创建的cdev、设备等等内容,如下所示:

1 cdev_del(); /* 删除cdev */
2 unregister_chrdev_region(); /* 注销设备号*/
3 device_destroy(); /* 删除设备*/
4 class_destroy(); /* 删除类*/

现在我们只需要一个misc_deregister 函数即可完成示例代码57.1.4 中的这些工作。关于MISC 设备驱动就讲解到这里,接下来我们就使用platform 加MISC 驱动框架来编写beep 蜂鸣器驱动。

硬件原理图分析

本章实验我们只使用到IMX6U-ALPHA 开发板上的BEEP 蜂鸣器,因此实验硬件原理图参考14.3 小节即可。

实验程序编写

本实验对应的例程路径为:开发板光盘-> 2、Linux 驱动例程-> 17_misc。
本章实验我们采用platform 加misc 的方式编写beep 驱动,这也是实际的Linux 驱动中很常用的方法。采用platform 来实现总线、设备和驱动,misc 主要负责完成字符设备的创建。

修改设备树

本章实验我们需要用到蜂鸣器,因此需要在imx6ull-alientek-emmc.dts 文件中创建蜂鸣器设备节点,这里我们直接使用46.3.1 小节创建的beep 这个设备节点即可。

beep 驱动程序编写

新建名为“19_miscbeep”的文件夹,然后在19_miscbeep 文件夹里面创建vscode 工程,工作区命名为“miscbeep。新建名为miscbeep.c 的驱动文件,在miscbeep.c 中输入如下所示内容:

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
/***************************************************************
Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
文件名		: miscbeep.c
作者	  	: 左忠凯
版本	   	: V1.0
描述	   	: 采用MISC的蜂鸣器驱动程序。
其他	   	: 无
论坛 	   	: www.openedv.com
日志	   	: 初版V1.0 2019/8/20 左忠凯创建
***************************************************************/
#define MISCBEEP_NAME		"miscbeep"	/* 名字 	*/
#define MISCBEEP_MINOR		144			/* 子设备号 */
#define BEEPOFF 			0			/* 关蜂鸣器 */
#define BEEPON 				1			/* 开蜂鸣器 */

/* miscbeep设备结构体 */
struct miscbeep_dev{
	dev_t devid;			/* 设备号 	 */
	struct cdev cdev;		/* cdev 	*/
	struct class *class;	/* 类 		*/
	struct device *device;	/* 设备 	 */
	struct device_node	*nd; /* 设备节点 */
	int beep_gpio;			/* beep所使用的GPIO编号		*/
};

struct miscbeep_dev miscbeep;		/* beep设备 */

/*
 * @description		: 打开设备
 * @param - inode 	: 传递给驱动的inode
 * @param - filp 	: 设备文件,file结构体有个叫做private_data的成员变量
 * 					  一般在open的时候将private_data指向设备结构体。
 * @return 			: 0 成功;其他 失败
 */
static int miscbeep_open(struct inode *inode, struct file *filp)
{
	filp->private_data = &miscbeep; /* 设置私有数据 */
	return 0;
}

/*
 * @description		: 向设备写数据 
 * @param - filp 	: 设备文件,表示打开的文件描述符
 * @param - buf 	: 要写给设备写入的数据
 * @param - cnt 	: 要写入的数据长度
 * @param - offt 	: 相对于文件首地址的偏移
 * @return 			: 写入的字节数,如果为负值,表示写入失败
 */
static ssize_t miscbeep_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
	int retvalue;
	unsigned char databuf[1];
	unsigned char beepstat;
	struct miscbeep_dev *dev = filp->private_data;

	retvalue = copy_from_user(databuf, buf, cnt);
	if(retvalue < 0) {
		printk("kernel write failed!\r\n");
		return -EFAULT;
	}

	beepstat = databuf[0];		/* 获取状态值 */
	if(beepstat == BEEPON) {	
		gpio_set_value(dev->beep_gpio, 0);	/* 打开蜂鸣器 */
	} else if(beepstat == BEEPOFF) {
		gpio_set_value(dev->beep_gpio, 1);	/* 关闭蜂鸣器 */
	}
	return 0;
}

/* 设备操作函数 */
static struct file_operations miscbeep_fops = {
	.owner = THIS_MODULE,
	.open = miscbeep_open,
	.write = miscbeep_write,
};

/* MISC设备结构体 */
static struct miscdevice beep_miscdev = {
	.minor = MISCBEEP_MINOR,
	.name = MISCBEEP_NAME,
	.fops = &miscbeep_fops,
};

 /*
  * @description     : flatform驱动的probe函数,当驱动与
  *                    设备匹配以后此函数就会执行
  * @param - dev     : platform设备
  * @return          : 0,成功;其他负值,失败
  */
static int miscbeep_probe(struct platform_device *dev)
{
	int ret = 0;

	printk("beep driver and device was matched!\r\n");
	/* 设置BEEP所使用的GPIO */
	/* 1、获取设备节点:beep */
	miscbeep.nd = of_find_node_by_path("/beep");
	if(miscbeep.nd == NULL) {
		printk("beep node not find!\r\n");
		return -EINVAL;
	} 

	/* 2、 获取设备树中的gpio属性,得到BEEP所使用的BEEP编号 */
	miscbeep.beep_gpio = of_get_named_gpio(miscbeep.nd, "beep-gpio", 0);
	if(miscbeep.beep_gpio < 0) {
		printk("can't get beep-gpio");
		return -EINVAL;
	}

	/* 3、设置GPIO5_IO01为输出,并且输出高电平,默认关闭BEEP */
	ret = gpio_direction_output(miscbeep.beep_gpio, 1);
	if(ret < 0) {
		printk("can't set gpio!\r\n");
	}
	
	/* 一般情况下会注册对应的字符设备,但是这里我们使用MISC设备
  	 * 所以我们不需要自己注册字符设备驱动,只需要注册misc设备驱动即可
	 */
	ret = misc_register(&beep_miscdev);
	if(ret < 0){
		printk("misc device register failed!\r\n");
		return -EFAULT;
	}

	return 0;
}

/*
 * @description     : platform驱动的remove函数,移除platform驱动的时候此函数会执行
 * @param - dev     : platform设备
 * @return          : 0,成功;其他负值,失败
 */
static int miscbeep_remove(struct platform_device *dev)
{
	/* 注销设备的时候关闭LED灯 */
	gpio_set_value(miscbeep.beep_gpio, 1);

	/* 注销misc设备 */
	misc_deregister(&beep_miscdev);
	return 0;
}

 /* 匹配列表 */
 static const struct of_device_id beep_of_match[] = {
     { .compatible = "atkalpha-beep" },
     { /* Sentinel */ }
 };
 
 /* platform驱动结构体 */
static struct platform_driver beep_driver = {
     .driver     = {
         .name   = "imx6ul-beep",         /* 驱动名字,用于和设备匹配 */
         .of_match_table = beep_of_match, /* 设备树匹配表          */
     },
     .probe      = miscbeep_probe,
     .remove     = miscbeep_remove,
};

/*
 * @description	: 驱动出口函数
 * @param 		: 无
 * @return 		: 无
 */
static int __init miscbeep_init(void)
{
	return platform_driver_register(&beep_driver);
}

/*
 * @description	: 驱动出口函数
 * @param 		: 无
 * @return 		: 无
 */
static void __exit miscbeep_exit(void)
{
	platform_driver_unregister(&beep_driver);
}

module_init(miscbeep_init);
module_exit(miscbeep_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zuozhongkai");

第29~94 行,标准的字符设备驱动。
第97~101 行,MISC 设备beep_miscdev,第98 行设置子设备号为144,第99 行设置设备名字为“miscbeep”,这样当系统启动以后就会在/dev/目录下存在一个名为“miscbeep”的设备文件。第100 行,设置MISC 设备的操作函数集合,为file_operations 类型。
第109~145 行,platform 框架的probe 函数,当驱动与设备匹配以后此函数就会执行,首先在此函数中初始化BEEP 所使用的IO。最后在138 行通过misc_register 函数向Linux 内核注册MISC 设备,也就是前面定义的beep_miscdev。
第152~160 行,platform 框架的remove 函数,在此函数中调用misc_deregister 函数来注销MISC 设备。
第163~196,标准的platform 驱动。

编写测试APP

新建miscbeepApp.c 文件,然后在里面输入如下所示内容:

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"
/***************************************************************
Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
文件名		: miscbeepApp.c
作者	  	: 左忠凯
版本	   	: V1.0
描述	   	: MISC驱动框架下的beep测试APP。
其他	   	: 无
使用方法	 :./miscbeepApp  /dev/miscbeep  0 关闭蜂鸣器
		     ./misdcbeepApp /dev/miscbeep  1 打开蜂鸣器
论坛 	   	: www.openedv.com
日志	   	: 初版V1.0 2019/8/20 左忠凯创建
***************************************************************/
#define BEEPOFF	0
#define BEEPON 	1

/*
 * @description		: main主程序
 * @param - argc 	: argv数组元素个数
 * @param - argv 	: 具体参数
 * @return 			: 0 成功;其他 失败
 */
int main(int argc, char *argv[])
{
	int fd, retvalue;
	char *filename;
	unsigned char databuf[1];
	
	if(argc != 3){
		printf("Error Usage!\r\n");
		return -1;
	}

	filename = argv[1];
	fd = open(filename, O_RDWR);	/* 打开beep驱动 */
	if(fd < 0){
		printf("file %s open failed!\r\n", argv[1]);
		return -1;
	}

	databuf[0] = atoi(argv[2]);	/* 要执行的操作:打开或关闭 */
	retvalue = write(fd, databuf, sizeof(databuf));
	if(retvalue < 0){
		printf("BEEP Control Failed!\r\n");
		close(fd);
		return -1;
	}

	retvalue = close(fd); /* 关闭文件 */
	if(retvalue < 0){
		printf("file %s close failed!\r\n", argv[1]);
		return -1;
	}
	return 0;
}

miscbeepApp.c 文件内容和其他例程的测试APP 基本一致,很简单,这里就不讲解了。

运行测试

编译驱动程序和测试APP

1、编译驱动程序
编写Makefile 文件,本章实验的Makefile 文件和第四十章实验基本一样,只是将obj-m 变量的值改为“miscbeep.o”,Makefile 内容如下所示:

KERNELDIR := /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
CURRENT_PATH := $(shell pwd)

obj-m := miscbeep.o

build: kernel_modules

kernel_modules:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules

clean:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

第4 行,设置obj-m 变量的值为“miscbeep.o”。
输入如下命令编译出驱动模块文件:

make -j32

编译成功以后就会生成一个名为“miscbeep.ko”的驱动模块文件。

2、编译测试APP
输入如下命令编译测试miscbeepApp.c 这个测试程序:

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

编译成功以后就会生成miscbeepApp 这个应用程序。

运行测试

将上一小节编译出来miscbeep.ko 和miscbeepApp 这两个文件拷贝到
rootfs/lib/modules/4.1.15 目录中,重启开发板,进入到目录lib/modules/4.1.15 中,输入如下命令加载miscbeep.ko 这个驱动模块。

depmod //第一次加载驱动的时候需要运行此命令
modprobe miscbeep.ko //加载设备模块

当驱动模块加载成功以后我们可以在/sys/class/misc 这个目录下看到一个名为“miscbeep”的子目录,如图57.4.2.1 所示:
在这里插入图片描述
所有的misc 设备都属于同一个类,/sys/class/misc 目录下就是misc 这个类的所有设备,每个设备对应一个子目录。
驱动与设备匹配成功以后就会生成/dev/miscbeep 这个设备驱动文件,输入如下命令查看这个文件的主次设备号:

ls /dev/miscbeep -l

结果如图57.4.2.2 所示:
在这里插入图片描述
从图57.4.2.2 可以看出,/dev/miscbeep 这个设备的主设备号为10,次设备号为144,和我们驱动程序里面设置的一致。
输入如下命令打开BEEP:

./miscbeepApp /dev/miscbeep 1 //打开BEEP

在输入如下命令关闭LED 灯:

./miscbeepApp /dev/miscbeep 0 //关闭BEEP

观察一下BEEP 能否打开和关闭,如果可以的话就说明驱动工作正常,如果要卸载驱动的话输入如下命令即可:

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

Linux MISC 驱动实验 的相关文章

  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • 如何在数组中存储包含双引号的命令参数?

    我有一个 Bash 脚本 它生成 存储和修改数组中的值 这些值稍后用作命令的参数 对于 MCVE 我想到了任意命令bash c echo 0 0 echo 1 1 这解释了我的问题 我将用两个参数调用我的命令 option1 without
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 如何在Linux内核源代码中打印IP地址或MAC地址

    我必须通过修改 Linux 内核源代码来稍微改变 TCP 拥塞控制算法 但为了检查结果是否正确 我需要记录 MAC 或 IP 地址信息 我使用 PRINTK 函数来打印内核消息 但我感觉很难打印出主机的MAC IP地址 printk pM
  • 如何将目录及其子目录中的所有 PDF 文件复制到一个位置?

    如何全部复制PDF文件从目录及其子目录到单个目录 实际上还有更多的文件 并且深度有些任意 假设四个目录的最大深度是公平的 我想这些文件需要重命名 如果a pdf例如 位于多个目录中 因为我会adding https ebooks stack
  • CentOS:无法安装 Chromium 浏览器

    我正在尝试在 centOS 6 i 中安装 chromium 以 root 用户身份运行以下命令 cd etc yum repos d wget http repos fedorapeople org repos spot chromium
  • Linux:在文件保存时触发 Shell 命令

    我想在修改文件时自动触发 shell 命令 我认为这可以通过注册 inotify 挂钩并调用来在代码中完成system 但是是否有更高级别的 bash 命令可以完成此任务 尝试 inotify 工具 我在复制链接时遇到问题 抱歉 但 Git
  • jpegtran 优化而不更改文件名

    我需要优化一些图像 但不更改它们的名称 jpegtran copy none optimize image jpg gt image jpg 但是 这似乎创建了 0 的文件大小 当我对不同的文件名执行此操作时 大小仍然完全相同 怎么样 jp
  • C语言中如何通过内存地址映射函数名和行号?

    如何用 GCC 中的内存地址映射回函数名称和行号 即假设一个 C 语言原型 void func Get the address of caller maybe this could be avoided MemoryAddress get
  • PHP 无法打开流:是一个目录

    非常简单的 PHP 脚本 我在我亲自设置的 Ubuntu Web 服务器上的 EE 模板中运行 我知道这与权限有关 并且我已经将我尝试写入的目录的所有者更改为 Apache 用户 我得到的错误是 遇到 PHP 错误 严重性 警告 消息 fi
  • jq中如何分组?

    这是 json 文档 name bucket1 clusterName cluster1 name bucket2 clusterName cluster1 name bucket3 clusterName cluster2 name bu
  • Linux 上有关 getBounds() 和 setBounds() 的 bug_id=4806603 的解决方法?

    在 Linux 平台上 Frame getBounds 和 Frame setBounds 的工作方式不一致 这在 2003 年就已经有报道了 请参见此处 http bugs java com bugdatabase view bug do
  • 如何使用 GOPATH 的 Samba 服务器位置?

    我正在尝试将 GOPATH 设置为共享网络文件夹 当我进入 export GOPATH smb path to shared folder I get go GOPATH entry is relative must be absolute
  • 如何更改 Apache 服务器的根目录? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何更改 Apache 服务器的文档根目录 我基本上想要localhost从 来 users spencer projects目录而不是
  • Gtk-ERROR **:检测到 GTK+ 2.x 符号

    我正在使用 gcc 编译我的 c 应用程序 并使用以下标志 gcc evis c pkg config cflags libs gtk 2 0 libs clutter gtk 1 0 libs gthread 2 0 Wall o evi
  • Linux 上的用户空间能否实现本机代码的抢占式多任务处理?

    我想知道是否可以在 Linux 用户空间的单个进程中实现本机代码的抢占式多任务处理 也就是说 从外部暂停一些正在运行的本机代码 保存上下文 交换到不同的上下文 然后恢复执行 所有这些都由用户空间精心安排 但使用可能进入内核的调用 我认为这可
  • 删除 Git 存储库,但保留所有文件

    在我使用 Linux 的过程中的某个时刻 我决定将我的主目录中的所有内容都放入源代码管理中是个好主意 我不是在问这是否是一个好主意 我是在问如何撤销它 删除存储库的原因是我最近安装了 Oh My Zsh 而且我非常喜欢它 问题是我的主目录有
  • 我不明白 execlp() 在 Linux 中如何工作

    过去两天我一直在试图理解execlp 系统调用 但我还在这里 让我直奔主题 The man pageexeclp 将系统调用声明为int execlp const char file const char arg 与描述 execl exe
  • php exec 返回的结果比直接进入命令行要少

    我有一个 exec 命令 它的行为与通过 Penguinet 给 linux 的相同命令不同 res exec cd mnt mydirectory zcat log file gz echo res 当将命令直接放入命令行时 我在日志文件

随机推荐

  • Nginx服务优化

    配置nginx隐藏版本号 隐藏nginx版本号 避免安全漏洞泄漏 方法一 修改配置文件法 root www conf vim usr local nginx confnginx conf 17 http 18 include mime ty
  • 图解---散列表(hash表)的基本原理以及hash冲突(碰撞)--易懂版

    图解 散列表 hash表 的基本原理以及hash冲突 碰撞 易懂版 散列表为什么诞生 它用于做什么 先说说数组 数组的优点是查找比较快 但是添加和删除效率比较低 再说说链表 链表的优点是添加和删除效率比较快 相对于数组 但是遍历需要一个指针
  • 一种软件网络验证方式的实现 + 网络验证转本地验证的一种实现(附VC源码)...

    目前很多软件都是通过网络验证来实现的 一种比较流行的方式便是把服务器端 如验证网页 放在服务器上 软件为客户端 当软件注册或启动时通过网络与服务器端进行数据交换 重新实现验证的目的 个人觉得网络验证将是一种趋势 做得好的网络验证方式将是对软
  • Spring 源码 事件监听

    2019独角兽企业重金招聘Python工程师标准 gt gt gt spring 监听器 一 事件监听机制概述 二 事件监听机制结构 三 Spring监听机制架构 Spring的Application拥有发布事件并且注册事件监听器的能力 拥
  • python验证码识别MuggleOCR通用识别使用

    先来看看MuggleOCR简介 白嫖 这是一个为麻瓜设计的本地OCR模块 只需要简单几步操作即可拥有两大通用识别模块 让你在工作中畅通无阻 这套模型是基于 https github com kerlomz captcha trainer 训
  • JSP注释(4种)

    说到注释 相信大家肯定都不陌生 它是对程序代码的解释和说明 注释可以提高代码的可读性 让他人能够更加轻松地了解代码 从而提高团队合作开发的效率 在 JSP 中可以使用以下 4 种注释 HTML 注释 带有 JSP 表达式的注释 隐藏注释 脚
  • 登录和注册的基本实现,超简单!

    前序 相信有很多的人在刚刚做项目的实现 登录与注册功能的实现是基本的要求 要是刚刚开始写的小伙伴肯定会有很多的困惑 这里我介绍一下自己的写法 希望能帮到你 也希望能免费点个小 这里就以之前我写的一个为例 大家可以根据自己的规则来更改 一 登
  • python 短路法提高二叉堆插入效率

    在学习 problem solving with algorithms and data structure using python 中的二叉堆时 其插入数据方法是将这个数据放在列表的尾部 然后通过一次次与父节点进行比较 并且交换 实现顺
  • 用Log4j 2记录日志

    说明 maven工程中增加对Log4j 2的依赖 下面代码示例的maven工程中的pom xml文件中需要增加对Log4j 2的依赖
  • -moz-transform:rotate()

    目前越来越多的浏览器兼容CSS3标准了 就连IE浏览器老大哥也开始向CSS3低头 微软宣布IE9浏览器支持更多的CSS3属性 IE9更注重HTML5标准 不过CSS3里有一个使对象旋转的属性transform rotate 号称兼容CSS3
  • 2023高教社杯 国赛数学建模B题思路 - 多波束测线问题

    1 赛题 B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术 声波在均匀介质中作匀 速直线传播 在不同界面上产生反射 利用这一原理 从测量船换能器垂直向海底发射声波信 号 并记录从声波发射到信号接收的传播时间
  • springboot定时任务

    1 配置 在主函数加 EnableScheduling 定时任务 package com biubiu import org springframework boot SpringApplication import org springf
  • golang的web框架Gin(一)---Gin的安装与初体验

    简介 1 1 介绍 Go世界里最流行的Web框架 Github上有32K star 基于httprouter开发的Web框架 中文文档齐全 简单易用的轻量级框架 Gin是一个golang的微框架 封装比较优雅 API友好 源码注释比较明确
  • [已解决]运行 ‘tomcat8‘ 出错: 无法打开调试器端口 (127.0.0.1:6672): java.net.SocketException

    解决 运行 tomcat8 出错 无法打开调试器端口 127 0 0 1 6672 java net SocketException 修改HTTP port端口号 没占用的端口号都可以 建议8000以上的数字 只要不是现在的端口号就可以 修
  • ARM(IMX6U)裸机按键输入实验(BSP+SDK、GPIO输入与输出、按键消抖)

    参考 Linux之ARM IMX6U 裸机按键输入实验 GPIO的输出与输入 作者 一只青木呀 发布时间 2020 08 17 21 43 37 网址 https blog csdn net weixin 45309916 article
  • Python实现顺序表

    Python实现顺序表 关于顺序表的介绍 请参考 https blog csdn net weixin 43790276 article details 103848039 Python 中的列表和元组都属于顺序表 下面根据顺序表的特性 自
  • 段错误的调试方法(printf输出、GDB)

    参考 段错误产生原因及简单的调试方法 参考 如何解决段错误 参考 C语言gdb调试之精髓 常用命令 多进程 多线程 程序日志 网址 https www bilibili com video BV1ei4y1V758 from search
  • 1031. 查验身份证(15)

    一个合法的身份证号码由17位地区 日期编号和顺序编号加1位校验码组成 校验码的计算规则如下 首先对前17位数字加权求和 权重分配为 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 然后将计算的和对11取模得到值Z 最
  • 艺赛旗RPA--经验分享:Python 中的“特殊”函数

    了解RPA www i search com cn 学习RPA https support i search com cn 私有函数 魔法函数 回调函数 在任何编程语言中 都会规定某些对象 属性 方法 函数 类等 只能够在某个范围内访问 出
  • Linux MISC 驱动实验

    目录 MISC 设备驱动简介 硬件原理图分析 实验程序编写 修改设备树 beep 驱动程序编写 编写测试APP 运行测试 编译驱动程序和测试APP 运行测试 misc 的意思是混合 杂项的 因此MISC 驱动也叫做杂项驱动 也就是当我们板子