linux驱动(四):platform
本文主要探讨x210驱动的平台设备类型(platform)以及misc设备。
驱动模型
设备驱动模型:总线(bus type)、设备(device)和驱动(driver)
总线:虚拟总线用于挂接驱动驱动和设备
总线、设备、驱动关系:/sys/bus下的子目录对应不同总线,总线目录有设备、驱动目录和、总线属性文件

总线
struct bus_type {const char *name;struct bus_attribute *bus_attrs;struct device_attribute *dev_attrs;struct driver_attribute *drv_attrs;int (*match)(struct device *dev, struct device_driver *drv);int (*uevent)(struct device *dev, struct kobj_uevent_env *env);int (*probe)(struct device *dev);int (*remove)(struct device *dev);void (*shutdown)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;struct bus_type_private *p;
};
总线属性
struct bus_attribute {struct attribute attr;ssize_t (*show)(struct bus_type *bus, char *buf);ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
设备属性
struct device_attribute {struct attribute attr;ssize_t (*show)(struct device *dev, struct device_attribute *attr,char *buf);ssize_t (*store)(struct device *dev, struct device_attribute *attr,const char *buf, size_t count);
};
驱动属性
struct driver_attribute {struct attribute attr;ssize_t (*show)(struct device_driver *driver, char *buf);ssize_t (*store)(struct device_driver *driver, const char *buf,size_t count);
};
公共属性结构体(show(read)和store(write)方法)
struct attribute {const char *name;struct module *owner;mode_t mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOCstruct lock_class_key *key;struct lock_class_key skey;
#endif
};
总线示例
struct bus_type i2c_bus_type = {.name = "i2c",.match = i2c_device_match,.probe = i2c_device_probe,.remove = i2c_device_remove,.shutdown = i2c_device_shutdown,.pm = &i2c_device_pm_ops,
};
name总线名称,struct bus_attribute,struct device_attribute,struct driver_attribut为总线,设备,驱动属性和方法
match为设备和驱动匹配函数,uevent内核向用户通知事件,probe探测函数,remove移除函数,shutdown关闭函数,suspend挂起,resume唤醒,struct dev_pm_ops *pm;电源管理,struct bus_type_private *p;私有数据
struct bus_type_private {struct kset subsys;struct kset *drivers_kset;struct kset *devices_kset;struct klist klist_devices;struct klist klist_drivers;struct blocking_notifier_head bus_notifier;unsigned int drivers_autoprobe:1;struct bus_type *bus;
};
struct kset subsys;总线子系统,kobj为子系统顶层目录
struct kset *drivers_kset;struct kset *devices_kset;挂载到该总线上的驱动和设备集合
struct klist klist_devices;struct klist klist_drivers;设备和驱动链表
unsigned int drivers_autoprobe:1;注册时自动探测设备
struct bus_type *bus;回指针
设备
struct device
{struct device *parent;struct device_private *p;struct kobject kobj;const char *init_name; /* initial name of the device */struct device_type *type;struct mutex mutex; /* mutex to synchronize calls to* its driver.*/struct bus_type *bus; /* type of bus device is on */struct device_driver *driver; /* which driver has allocated thisdevice */void *platform_data; /* Platform specific data, devicecore doesn't touch it */struct dev_pm_info power;#ifdef CONFIG_NUMAint numa_node; /* NUMA node this device is close to */
#endifu64 *dma_mask; /* dma mask (if dma'able device) */u64 coherent_dma_mask;/* Like dma_mask, but foralloc_coherent mappings asnot all hardware supports64 bit addresses for consistentallocations such descriptors. */struct device_dma_parameters *dma_parms;struct list_head dma_pools; /* dma pools (if dma'ble) */struct dma_coherent_mem *dma_mem; /* internal for coherent memoverride *//* arch specific additions */struct dev_archdata archdata;
#ifdef CONFIG_OFstruct device_node *of_node;
#endifdev_t devt; /* dev_t, creates the sysfs "dev" */spinlock_t devres_lock;struct list_head devres_head;struct klist_node knode_class;struct class *class;const struct attribute_group **groups; /* optional groups */void (*release)(struct device *dev);
}
device结构体用于描述设备
struct device *parent;父设备
struct device_private *p;私有数据
struct device_private {struct klist klist_children;struct klist_node knode_parent;struct klist_node knode_driver;struct klist_node knode_bus;void *driver_data;struct device *device;
};
const char *init_name;设备名
struct bus_type *bus;指向总线
struct device_type *type;设备处理函数
struct device_type {const char *name;const struct attribute_group **groups;int (*uevent)(struct device *dev, struct kobj_uevent_env *env);char *(*devnode)(struct device *dev, mode_t *mode);void (*release)(struct device *dev);const struct dev_pm_ops *pm;
};
struct device_driver *driver;设备驱动
struct kobject kobj;内嵌kobject
struct kobject {const char *name;struct list_head entry;struct kobject *parent;struct kset *kset;struct kobj_type *ktype;struct sysfs_dirent *sd;struct kref kref;unsigned int state_initialized:1;unsigned int state_in_sysfs:1;unsigned int state_add_uevent_sent:1;unsigned int state_remove_uevent_sent:1;unsigned int uevent_suppress:1;
};
void (*release)(struct device *dev);释放设备回调函数
dev_t devt;设备号
struct class *class;设备类类指针
void *platform_data;平台设备数据(gpio、中断号、设备名称等)
设备注册和注销
int device_register(struct device *dev);
void device_unregister(struct device *dev);
宏DEVICE_ATTR定义attribute结构
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
创建和删除device目录下的属性文件
int device_create_file(struct device *dev,const struct device_attribute *attr);
void device_remove_file(struct device *dev,const struct device_attribute *attr);
驱动
struct device_driver {const char *name;struct bus_type *bus;struct module *owner;const char *mod_name; /* used for built-in modules */bool suppress_bind_attrs; /* disables bind/unbind via sysfs */#if defined(CONFIG_OF)const struct of_device_id *of_match_table;
#endifint (*probe) (struct device *dev);int (*remove) (struct device *dev);void (*shutdown) (struct device *dev);int (*suspend) (struct device *dev, pm_message_t state);int (*resume) (struct device *dev);const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p;
}
const char *name;驱动名字与设备名字相同总线match匹配函数才可对应找到
struct bus_type *bus;指向驱动总线
const char *mod_name;驱动模块名字
probe驱动探测方法(装载使用),remove删除驱动,shutdown关闭驱动方法,suspend挂起方法,resume唤醒方法
struct driver_private *p;设备驱动私有数据
struct driver_private {struct kobject kobj;struct klist klist_devices;struct klist_node knode_bus;struct module_kobject *mkobj;struct device_driver *driver;
};
const struct attribute_group **groups;驱动属性组
struct attribute_group {const char *name;mode_t (*is_visible)(struct kobject *,struct attribute *, int);struct attribute **attrs;
};
驱动程序注册和注销
int driver_register(struct device_driver *drv);
void driver_unregister(struct device_driver *drv);
驱动属性文件删除和创建
int driver_create_file(struct device_driver *drv, const struct driver_attribute *attr);
void driver_remove_file(struct device_driver *drv,const struct driver_attribute *attr);
platform(drivers/base/platform.c)
平台设备:wdt、i2c、i2s、rtc,adc等
CPU与外部通信:地址总线、专用接口
平台总线为地址总线式连接设备(soc内部外设)
平台设备(struct platform_device)
struct platform_device {const char * name;int id;struct device dev;u32 num_resources;struct resource * resource;const struct platform_device_id *id_entry;/* arch specific additions */struct pdev_archdata archdata;
};
name设备名,struct device dev;设备结构体
const struct platform_device_id *id_entry;设备ID表
struct pdev_archdata archdata;预留
struct resource * resource;资源数组
u32 num_resources;设备使用资源数量
struct resource {resource_size_t start;resource_size_t end;const char *name;unsigned long flags;struct resource *parent, *sibling, *child;
};
static struct resource s3c_wdt_resource[] = {[0] = {.start = S3C_PA_WDT,.end = S3C_PA_WDT + SZ_1M - 1,.flags = IORESOURCE_MEM,},[1] = {.start = IRQ_WDT,.end = IRQ_WDT,.flags = IORESOURCE_IRQ,}
};
start资源起始地址(WTCON),资源结束地址,name资源名,flags资源类型(IORESOURCE_MEM内存资源)
start资源起始地址(IRQ_WDT中断开始信号),资源结束地址(IRQ_WDT中断结束信号),flags资源类型(IORESOURCE_IRQ中断资源)
flags标志:I/O端口(IORESOURCE_IO)、内存资源(IORESOURCE_MEM)、中断号(IORESOURCE_IRQ)、DMA资源(IORESOURCE_DMA)
struct resource *parent, *sibling, *child;构建资源设备树
平台设备函数
int platform_device_add(struct platform_device *pdev);
void platform_device_del(struct platform_device *pdev);
int platform_device_register(struct platform_device *pdev);
void platform_device_unregister(struct platform_device *pdev);
struct resource *platform_get_resource(struct platform_device *dev,unsigned int type, unsigned int num);
平台设备驱动
struct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver;const struct platform_device_id *id_table;
};
struct device_driver driver;设备驱动结构体
const struct platform_device_id *id_table;设备ID表
probe驱动探测方法(装载使用),remove删除驱动,shutdown关闭驱动方法,suspend挂起方法,resume唤醒方法
平台驱动注册(probe)和注销(remove)
int platform_driver_register(struct platform_driver *drv);
void platform_driver_unregister(struct platform_driver *drv);
misc
杂项主设备号通常为10
设备类文件:/sys/class/misc

混杂设备
struct miscdevice {int minor;const char *name;const struct file_operations *fops;struct list_head list;struct device *parent;struct device *this_device;const char *nodename;mode_t mode;
};
minor次设备号,name设备名,fops设备操作函数,this_device当前设备指针
混杂设备的注册和注销
int misc_register(struct miscdevice * misc);
int misc_deregister(struct miscdevice *misc);
210蜂鸣器(x210-buzzer.c)
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <plat/gpio-cfg.h>//定义设备名
#define DEVICE_NAME "buzzer"//定义cmd
#define PWM_IOCTL_SET_FREQ 1
#define PWM_IOCTL_STOP 0//定义信号量
static struct semaphore lock;//初始化buzzer,设置频率
// TCFG0在Uboot中设置,这里不再重复设置
// Timer0输入频率Finput=pclk/(prescaler1+1)/MUX1=66M/16/16
// TCFG0 = tcnt = (pclk/16/16)/freq;
// PWM0输出频率Foutput =Finput/TCFG0= freq
static void PWM_Set_Freq( unsigned long freq )
{unsigned long tcon;unsigned long tcnt;unsigned long tcfg1;struct clk *clk_p;unsigned long pclk;//unsigned tmp;//设置GPD0_2为PWM输出s3c_gpio_cfgpin(S5PV210_GPD0(2), S3C_GPIO_SFN(2));tcon = __raw_readl(S3C2410_TCON);tcfg1 = __raw_readl(S3C2410_TCFG1);//mux = 1/16tcfg1 &= ~(0xf<<8);tcfg1 |= (0x4<<8);__raw_writel(tcfg1, S3C2410_TCFG1);clk_p = clk_get(NULL, "pclk");pclk = clk_get_rate(clk_p);tcnt = (pclk/16/16)/freq;__raw_writel(tcnt, S3C2410_TCNTB(2));__raw_writel(tcnt/2, S3C2410_TCMPB(2));//占空比为50%tcon &= ~(0xf<<12);tcon |= (0xb<<12); //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0__raw_writel(tcon, S3C2410_TCON);tcon &= ~(2<<12); //clear manual update bit__raw_writel(tcon, S3C2410_TCON);
}//停止buzzer(改为输入模式)
void PWM_Stop( void )
{//将GPD0_2设置为inputs3c_gpio_cfgpin(S5PV210_GPD0(2), S3C_GPIO_SFN(0));
}//对应open,开锁
static int x210_pwm_open(struct inode *inode, struct file *file)
{if (!down_trylock(&lock))return 0;elsereturn -EBUSY;}//对应close,上锁
static int x210_pwm_close(struct inode *inode, struct file *file)
{up(&lock);return 0;
}// PWM:GPF14->PWM0(接收cmd,设置频率,关闭buzzer)
static int x210_pwm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{switch (cmd) {case PWM_IOCTL_SET_FREQ:printk("PWM_IOCTL_SET_FREQ:\r\n");if (arg == 0)return -EINVAL;PWM_Set_Freq(arg);break;case PWM_IOCTL_STOP:default:printk("PWM_IOCTL_STOP:\r\n");PWM_Stop();break;}return 0;
}static struct file_operations dev_fops = {.owner = THIS_MODULE,.open = x210_pwm_open,.release = x210_pwm_close, .ioctl = x210_pwm_ioctl,
};//定义msic设备
static struct miscdevice misc = {.minor = MISC_DYNAMIC_MINOR,.name = DEVICE_NAME,.fops = &dev_fops,
};//驱动装载
static int __init dev_init(void)
{int ret;init_MUTEX(&lock);ret = misc_register(&misc);/* GPD0_2 (PWMTOUT2) */ret = gpio_request(S5PV210_GPD0(2), "GPD0");if(ret)printk("buzzer-x210: request gpio GPD0(2) fail");s3c_gpio_setpull(S5PV210_GPD0(2), S3C_GPIO_PULL_UP);s3c_gpio_cfgpin(S5PV210_GPD0(2), S3C_GPIO_SFN(1));gpio_set_value(S5PV210_GPD0(2), 0);printk ("x210 "DEVICE_NAME" initialized\n");return ret;
}//驱动卸载
static void __exit dev_exit(void)
{misc_deregister(&misc);
}module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.9tripod.com");
MODULE_DESCRIPTION("x210 PWM Driver");
buzzer.c
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>#define DEVNAME "/dev/buzzer"#define PWM_IOCTL_SET_FREQ 1
#define PWM_IOCTL_STOP 0int main(void)
{int fd = -1;fd = open(DEVNAME, O_RDWR);if (fd < 0){perror("open");return -1;}ioctl(fd, PWM_IOCTL_SET_FREQ, 10000);sleep(3);ioctl(fd, PWM_IOCTL_STOP);close(fd);
}
demo:
使用平台总线方式驱动led(模仿leds-s3c24xx.c)
Makefile
KERN_DIR = /root/kernelobj-m += x210-led.oall:make -C $(KERN_DIR) M=`pwd` modules cp:cp *.ko /root/rootfs/driver.PHONY: clean
clean:make -C $(KERN_DIR) M=`pwd` modules clean
x210-led.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/leds.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <mach/gpio.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <mach/leds_x210-gpio.h>#define LED_OFF 1
#define LED_ON 0struct s5pv210_gpio_led
{struct led_classdev cdev;struct s5pv210_led_platdata *pdata;
};static inline struct s5pv210_gpio_led *pdev_to_gpio(struct platform_device *dev)
{return platform_get_drvdata(dev);
}static inline struct s5pv210_gpio_led *to_gpio(struct led_classdev *led_cdev)
{return container_of(led_cdev, struct s5pv210_gpio_led, cdev);
}static void s5pv210_led_set(struct led_classdev *led_cdev,enum led_brightness value)
{struct s5pv210_gpio_led *p = to_gpio(led_cdev);if(value == LED_OFF){gpio_set_value(p->pdata->gpio,LED_OFF);}else{gpio_set_value(p->pdata->gpio,LED_ON);}
}int s5pv210_led_probe(struct platform_device *dev)
{int ret = -1;struct s5pv210_led_platdata *pdata = dev->dev.platform_data;struct s5pv210_gpio_led *led;led = kzalloc(sizeof(struct s5pv210_gpio_led), GFP_KERNEL);if (led == NULL) {dev_err(&dev->dev, "No memory for device\n");return -ENOMEM;}platform_set_drvdata(dev, led);ret = gpio_request(pdata->gpio, pdata->name);if (ret != 0) {printk(KERN_ERR "gpio_request failed %d\n",ret);return ret;} else {gpio_direction_output(pdata->gpio,GPIOF_OUT_INIT_HIGH);}led->cdev.name = pdata->name;led->cdev.brightness = 0;led->cdev.brightness_set = s5pv210_led_set;led->pdata = pdata;ret = led_classdev_register(&dev->dev, &led->cdev);if (ret < 0) {printk(KERN_ERR "led classdev register failed\n");kfree(led);return ret;}return 0;
}static int s5pv210_led_remove(struct platform_device *dev)
{struct s5pv210_gpio_led *p = pdev_to_gpio(dev);led_classdev_unregister(&p->cdev);gpio_free(p->pdata->gpio);kfree(p);return 0;
}struct platform_driver s5pv210_led_driver[] ={[0] = {.probe = s5pv210_led_probe,.remove = s5pv210_led_remove,.driver = {.name = "led1",.owner = THIS_MODULE,}},[1] = {.probe = s5pv210_led_probe,.remove = s5pv210_led_remove,.driver = {.name = "led2",.owner = THIS_MODULE,}},[2] = {.probe = s5pv210_led_probe,.remove = s5pv210_led_remove,.driver = {.name = "led3",.owner = THIS_MODULE,}},
};static int __init led_dev_init(void)
{platform_driver_register(&s5pv210_led_driver[0]);platform_driver_register(&s5pv210_led_driver[1]);platform_driver_register(&s5pv210_led_driver[2]);return 0;
}static void __exit led_dev_exit(void)
{platform_driver_unregister(&s5pv210_led_driver[0]);platform_driver_unregister(&s5pv210_led_driver[1]);platform_driver_unregister(&s5pv210_led_driver[2]);
}module_init(led_dev_init);
module_exit(led_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("cxb");
MODULE_DESCRIPTION("led gpio module");
MODULE_ALIAS("led");
操作流程
vim arch/arm/mach-s5cpv210/include/mach/leds_x210-gpio.h添加设备特殊数据结构体(gpio、中断号、设备名称等)#ifndef __ASM_ARCH_LEDSGPIO_H
#define __ASM_ARCH_LEDSGPIO_H "leds-gpio.h"#define S5PV210_LEDF_ACTLOW (1<<0) /* LED is on when GPIO low */
#define S5PV210_LEDF_TRISTATE (1<<1) /* tristate to turn off */struct s5pv210_led_platdata {unsigned int gpio;unsigned int flags;char *name;char *def_trigger;
};#endif /* __ASM_ARCH_LEDSGPIO_H */vim arch/arm/mach-s5pv210/mach-x210.c添加设备特殊数据结构体#include <mach/leds_x210-gpio.h>定义如下平台总线设备到smdkc110_devices[]前static struct s5pv210_led_platdata x210_led1_pdata = {.name = "led1",.gpio = S5PV210_GPJ0(3),.flags = S5PV210_LEDF_ACTLOW | S5PV210_LEDF_TRISTATE,.def_trigger = "",
};static struct platform_device x210_led1 = {.name = "led1",.id = 0,.dev = {.platform_data = &x210_led1_pdata,},
};static struct s5pv210_led_platdata x210_led2_pdata = {.name = "led2",.gpio = S5PV210_GPJ0(4),.flags = S5PV210_LEDF_ACTLOW | S5PV210_LEDF_TRISTATE,.def_trigger = "",
};static struct platform_device x210_led2 = {.name = "led2",.id = 1,.dev = {.platform_data = &x210_led2_pdata,},
};static struct s5pv210_led_platdata x210_led3_pdata = {.name = "led3",.gpio = S5PV210_GPJ0(5),.flags = S5PV210_LEDF_ACTLOW | S5PV210_LEDF_TRISTATE,.def_trigger = "",
};static struct platform_device x210_led3 = {.name = "led3",.id = 2,.dev = {.platform_data = &x210_led3_pdata,},
};添加如下平台总线设备到smdkc110_devices[]&x210_led1
&x210_led2
&x210_led3make -j8 && cp arch/arm/boot/zImage ~/tftp -f make cp
结果示例:

相关文章:
linux驱动(四):platform
本文主要探讨x210驱动的平台设备类型(platform)以及misc设备。 驱动模型 设备驱动模型:总线(bus type)、设备(device)和驱动(driver) 总线:虚拟总线用于挂接驱动驱动和设备 总线、设备、驱动关系:/sys/bus下的子目录…...
Guava:Cache强大的本地缓存框架
Guava Cache是一款非常优秀的本地缓存框架。 一、 经典配置 Guava Cache 的数据结构跟 JDK1.7 的 ConcurrentHashMap 类似,提供了基于时间、容量、引用三种回收策略,以及自动加载、访问统计等功能。 基本的配置 Testpublic void testLoadingCache() th…...
#{}和${}的区别?
#{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译处理。Mybatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值。Mybatis在…...
string的模拟实现
string的模拟实现 msvc和g下的string内存比较成员变量构造函数与析构函数拷贝构造函数赋值拷贝c_str、size和capacity函数以及重载[]、clear、expand_capacity迭代器与遍历reservepush_back、append、insert字符串比较运算符erase<<流提取 >>流插入resizefindsubst…...
算法练习:查找二维数组中的目标值
题目: 编写一个高效的算法来搜索矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:每行的元素从左到右升序排列。每列的元素从上到下升序排列。 实现: 1. main方法 public static void main(String[] args) {int[][] matrix {{1…...
考研自命题资料、考题如何找
这篇文章是抖音和b站上上传的同名视频的原文稿件,感兴趣的csdn用户可以关注我的抖音和b站账号(GeekPower极客力量)。同时这篇文章也为视频观众提供方便,可以更加冷静地分析和思考。文章同时在知乎发表。 去年我发布了一个视频&am…...
MySQL 存储引擎和索引类型介绍
1. 引言 MySQL 是一个流行的关系型数据库管理系统,提供多种存储引擎以满足不同的业务需求。本文将介绍几种常见的 MySQL 存储引擎和索引类型比较,并给出相应的示例。 2. 存储引擎概述 2.1 InnoDB 存储引擎 InnoDB 是 MySQL 的默认存储引擎࿰…...
element-ui table height 属性导致界面卡死
问题: 项目上,有个点击按钮弹出抽屉的交互, 此时界面卡死 原因分析: 一些场景下(父组件使用动态单位/弹窗、抽屉中使用), element-ui 的 table 会循环计算高度值, 导致界面卡死 github 上的一些 issues 和解决方案: Issues ElemeFE/element GitHub 官方讲是升…...
Vue2.v-指令
v-if 在双引号中写判断条件。 <div v-if"score>90">A</div> <div v-else-if"score>80">B</div> <div v-else>C</div>v-on: :冒号后面跟着事件。 为了简化,可以直接用代替v-on:。 事件名“内联语…...
Java中SpringBoot组件集成接入【Knife4j接口文档(swagger增强)】
Java中SpringBoot组件集成接入【Knife4j接口文档】 1.Knife4j介绍2.maven依赖3.配置类4.常用注解使用1.实体类及属性(@ApiModel和@ApiModelProperty)2.控制类及方法(@Api、@ApiOperation、@ApiImplicitParam、 @ApiResponses)3.@ApiOperationSupport注解未生效的解决方法5.…...
继承和多态的详解
文章目录 1. 继承1.1 继承的概念1.3 继承的语法1.3 父类成员访问1.3.1 子类中访问父类的成员变量1.3.2 子类中访问父类的成员方法 1.4 子类构造方法 2.super关键字2.1 super关键字的概念2.2 super和this的区别 3. 在继承中访问限定符的可见性4. 继承方式的分类5. 多态5.1 多态的…...
【Unity】UniTask(异步工具)快速上手
UniTask(异步工具) 官方文档:https://github.com/Cysharp/UniTask/blob/master/README_CN.md URL:https://github.com/Cysharp/UniTask.git?pathsrc/UniTask/Assets/Plugins/UniTask 优点:0GC,可以在任何地方使用 为Unity提供一个高性能&…...
k8s三种常用的项目发布方式
k8s三种常用的项目发布方式 1、 蓝绿发布 2、 金丝雀发布(灰度发布):使用最多 3 、滚动发布 应用程序升级,面临的最大问题是新旧业务之间的切换。 项目的生命周期:立项----定稿----需求发布----开发----测试-----发布 最后测试之后上线。再…...
Nodejs搭配axios下载图片
新建一个文件夹,npm i axios 实测发现只需保留node_modules文件夹,删除package.json不影响使用 1.纯下载图片 其实该方法不仅可以下载图片,其他的文件都可以下载 const axios require(axios) const fs require(fs) var arrPic [https:…...
强化学习在生成式预训练语言模型中的研究现状简单调研
1. 绪论 本文旨在深入探讨强化学习在生成式预训练语言模型中的应用,特别是在对齐优化、提示词优化和经验记忆增强提示词等方面的具体实践。通过对现有研究的综述,我们将揭示强化学习在提高生成式语言模型性能和人类对话交互的关键作用。虽然这些应用展示…...
python_selenium_安装基础学习
目录 1.为什么使用selenium 2.安装selenium 2.1Chrome浏览器 2.2驱动 2.3下载selenium 2.4测试连接 3.selenium元素定位 3.1根据id来找到对象 3.2根据标签属性的属性值来获取对象 3.3根据xpath语句来获取对象 3.4根据标签的名字获取对象 3.5使用bs4的语法来获取对象…...
面试宝典进阶之关系型数据库面试题
D1、【初级】你都使用过哪些数据库? (1)MySQL:开源数据库,被Oracle公司收购 (2)Oracle:Oracle公司 (3)SQL Server:微软公司 (4&#…...
Agisoft Metashape 地面点分类参数设置
Agisoft Metashape 点云分类之地面点分类参数设置 文章目录 Agisoft Metashape 点云分类之地面点分类参数设置前言一、分类地面点参数二、农村及城区有房屋地区二、植被区域分类三、侵蚀半径(Erosion radius)参数设置前言 Agisoft Metashape提供了自动检测地面点的功能,减少…...
计算机科学速成课【学习笔记】(4)——二进制
本集课程B站链接: 4. 二进制-Representing Numbers and Letters with Binary_BiliBili_哔哩哔哩_bilibili4. 二进制-Representing Numbers and Letters with Binary_BiliBili是【计算机科学速成课】[40集全/精校] - Crash Course Computer Science的第4集视频&…...
数据库开发工具Navicat Premium 15 mac软件特色
Navicat Premium 15 mac版是一款数据库开发工具,Navicat Premium 15 Mac版可以让你以单一程序同時连接到 MySQL、MariaDB、SQL Server、SQLite、Oracle 和 PostgreSQL 数据库。 Navicat Premium mac软件特色 无缝数据迁移 数据传输,数据同步和结构同步…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
