Linux驱动开发之杂项设备注册和Linux2.6设备注册
目录
一、杂项设备注册
杂项设备注册简介
杂项设备注册特点:
杂项设备注册相关API
misc_register()
misc_deregister()
杂项设备注册相关例程
例程简介
源码分享
二、Linux 2.6设备注册
Linux2.6设备注册简介
Linux 2.6设备注册特点
Linux2.6设备注册流程
Linux2.6设备注册相关函数
alloc_chrdev_region()
unregister_chrdev_region()
cdev_init()
cdev_add()
cdev_del()
class_create()
device_create()
device_destroy()
class_destroy()
Linux2.6设备注册相关例程
例程简介
源码分享
三、选择建议
Linux设备驱动开发中,需要向内核正确注册设备,才能创建设备节点,以供应用层访问。本文将详细介绍Linux下的两种设备注册方法:杂项设备注册和Linux 2.6新方法注册。
一、杂项设备注册
杂项设备注册简介
杂项设备注册是Linux驱动开发中的一种设备注册方式。在Linux系统中,杂项设备是一类没有明确分类的设备,它们不属于字符设备、块设备或网络设备等特定类型。杂项设备可以包括各种不同类型的设备,如传感器、LED灯、温度计等。
杂项设备注册的目的是将这些杂项设备描述成设备文件,以便通过文件操作来控制和访问设备。通过设备文件,应用程序可以打开、关闭、读取和写入杂项设备,实现对设备的控制和数据交互。
在杂项设备注册中,使用struct miscdevice
结构体来描述设备的属性和设备文件的名字。该结构体包含了主设备号、次设备号、设备文件名和文件操作集合等信息。通过调用misc_register
函数,将杂项设备的核心结构体注册到内核中,完成设备的注册过程。
杂项设备注册的好处是它可以自动生成设备文件,无需手动创建。系统会根据设备的主设备号和次设备号,在/dev
目录下自动创建对应的设备文件。这样,应用程序可以直接通过设备文件来访问和控制杂项设备,简化了设备的管理和使用。
杂项设备注册特点:
- 主设备号固定为10,次设备号自动分配
- 注册后在/dev目录自动创建设备节点
- 每个主机最多256个杂项设备
杂项设备注册相关API
misc_register()
功能向内核注册一个杂项设备
头文件Linux/miscdevice.h
原型int misc_register(struct miscdevice * misc)
参数struct miscdevice * misc:杂项设备注册的核心结构体
返回值成功 0失败 负数struct miscdevice {//杂项注册核心结构体int minor; //次设备号const char *name; //设备的名字 会出现在 /dev/目录下const structfile_operations *fops; 操作集合结构体//以下内容可以不管struct list_head list;struct device *parent;struct device*this_device;const char *nodename;umode_t mode;
};
+++++++++++++++++++++++++++++++++++++++++++++++++++++
struct file_operations {//操作集合结构体,使用时需要实现内核编程接口:open/close/read/write等。structmodule *owner; //固定填写 THIS_MODULEint(*open) (struct inode *, struct file *); //内核层的open函数int(*release) (struct inode *, struct file *); //内核层的close函数……………………………………..};
misc_deregister()
功能 取消注册的杂项设备
头文件Linux/miscdevice.h
原型int misc_deregister(struct miscdevice*misc)
参数struct miscdevice *misc:杂项设备的核心结构体
返回值成功 0失败 负数
杂项设备注册相关例程
例程简介
这个例程的作用是实现一个蜂鸣器的控制功能。它包括了一个内核模块和一个用户态程序。
内核模块部分:
- 在模块初始化函数
bp_init
中,首先进行了地址映射,将控制寄存器和数据寄存器映射到内核空间。 - 然后设置了蜂鸣器的相关寄存器,包括将控制寄存器的低四位设置为1,将数据寄存器的最低位设置为0。
- 接下来,通过
misc_register
函数向内核注册了一个杂项设备。设置了该设备的打开和关闭函数,并指定了设备文件名和次设备号。 - 在模块退出函数
bp_exit
中,调用misc_deregister
函数取消注册杂项设备。
用户态程序部分:
- 在
main
函数中,通过open
函数打开设备文件/dev/bp_dev
,并指定了读写权限。 - 然后进入一个循环,每隔一秒钟打开蜂鸣器并输出提示信息,再关闭蜂鸣器并输出提示信息。
- 循环会一直执行,直到程序被手动终止。
源码分享
/*驱动层相关源码*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/io.h>void __iomem *GPD0_CON = NULL; //控制寄存器
void __iomem *GPD0_DAT = NULL; //数据寄存器struct file_operations bp_fops;
struct miscdevice bp_misc;//开启蜂鸣器函数
int bp_open (struct inode *inode, struct file *file){
printk("蜂鸣器开启\n");
*((unsigned int *)GPD0_DAT) |= 0x1;
return 0;
}//蜂鸣器关闭函数
int bp_close (struct inode *inode, struct file *file){
printk("蜂鸣器关闭\n");
*((unsigned int *)GPD0_DAT) &= ~(0x1);
return 0;
}static int __init bp_init(void){
printk("加载蜂鸣器模块\n");//地址映射
GPD0_CON = ioremap(0x114000a0, 2);
GPD0_DAT = ioremap(0x114000a4, 1);//寄存器设置
*((unsigned int *)GPD0_CON) &= ~(0xf);
*((unsigned int *)GPD0_CON) |= (0x1);
*((unsigned int *)GPD0_DAT) &= (0x1);//向内核注册一个杂项设备
bp_fops.open = bp_open; //打开蜂鸣器
bp_fops.release = bp_close; //关闭蜂鸣器
bp_fops.owner = THIS_MODULE; //模块所有者bp_misc.minor = 255; //系统分配次设备号
bp_misc.name = "bp_dev"; //设备文件名
bp_misc.fops = &bp_fops; //文件操作集合
misc_register(&bp_misc);return 0;
}static void __exit bp_exit(void){
printk("卸载蜂鸣器模块\n");
misc_deregister(&bp_misc);}module_init(bp_init);
module_exit(bp_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YYY");
/*用户层相关源码*/#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>int main(){int bp_fd =0;
while(1){bp_fd = open("/dev/bp_dev", O_RDWR);if(bp_fd < 0){printf("打开bp_dev失败\n");perror("open");}printf("开启蜂鸣器\n");sleep(1);close(bp_fd);printf("关闭蜂鸣器\n");sleep(1);
}
return 0;
}
二、Linux 2.6设备注册
Linux2.6设备注册简介
Linux 2.6内核引入了一种更灵活的设备注册机制,提供了设备模型来管理和注册设备。这种设备注册方式相对于旧版本的Linux内核更加面向对象,具有更好的可维护性和扩展性,也是当前比较最流行的设备注册方法。
Linux 2.6设备注册特点
- 提供更灵活的设备注册机制,主次设备号不再限定
- 注册后需要自行创建设备节点
- 支持模块化和多实例设计
- 可以灵活配置主次设备号
- 支持多实例和模块化设计
- 更好地处理多个设备的情况
Linux2.6设备注册流程
- 申请设备号(alloc_chrdev_region) 设备号由主设备号和次设备号组成,用于唯一标识一个设备。可以使用
alloc_chrdev_region
函数动态申请字符设备号,或者使register_chrdev_region
函数静态注册一个已知的设备号。 - 初始化cdev结构体(cdev_init)
cdev
结构体表示字符设备。开发者需要初始化这个结构体,并将它与设备的文件操作函数关联起来。这可以通过cdev_init
和cdev_add
函数来完成。 - 注册cdev结构体(cdev_add)
cdev_add
函数用于将cdev
结构体添加到系统中,使得内核可以管理和操作这个设备。 - 创建设备类(class_create) 使用
class_create
函数创建一个设备类,这个类将出现在/sys/class
目录下。 - 创建设备节点(device_create) 用
device_create
函数自动创建设备节点(通常位于/dev
目录下),而不是手动使用mknod
命令。
Linux2.6设备注册相关函数
alloc_chrdev_region()
功能向内核申请设备号
头文件Linux/fs.h
原型int alloc_chrdev_region(dev_t * dev, unsigned baseminor, unsigned count, const char * name)
参数dev_t *dev, 用来存放获取到的设备号的变量unsigned baseminor, 次设备号的起始位置 unsigned count, 要申请的设备号的数量 constchar *name 设备的名字
返回值成功 0失败 非零
unregister_chrdev_region()
功能释放设备号
头文件Linux/fs.h
原型void unregister_chrdev_region(dev_t from, unsigned count)
参数dev_t from, 要释放的设备号的起始位置 unsigned count 要释放的设备号的个数
返回值无
cdev_init()
功能初始化linux2.6的核心结构体
头文件Linux/cdev.h
原型void cdev_init(struct cdev *cdev, conststruct file_operations *fops);
参数struct cdev *cdev, linux2.6的核心结构体const struct file_operations *fops 操作集合结构体
返回值无
cdev_add()
功能注册一个linux2.6的核心结构体
头文件Linux/cdev.h
原型int cdev_add(struct cdev *, dev_t,unsigned);
参数struct cdev *cdev, linux2.6的核心结构体dev_t dev, 设备号unsigned count 向内核注册的linux2.6的核心结构体的个数 一般填1
返回值成功 0失败 错误码
cdev_del()
功能取消linux2.6核心结构体的注册
头文件Linux/cdev.h
原型void cdev_del(struct cdev *p)
参数struct cdev *p:linux2.6的核心结构体指针
返回值无
class_create()
功能创建类结构体
头文件Linux/device.h
原型struct class *class_create( struct module*owner, const char *name)
参数struct module *owner, :THIS_MODULEconst char *name :类结构体的名字
返回值成功 类结构体指针失败 NULL
device_create()
功能自动生成设备文件
头文件Linux/device.h
原型struct device *device_create(struct class*class, struct device *parent,dev_t devt, void *drvdata, const char*fmt, ...)
参数struct class *class, 类结构体的名字struct device *parent, NULLdev_t devt, 设备号void*drvdata, 传给设备的私有数据 NULLconst char *fmt,... 设备的名字 会出现在/dev/目录下
返回值成功 设备的结构体指针失败 NULL
device_destroy()
功能销毁设备文件
头文件Linux/device.h
原型void device_destroy(struct class *class,dev_t devt)
参数struct class *class, 类结构体dev_t devt 设备号
返回值无
class_destroy()
功能销毁类结构体
头文件Linux/device.h
原型void class_destroy(struct class *cls)
参数struct class *cls:类结构体
返回值无
Linux2.6设备注册相关例程
例程简介
这个Linux内核模块的例程实现了一个简单的 LED 流水灯控制。
- Linux内核模块部分:
- 定义了一个字符设备驱动,设备名为"myled"。这个驱动通过
myopen
和myclose
函数控制LED灯的开关,并实现了流水灯效果。 - 在
myled_init
函数中,首先通过alloc_chrdev_region
函数申请设备号,然后初始化cdev
结构体并通过cdev_add
函数将其添加到系统中。接着创建一个类结构体,并在该类下创建设备文件。 - 在
myled_exit
函数中,注销设备文件,注销类结构体,取消cdev
的注册,并释放设备号。
- 用户空间程序部分:
- 这个程序通过打开"/dev/myled"设备文件来控制LED灯的开关。每次打开设备文件时,LED灯会按照流水灯的效果亮起,每次关闭设备文件时,LED灯会熄灭。
- 程序会无限循环打开和关闭设备文件,从而实现LED灯的不断闪烁。
源码分享
/*驱动层源码*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>dev_t mydev;
int count;
struct cdev mycdev;
struct file_operations myfops;
struct class *myclass = NULL;//open函数实现,开灯,流水灯效果
int myopen (struct inode *inode, struct file *file){
if(count == 4)
count = 0;
gpio_set_value(EXYNOS4X12_GPM4(count), 0);
gpio_set_value(EXYNOS4_GPD0(0), 1);
count++;
printk("开灯%d\n", count);
return 0;
}//close函数实现,关灯,流水灯效果
int myclose (struct inode *inode, struct file *file){
gpio_set_value(EXYNOS4X12_GPM4(count - 1), 1);
gpio_set_value(EXYNOS4_GPD0(0), 0);
printk("关灯%d\n", count - 1);
return 0;
}static int __init myled_init(void){
//申请设备号alloc_chrdev_region(&mydev, 0, 1, "myled");
printk("申请到的设备号为 %d\n", mydev);
printk("主设备号 %d\n", MAJOR(mydev));
printk("次设备号 %d\n", MINOR(mydev));//初始化Linux2.6的核心结构体
myfops.owner = THIS_MODULE;
myfops.open = myopen;
myfops.release = myclose;
cdev_init(&mycdev, &myfops);//向内核注册一个Linux2.6核心结构体
cdev_add(&mycdev, mydev, 1);//创建一个类结构体
myclass = class_create(THIS_MODULE, "myled");
if(myclass == NULL){printk("创建类结构体失败\n");return -1;
}//创建设备文件
device_create(myclass, NULL, mydev, NULL, "myled");
return 0;
}static void __exit myled_exit(void){
//注销设备文件
device_destroy(myclass, mydev);//注销类结构体
class_destroy(myclass);//取消Linux2.6注册
cdev_del(&mycdev);//释放设备号
unregister_chrdev_region(mydev, 1);
}module_init(myled_init);
module_exit(myled_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YYY");
/*用户层源码*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>int main(){int led_fd = 0;
while(1){led_fd = open("/dev/myled", O_RDWR);if(led_fd < 0){printf("打开myled失败\n");perror("open");}printf("开灯\n");sleep(1);close(led_fd);printf("关灯\n");sleep(1);
}
return 0;
}
//申请设备号
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);//初始化注册cdev
void cdev_init(struct cdev *cdev, const struct file_operations *fops);
int cdev_add(struct cdev *cdev, dev_t dev, unsigned count);//创建设备节点
struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt,..);
三、选择建议
- 简单的字符设备推荐使用杂项设备注册
- 需要灵活控制主次设备号的复杂设备使用Linux 2.6方法
- 在模块化设计方面,Linux 2.6方式更优秀
相关文章:
Linux驱动开发之杂项设备注册和Linux2.6设备注册
目录 一、杂项设备注册 杂项设备注册简介 杂项设备注册特点: 杂项设备注册相关API misc_register() misc_deregister() 杂项设备注册相关例程 例程简介 源码分享 二、Linux 2.6设备注册 Linux2.6设备注册简介 Linux 2.6设备注册特点 Linux2.6设备注册流程 Linu…...
javafx写一个文档编辑器
文本编辑器是一种用于编辑纯文本文件的工具。它具有基本的文本编辑功能,如插入、删除、复制、粘贴等。文本编辑器通常不具备格式化文本、排版和图形编辑等高级功能,专注于纯文本的编辑。常见的文本编辑器包括记事本(Notepad)、Sublime Text、Visual Studio Code、Atom、Emacs…...
PHP与Angular详细对比 帮助你选择合适的项目技术
开发可有效扩展并提供诺克斯堡级安全性的Web应用程序和网站是每个开发人员的梦想。而使用这样的产品是每个用户的愿望。因此,为您的项目选择最合适和可靠的技术非常关键。 虽然PHP和Angular是完全不同的技术——PHP与JavaScript是一个更恰当的比较——但它们都广泛…...
基于立锜RTQ7882,支持全协议及DP显示功能的PD快充方案
在上一篇文章【基于RTQ7882的车载PD快充方案 - 大大通 (wpgdadatong.com)】中,已经对立锜科技(Richtek)及主打产品RTQ7882的基本功能作了介绍。 本文将分享RTQ7882近期新增的功能,以及其Cost Down版本。 旨…...
2023-12-25 LeetCode每日一题(不浪费原料的汉堡制作方案)
2023-12-25每日一题 一、题目编号 1276. 不浪费原料的汉堡制作方案二、题目链接 点击跳转到题目位置 三、题目描述 圣诞活动预热开始啦,汉堡店推出了全新的汉堡套餐。为了避免浪费原料,请你帮他们制定合适的制作计划。 给你两个整数 tomatoSlices …...
JavaScript 基础通关
快速熟悉 JavaScript 的基础语法,比较高级的比如事件放在后面的笔记中。 JavaScript 1. JavaScript 介绍 1.1 JavaScript 基本介绍 JavaScript 是一门运行在客户端(浏览器)的编程语言,实现人机交互的效果。实现网页特效、表单验…...
目标检测损失函数:IoU、GIoU、DIoU、CIoU、EIoU、alpha IoU、SIoU、WIoU原理及Pytorch实现
前言 损失函数是用来评价模型的预测值和真实值一致程度,损失函数越小,通常模型的性能越好。不同的模型用的损失函数一般也不一样。损失函数主要是用在模型的训练阶段,如果我们想让预测值无限接近于真实值,就需要将损失值降到最低…...
今年努力输出的嵌入式Linux视频
今年努力了一波,几个月周六日无休,自己在嵌入式linux工作有些年头,结合自己也是一直和SLAM工程师对接,所以输出了一波面向SLAM算法工程师Linux课程,当然嵌入式入门的同学也可以学习。下面是合作的官方前面发的宣传文章…...
python非常好用的文件系统监控库
如果你不想使用Watchdog库,而是自己编写代码来监视文件系统的变化,可以使用Python的内置模块os和time来实现。 下面是一个简单的示例代码,演示如何使用os和time模块来监视文件系统中文件的变化: pythonimport osimport timedef m…...
基于SpringBoot的电影购票系统
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的电影购票系统,java项目…...
Spring系列:Spring如何解决循环依赖
❤ 作者主页:欢迎来到我的技术博客😎 ❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~* 🍊 如果文章对您有帮助,记得关注、点赞、收藏、…...
netty源码:(40)ReplayingDecoder
ReplayingDecoder是ByteToMessageDecoder的子类,我们继承这个类时,也要实现decode方法,示例如下: package cn.edu.tju;import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handle…...
Apache Doris (五十五): Doris Join类型 - Colocation Join
🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录 1. Colocation Join原理...
计算机组成原理复习7
内存管理 文章目录 内存管理存储器概述存储器的分类按在计算机中的作用(层次)分类按存储介质分类按存取方式分类按信息的可保存性分类 存储器的性能指标存储容量单位成本存储速度:数据传输率数据的宽度/存储周期 存储器的层次化结构多级存储系…...
python使用openpyxl操作excel
文章目录 前提读取已有excel创建一个excel工作簿对象创建excel工作簿中的工作表获取工作表第一种:.active 方法第二种:通过工作表名获取指定工作表第三种:.get_sheet_name() 修改工作表的名称数据操作写入数据按单元格写入通过指…...
使用keepalived时虚拟IP漂移注意事项
什么是Keepalived服务 keepalived是一个开源的软件项目,用于实现高可用性(HA)的网络服务器负载均衡和故障转移。它允许将多台服务器组合在一起,形成一个虚拟服务器集群,实现负载均衡和故障转移。 keepalived的核心功…...
32阵元 MVDR和DREC DOA估计波束方向图对比
32阵元 MVDR和DREC DOA估计波束方向图对比 一、原理 MVDR原理:https://zhuanlan.zhihu.com/p/457528114 DREC原理(无失真响应特征干扰相消器):http://radarst.ijournal.cn/html/2019/3/201903018.html 主要参数: 阵…...
OpenCV-11颜色通道的分离与合并
本次我们使用两个比较重要的API split(mat)将图像的通道进行分割。 merge((ch1,ch2,ch3))将多个通道进行融合。 示例代码如下: import cv2 import numpy as npimg np.zeros((480, 640, 3),…...
从0到1入门C++编程——01 C++基础知识
文章目录 一、工具安装二、新建项目三、设置字体、注释、行号四、C基础知识1.数据类型2.输入输出3.运算符4.选择、循环结构5.跳转语句6.数组7.函数8.指针9.结构体 一、工具安装 学习C使用到的工具是Visual Studio,Visual Studio 2010旗舰版下载链接:点此…...
C#编程-编写和执行C#程序2
C#编程-编写和执行C#程序 问题陈述 Dvid所在的团队正在为网球比赛开发自动排名软件。他负责创建一个程序来接受网球选手的以下详细信息并将其显示在屏幕上: 1.姓名 2.排名 您需要帮助David创建该程序。 要创建所需的程序,David需要执行以下步骤: 1.打开“记事本”。 2.在“…...
Day02-ES6
一.proxy代理 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head>…...
2023年12月记录内容管理
文章目录 前言1.[vue构建项目](https://mp.csdn.net/mp_blog/creation/editor/134829688)2. [Nodejs后端express框架](https://mp.csdn.net/mp_blog/creation/editor/134841711)3. [前端知识点](https://mp.csdn.net/mp_blog/creation/editor/132810879)4.[前端知识点-vue篇&am…...
【测试基础】构造测试数据之 MySQL 篇
构造测试数据之 MySQL 篇 作为一名测试工程师,我们经常会构造测试数据进行一些功能验证。为了暴露更多的问题,在测试数据的构造上,我们应该尽可能的构造不同类型字段的数据,且一张表的字段最好不低于 10 10 10 个。 对于 MySQL …...
基于单片机的语音识别自动避障小车(论文+源码)
1.系统设计 此次基于单片机的语音识别自动避障小车,以STC89C52单片机作为系统的主控制器,利用超声波模块来实现小车与障碍物距离的测量并通过LCD液晶显示,当距离低于阈值时会通过WT588语音模块进行报警提示,并且小车会后退来躲避…...
2023年“中银杯”四川省职业院校技能大赛“云计算应用”赛项样题卷①
2023年“中银杯”四川省职业院校技能大赛“云计算应用”赛项(高职组) 样题(第1套) 目录 2023年“中银杯”四川省职业院校技能大赛“云计算应用”赛项(高职组) 样题(第1套) 模块一…...
【信息安全原理】——入侵检测与网络欺骗(学习笔记)
📖 前言:在网络安全防护领域,防火墙是保护网络安全的一种最常用的设备。网络管理员希望通过在网络边界合理使用防火墙,屏蔽源于外网的各类网络攻击。但是,防火墙由于自身的种种限制,并不能阻止所有攻击行为…...
JVM GC 算法原理概述
对于JVM的垃圾收集(GC),这是一个作为Java开发者必须了解的内容,那么,我们需要去了解哪些内容呢,其实,GC主要是解决下面的三个问题: 哪些内存需要回收? 什么时候回收&…...
【数值分析】LU分解解Ax=b,matlab自己编程实现
LU分解(直接三角分解,Doolittle分解) A x b , A L U Axb \,\,,\,\, ALU Axb,ALU { L y b U x y \begin{cases} Lyb \\ Uxy \end{cases} {LybUxy 矩阵 L {L} L 的对角元素为 1 {1} 1 ,矩阵 U {U} U 的第一行和 A {A} A …...
华为HCIE-Datacom课程介绍
厦门微思网络HCIE-Datacom课程介绍 一、认证简介 HCIE-Datacom(Huawei Certified ICT Expert-Datacom)认证是华为认证体系中的顶级认证,HCIE-Datacom认证定位具备坚实的企业网络跨场景融合解决方案理论知识,能够使用华为数通产品…...
QT(C++)-QTableWight添加行和删除空行
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、QTableWidget的添加行3、删除行 1、前言 最近要用QT开发项目,对QT不是很熟,就根据网上的查到的知识和自己的摸索,将一…...
公司做免费网站建设/搜索引擎广告案例
0x00 前言 随着微软越来越开放,C#也变得越来越吸引人们的眼球。而在游戏行业中,C#也开始慢慢地获得了关注。这不, 网易绝代双娇手游团队已经全面使用.Net Core支持前后端统一C#开发,跨平台部署了。 所以,我们就来总结一…...
专门做优选的网站/深圳推广服务
我们知道,swoole中有两大进程,分别是 master 主进程和 manager 管理进程。 (推荐学习:swoole视频教程)其中 master 主进程中会有一个主 reactor 线程和多个 reactor 线程,主要的作用就是用来维护TCP连接,处理网络IO&am…...
1号网站建设 高端网站建设/四川网站seo
题目链接:http://poj.org/problem?id2955 题意:求相互匹配的括号个数。 一道简单的区间dp,按常规的套路来写就可以了。 #include <iostream> #include <cstring> #include <string> using namespace std; int dp[110][110…...
ppt做多个网站/深圳做推广哪家比较好
这问题一般是在manifest.xml中没有配置相应的activity,或者配置的android:name 的路径不对,没写全。 可是今天我在manifest中已经配置正确了activity还有这错误。 原因在activity的构造方法 我的activity中的构造方法中写多了参数,导致跳转时…...
常州网站建设基本流程/网页设计制作
《Linux设备驱动程序》ioctl详解除了读取和写入设备之外,大部分驱动程序还需要通过设备驱动程序实行各种类型的硬件控制。简单的数据传输之外,大部分设备还可以执行其他一些操作,比如,用户空间经常会请求设备锁门,弹出…...
医疗网站建设计划书/长沙互联网推广公司
一般都是这么写: ifneq ($(KERNELRELEASE),) obj-m : else KERNELDIR ? /lib/modules/$(shell uname -r)/build PWD : $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M$(PWD) modules endif 这个makefile会用到两次。 第一次make的时候,KERNELR…...