Linux中断

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、中断的相关概念
    • 1.中断号
    • 2.中断的申请和释放
      • 申请API函数如下:
      • 释放API函数如下:
      • 中断处理函数如下:
      • 使能和禁止中断
  • 二、上半部分和下本部分
    • 1.tasklet
    • 2.工作队列
  • 三、设备树中对于中断的描述
  • 三、获取中断号
  • 四、实例如下


前言

使用Linux内核提供的API函数,完成中断的驱动开发。

一、中断的相关概念

1.中断号

中断号的作用是用来区分不同的中断类型,数据结构是int类型。

编写驱动的时候需要用到中断号,我们用到中断号,中断信息已经写到了设备树里面,因
此可以通过 irq_of_parse_and_map 函数从 interupts 属性中提取到对应的设备号,函数原型如下:
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
函数参数和返回值含义如下:
dev:设备节点。
index:索引号,interrupts 属性可能包含多条中断信息,通过 index 指定要获取的信息。
返回值:中断号。
如果使用 GPIO 的话,可以使用 gpio_to_irq 函数来获取 gpio 对应的中断号,函数原型如下:
int gpio_to_irq(unsigned int gpio)
函数参数和返回值含义如下:
gpio:要获取的 GPIO 编号。
返回值:GPIO 对应的中断号。

2.中断的申请和释放

Linux中使用中断要向内核提交申请,使用完成后要释放掉中断。

申请API函数如下:

int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
函数参数和返回值含义如下:
irq:要申请中断的中断号。
handler:中断处理函数,当中断发生以后就会执行此中断处理函数。
flags:中断标志,可以在文件 include/linux/interrupt.h 里面查看所有的中断标志
name:中断名字,设置以后可以在/proc/interrupts 文件中看到对应的中断名字。
dev:如果将 flags 设置为 IRQF_SHARED 的话,dev 用来区分不同的中断,一般情况下将
dev 设置为设备结构体,dev 会传递给中断处理函数 irq_handler_t 的第二个参数。
返回值:0 中断申请成功,其他负值 中断申请失败,如果返回-EBUSY 的话表示中断已经
被申请了

下图提供常用的中断标志
在这里插入图片描述
注意:request_irq函数可能会导致休眠,因此不能在中断上下文或者其他禁止休眠的代码段中使用 request_irq 函数。request_irq 函数会自动激活(使能)中断,所以不需要我们手动去使能中断。

释放API函数如下:

void free_irq(unsigned int irq, void *dev)
函数参数和返回值含义如下:
irq:要释放的中断。
dev:如果中断设置为共享(IRQF_SHARED)的话,此参数用来区分具体的中断。
共享中断只有在释放最后中断处理函数的时候才会被禁止掉。
返回值:无。

注意:如果中断不是共享的,那么 free_irq 会删除中断处理函数并且禁止中断

中断处理函数如下:

irqreturn_t (*irq_handler_t) (int, void *)
第一个参数是要中断处理函数要相应的中断号。第二个参数是一个指向 void 的指针,也就
是个通用指针,需要与 request_irq 函数的 dev 参数保持一致。用于区分共享中断的不同设备,
dev 也可以指向设备数据结构。
中断处理函数的返回值为 irqreturn_t 类型。其定义如下:
10 enum irqreturn {
11 IRQ_NONE = (0 << 0),
12 IRQ_HANDLED = (1 << 0),
13 IRQ_WAKE_THREAD = (1 << 1),
14 };
15
16 typedef enum irqreturn irqreturn_t;
可以看出 irqreturn_t 是个枚举类型,一共有三种返回值
一般中断服务函数返回值使用如下形式:
return IRQ_RETVAL(IRQ_HANDLED)

使能和禁止中断

void enable_irq(unsigned int irq)
void disable_irq(unsigned int irq)

disable_irq函数要等到当前正在执行的中断处理函数执行完才返回,因此使用者需要保证不会产生新的中断,并且确保所有已经开始执行的中断处理程序已经全部退出。那如何处理上述情况的使用如下函数:

void disable_irq_nosync(unsigned int irq)
disable_irq_nosync 函数调用以后立即返回,不会等待当前中断处理程序执行完毕。

上述三个函数是使能或者禁止某一中断,有时候需要使能和关闭整个系统的中断,使用如下函数:

local_irq_enable()
local_irq_disable()

在使用全局中断的时候有个问题,比如当程序A执行关闭10S中断,当2秒后程序B也执行了关闭全局中断,但过了3秒后,B程序又启用了全局中断,但这时候程序A关闭10S还没有结束,这种情况严重会导致系统崩溃。那该怎么解决呢,Linux中提供如下函数解决整个问题

local_irq_save(flags)
local_irq_restore(flags)

这两个函数是成对出现的,local_irq_save 函数用于禁止中断,并且将中断状态保存在 flags 中。local_irq_restore 用于恢复中断,将中断到 flags 状态。

二、上半部分和下本部分

当发生中断的时候,会进入中断处理函数,在函数中,我们希望时间越小越好,但往往事与愿违,在时间驱动编写的时候,在中断处理函数中,需要花费的时间不小,比如电容触摸屏通过中断通知 SOC 有触摸事件发生,SOC 响应中断,然后通过 IIC 接口读取触摸坐标值并将其上报给系统。但是我们都知道 IIC 的速度最高也只有400Kbit/S,所以在中断中通过 IIC 读取数据就会浪费时间。我们可以将通过 IIC 读取触摸数据的操作暂后执行,中断处理函数仅仅响应中断,然后清除中断标志位即可,这种方式就是Linux处理中断的过程:
上半部:上半部就是中断处理函数,那些处理过程比较快,不会占用很长时间的处理就可
以放在上半部完成。
下半部:如果中断处理过程比较耗时,那么就将这些比较耗时的代码提出来,交给下半部
去执行,这样中断处理函数就会快进快出。
比如在上半部将数据拷贝到内存中,关于数据的具体处理就可以放到下半部去执行。至于哪些代码属于上半部,哪些代码属于下半部并没有明确的规定,当然了也是有些经验可以参考的:
①、如果要处理的内容不希望被其他中断打断,那么可以放到上半部。
②、如果要处理的任务对时间敏感,可以放到上半部。
③、如果要处理的任务与硬件有关,可以放到上半部
④、除了上述三点以外的其他任务,优先考虑放到下半部。
那如何将上半部分和下半部分连接起来呢,Linux提供许多方法,可以百度查看一下,下面提供两种常用的方式

1.tasklet

Linux 内核使用 tasklet_struct 结构体来表示 tasklet:

484 struct tasklet_struct
485 {
486 struct tasklet_struct *next; /* 下一个 tasklet */
487 unsigned long state; /* tasklet 状态 */
488 atomic_t count; /* 计数器,记录对 tasklet 的引用数 */
489 void (*func)(unsigned long); /* tasklet 执行的函数 */
490 unsigned long data; /* 函数 func 的参数 */
491 };

第 489 行的 func 函数就是 tasklet 要执行的处理函数,用户定义函数内容,相当于中断处理
函数。如果要使用 tasklet,必须先定义一个 tasklet,然后使用 tasklet_init 函数初始化 tasklet,taskled_init 函数原型如下:

void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long), 
unsigned long data);
函数参数和返回值含义如下:
t:要初始化的 tasklet
func:tasklet 的处理函数。
data:要传递给 func 函数的参数
返回值:没有返回值也可以使用宏 DECLARE_TASKLET 来一次性完成 tasklet 的定义和初始化,
DECLARE_TASKLET 定义在 include/linux/interrupt.h 文件中,定义如下:
DECLARE_TASKLET(name, func, data)
其中 name 为要定义的 tasklet 名字,这个名字就是一个 tasklet_struct 类型的时候变量,func
就是 tasklet 的处理函数,data 是传递给 func 函数的参数。

在上半部,也就是中断处理函数中调用 tasklet_schedule 函数就能使 tasklet 在合适的时间运行,tasklet_schedule 函数原型如下:

void tasklet_schedule(struct tasklet_struct *t)
函数参数和返回值含义如下:
t:要调度的 tasklet,也就是 DECLARE_TASKLET 宏里面的 name。
返回值:没有返回值

使用tasklet的格式如下:

/* 定义 taselet */
struct tasklet_struct testtasklet;
/* tasklet 处理函数 */
void testtasklet_func(unsigned long data)
{/* tasklet 具体处理内容 */
}
/* 中断处理函数 */
irqreturn_t test_handler(int irq, void *dev_id)
{....../* 调度 tasklet */tasklet_schedule(&testtasklet);......
}
/* 驱动入口函数 */
static int __init xxxx_init(void)
{....../* 初始化 tasklet */tasklet_init(&testtasklet, testtasklet_func, data);/* 注册中断处理函数 */request_irq(xxx_irq, test_handler, 0, "xxx", &xxx_dev);......
}

2.工作队列

工作队列是另外一种下半部执行方式,工作队列在进程上下文执行,工作队列将要推后的
工作交给一个内核线程去执行,因为工作队列工作在进程上下文,因此工作队列允许睡眠或重新调度。因此如果你要推后的工作可以睡眠那么就可以选择工作队列,否则的话就只能选择软中断或 tasklet。
简单创建工作很简单,直接定义一个 work_struct 结构体变量即可,然后使用 INIT_WORK 宏来初始化工作,INIT_WORK 宏定义如下:

#define INIT_WORK(_work, _func)
_work 表示要初始化的工作,_func 是工作对应的处理函数。
也可以使用 DECLARE_WORK 宏一次性完成工作的创建和初始化,宏定义如下:
#define DECLARE_WORK(n, f)
n 表示定义的工作(work_struct),f 表示工作对应的处理函数。
和 tasklet 一样,工作也是需要调度才能运行的,工作的调度函数为 schedule_work,函数原
型如下所示:
bool schedule_work(struct work_struct *work)
函数参数和返回值含义如下:
work:要调度的工作。
返回值:0 成功,其他值 失败。

格式如下:

/* 定义工作(work) */
struct work_struct testwork;
/* work 处理函数 */
void testwork_func_t(struct work_struct *work);
{/* work 具体处理内容 */
}
/* 中断处理函数 */
irqreturn_t test_handler(int irq, void *dev_id)
{....../* 调度 work */schedule_work(&testwork);......
}
/* 驱动入口函数 */
static int __init xxxx_init(void)
{....../* 初始化 work */INIT_WORK(&testwork, testwork_func_t);/* 注册中断处理函数 */request_irq(xxx_irq, test_handler, 0, "xxx", &xxx_dev);......
}

三、设备树中对于中断的描述

如果使用设备树的话就需要在设备树中设置好中断属性信息,Linux 内核通过读取设备树中的中断属性信息来配置中断。
在imx6ull中描述中断控制器的节点在imx6ull.dtsi文件中

intc: interrupt-controller@00a01000 {compatible = "arm,cortex-a7-gic";#interrupt-cells = <3>;interrupt-controller;reg = <0x00a01000 0x1000>,<0x00a02000 0x100>;};

compatible 属性值为“arm,cortex-a7-gic”在 Linux 内核源码中搜索“arm,cortex-a7-gic”即可找到中断控制器驱动文件。
#interrupt-cells属性,描述了cells大小,可以在绑定文档中查看其含义:
在这里插入图片描述
第一个 cells:中断类型,0 表示 SPI 中断,1 表示 PPI 中断。
第二个 cells:中断号,对于 SPI 中断来说中断号的范围为 0~987,对于 PPI 中断来说中断
号的范围为 0~15。
第三个 cells:标志,bit[3:0]表示中断触发类型,为 1 的时候表示上升沿触发,为 2 的时候
表示下降沿触发,为 4 的时候表示高电平触发,为 8 的时候表示低电平触发。bit[15:8]为 PPI 中断的 CPU 掩码。
interrupt-controller 节点为空,表示当前节点是中断控制器

对于 gpio 来说,gpio 节点也可以作为中断控制器,比如 imx6ull.dtsi 文件中的 gpio5 节点内
容如下所示:

	gpio5: gpio@020ac000 {compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";reg = <0x020ac000 0x4000>;interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;gpio-controller;#gpio-cells = <2>;interrupt-controller;#interrupt-cells = <2>;};

interrupts描述中断源信息,属性值大小按照intc中设置填写,对于 gpio5 来说一共有两条信息,中断类型都是 SPI,触发电平都是 IRQ_TYPE_LEVEL_HIGH。不同之处在于中断源,一个是 74,一个是 75,打开可以打开《IMX6ULL 参考手册》的“Chapter 3 Interrupts and DMA Events”章节,找到表 3-1:
在这里插入图片描述
从上图中可以看出,GPIO5 一共用了 2 个中断号,一个是 74,一个是 75。其中 74 对应 GPIO5_IO00-GPIO5_IO15 这低 16 个 IO,75 对应 GPIO5_IO16~GPIOI5_IO31 这高 16 位 IO。
interrupt-controller 表明了 gpio5 节点也是个中断控制器,用于控制 gpio5 所有 IO的中断。
将#interrupt-cells 修改为 2,为什么是2呢,查看绑定信息
在这里插入图片描述
此绑定信息在目录\Documentation\devicetree\bindings\gpio
在这里插入图片描述
上边是NXP官方写的设备树,如果用户要使用该如何使用呢,下面举个例子:

1 fxls8471@1e {
2 compatible = "fsl,fxls8471";
3 reg = <0x1e>;
4 position = <0>;
5 interrupt-parent = <&gpio5>;
6 interrupts = <0 8>;
7 };
fxls8471 是 NXP 官方的 6ULL 开发板上的一个磁力计芯片,fxls8471 有一个中断引脚链接
到了 I.MX6ULL 的 SNVS_TAMPER0 因脚上,这个引脚可以复用为 GPIO5_IO00。
第 5 行,interrupt-parent 属性设置中断控制器,这里使用 gpio5 作为中断控制器。
第 6 行,interrupts 设置中断信息,0 表示 GPIO5_IO00,8 表示低电平触发。
简单总结一下与中断有关的设备树属性信息:
①、#interrupt-cells,指定中断源的信息 cells 个数。
②、interrupt-controller,表示当前节点为中断控制器。
③、interrupts,指定中断号,触发方式等。
④、interrupt-parent,指定父中断,也就是中断控制器

三、获取中断号

编写驱动的时候需要用到中断号,我们用到中断号,中断信息已经写到了设备树里面,因
此可以通过 irq_of_parse_and_map 函数从 interupts 属性中提取到对应的设备号,函数原型如下:

unsigned int irq_of_parse_and_map(struct device_node *dev,int index)
函数参数和返回值含义如下:
dev:设备节点。
index:索引号,interrupts 属性可能包含多条中断信息,通过 index 指定要获取的信息。
返回值:中断号。
如果使用 GPIO 的话,可以使用 gpio_to_irq 函数来获取 gpio 对应的中断号,函数原型如
下:
int gpio_to_irq(unsigned int gpio)
函数参数和返回值含义如下:
gpio:要获取的 GPIO 编号。
返回值:GPIO 对应的中断号。

四、实例如下

#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/export.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/semaphore.h>
#include <linux/timer.h>
#include <linux/of_irq.h>
#include <linux/irq.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/sched.h>
/***************************************************************
Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
文件名		: imx6uirq.c
作者	  	: 车文超
版本	   	: V1.0
描述	   	: Linux中断驱动实验
其他	   	: 无
论坛 	   	: 
日志	   	: 
***************************************************************/
#define IMX6ULL_CNT		1			    /* 设备号个数 	*/
#define IMX6ULL_NAME		"imx6ull"	/* 名字 		*/#define KEY0VALUE 0X01 /* KEY0 按键值 */
#define INVAKEY 0XFF /* 无效的按键值 */
#define KEY_NUM 1 /* 按键数量 */
/*按键设备*/
struct key_dev{int gpioid;		            /*gpio编号*/unsigned char value;		/*按键保存值*/char name[10];				/*按键名字*/int irqnum;				/*中断号*/irqreturn_t (*handler)(int, void *); /* 中断服务函数 */
};/* imx6uirq设备结构体 */
struct imx6ull_dev{dev_t devid;			/* 设备号 	 */struct cdev cdev;		/* cdev 	*/struct class *class;	/* 类 		*/struct device *device;	/* 设备 	 */int major;				/* 主设备号	  */int minor;				/* 次设备号   */struct device_node	*nd; /* 设备节点 */struct key_dev key0dev;	/*按键设备*/struct timer_list timerdev;/*定时器设备*/atomic_t keyvalue;/*按键值*/atomic_t release;/*按键释放值*/};struct imx6ull_dev imx6ulldev;	/* imx6ulldev */
/** @description		: 打开设备* @param - inode 	: 传递给驱动的inode* @param - filp 	: 设备文件,file结构体有个叫做private_data的成员变量* 					  一般在open的时候将private_data指向设备结构体。* @return 			: 0 成功;其他 失败*/
static int imx6ull_open(struct inode *inode, struct file *filp)
{filp->private_data = &imx6ulldev;	/* 设置私有数据 */return 0;
}/** @description     : 从设备读取数据 * @param - filp    : 要打开的设备文件(文件描述符)* @param - buf     : 返回给用户空间的数据缓冲区* @param - cnt     : 要读取的数据长度* @param - offt    : 相对于文件首地址的偏移* @return          : 读取的字节数,如果为负值,表示读取失败*/
static ssize_t imx6ull_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{struct imx6ull_dev *dev = (struct imx6ull_dev *)filp->private_data;int ret = 0;int value = 0;int release = 0;value = atomic_read(&dev->keyvalue);release = atomic_read(&dev->release);if(release ==1){if(value & 0x80){value &= ~0x80;ret = copy_to_user(buf,&value,sizeof(value));}else{goto data_error;}atomic_set(&dev->release,0);}else{return -EINVAL;}return ret;
data_error:return -EINVAL;
}/* 设备操作函数 */
static const struct file_operations imx6ull_fops = {.owner = THIS_MODULE,.open = imx6ull_open,.read = imx6ull_read,
};
/** @description	: 中断处理函数* @param 		: 无* @return 		: 无*/
static irqreturn_t key0_irq(int irq, void *dev_id){struct imx6ull_dev *dev = (struct imx6ull_dev *)dev_id;
#if 0value = gpio_get_value(dev->key0dev.gpioid);printk("value=%d\n\r", value);if(value == 0){printk("key0按下");}if(value ==1){printk("key0抬起");}
#endifdev->timerdev.data = (unsigned long)dev_id;mod_timer(&dev->timerdev, jiffies + msecs_to_jiffies(10));return 0;
}
/** @description	: 定时器中断函数* @param 		: 无* @return 		: 无*/
static void timer_func(unsigned long data)
{int value = 0;struct imx6ull_dev *dev = (struct imx6ull_dev *)data;value = gpio_get_value(dev->key0dev.gpioid);printk("value=%d\n\r", value);if(value == 0){printk("key0按下");atomic_set(&dev->keyvalue, dev->key0dev.value);}if(value ==1){printk("key0抬起");atomic_set(&dev->keyvalue, (dev->key0dev.value)|0x80);atomic_set(&dev->release,1);}}/** @description	: 按键初始化函数* @param 		: 无* @return 		: 无*/
static int key_myinit(struct imx6ull_dev *dev_id){int ret = 0	;struct imx6ull_dev *dev = (struct imx6ull_dev *)dev_id;/*1.获取节点*/dev->nd = of_find_node_by_path("/key");if(dev->nd == NULL){printk("of_find_node_by_path_erro\n\r");return -1;}/*2.获取GPIO编号*/dev->key0dev.gpioid = of_get_named_gpio(dev->nd, "key-gpios", 0);if(dev->key0dev.gpioid < 0){printk("of_get_named_gpio_erro\n\r");return -1;}/*3.申请IO*/memset(dev->key0dev.name, 0, sizeof(dev->key0dev.name));//sprintf(dev->keydev[i].name,"KEY%d",i);sprintf(dev->key0dev.name,"key%d",0);ret = gpio_request(dev->key0dev.gpioid,dev->key0dev.name);if(ret < 0){printk("gpio_request_erro\n\r");return -1;}gpio_direction_input(dev->key0dev.gpioid);/*4中断号获取*///dev->keydev[i].irqnum = gpio_to_irq(dev->keydev[i].gpioid);dev->key0dev.irqnum = irq_of_parse_and_map(dev->nd,0);printk("dev->key0dev.irqnum=%d\n\r",dev->key0dev.irqnum);dev->key0dev.handler = key0_irq;dev->key0dev.value = KEY0VALUE;/*5.注册中断*/ret = request_irq(dev->key0dev.irqnum, dev->key0dev.handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,dev->key0dev.name, &imx6ulldev);printk("ret=%d\n\r",ret);if(ret){printk("request_irq_erro\n\r");//goto file_irq;return -1;}/*初始化定时器*/init_timer(&imx6ulldev.timerdev);imx6ulldev.timerdev.function = timer_func;//file_irq:// free_irq(dev->key0dev.irqnum, &imx6ulldev);
return ret;
}
/** @description	: 驱动入口函数* @param 		: 无* @return 		: 无*/
static int __init imx6ull_init(void)
{/* 1、构建设备号 */if (imx6ulldev.major) {imx6ulldev.devid = MKDEV(imx6ulldev.major, 0);register_chrdev_region(imx6ulldev.devid, IMX6ULL_CNT, IMX6ULL_NAME);} else {alloc_chrdev_region(&imx6ulldev.devid, 0, IMX6ULL_CNT, IMX6ULL_NAME);imx6ulldev.major = MAJOR(imx6ulldev.devid);imx6ulldev.minor = MINOR(imx6ulldev.devid);}/* 2、注册字符设备 */cdev_init(&imx6ulldev.cdev, &imx6ull_fops);cdev_add(&imx6ulldev.cdev, imx6ulldev.devid, IMX6ULL_CNT);/* 3、创建类 */imx6ulldev.class = class_create(THIS_MODULE, IMX6ULL_NAME);if (IS_ERR(imx6ulldev.class)) {return PTR_ERR(imx6ulldev.class);}/* 4、创建设备 */imx6ulldev.device = device_create(imx6ulldev.class, NULL, imx6ulldev.devid, NULL, IMX6ULL_NAME);if (IS_ERR(imx6ulldev.device)) {return PTR_ERR(imx6ulldev.device);}/*key初始化*/key_myinit(&imx6ulldev);atomic_set(&imx6ulldev.keyvalue, INVAKEY);atomic_set(&imx6ulldev.release, 0);return 0;
}/** @description	: 驱动出口函数* @param 		: 无* @return 		: 无*/
static void __exit imx6ull_exit(void)
{/*释放中断号,释放IO*/free_irq(imx6ulldev.key0dev.irqnum, &imx6ulldev);gpio_free(imx6ulldev.key0dev.gpioid);/*删除定时器*/del_timer_sync(&imx6ulldev.timerdev);/*删除设备 *//*删除字符设备 */cdev_del(&imx6ulldev.cdev);/*删除设备号 */unregister_chrdev_region(imx6ulldev.devid, IMX6ULL_CNT);/*删除设备 */device_destroy(imx6ulldev.class, imx6ulldev.devid);/*删除类 */class_destroy(imx6ulldev.class);
}module_init(imx6ull_init);
module_exit(imx6ull_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("chewenchao");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/18862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

el-select 组件获取整个对象

法一&#xff1a;要获取整个对象的话&#xff0c;如果有列表就可以遍历列表&#xff0c;找到指定对象 let obj this.chainTaskList.find((item) > item.chainTaskNo e); if (obj) {this.form.storeNo obj.storeNo;this.form.storeName obj.couponVO.storeName; }或 fo…

AI推介-大语言模型LLMs论文速览(arXiv方向):2024.05.10-2024.05.20

文章目录~ 1.MeteoRA: Multiple-tasks Embedded LoRA for Large Language Models2.Zero-Shot Stance Detection using Contextual Data Generation with LLMs3.A Multi-Perspective Analysis of Memorization in Large Language Models4.Improved Content Understanding With E…

CF609D D. Gadgets for dollars and pounds

题目链接 题意&#xff1a; 在最少的时间内并且价格在s内从m个物品中购买k个物品 题解&#xff1a; 如果Nura能在x天内买到k个小玩意&#xff0c;那么她也能在x1天内买到这些小玩意。所以&#xff0c;这个答案是单调的。因此&#xff0c;我们可以使用二分查找来找到最小的天…

nvidia origin nx 刷机JETPACK 6

条件&#xff1a; 1.sdkmanager 链接&#xff1a;https://pan.baidu.com/s/1pmeT7_vKF_NXvP8xEhCelw?pwd8q1e 提取码&#xff1a;8q1e 2.ubuntu 20或者ubuntu22 3.nvidia orin nx Nvidia Jetson Orin NX&#xff08;一&#xff09;开始刷机_jetson nx刷机-CSDN博客

基于python实现的深度学习web多格式纠错系统

基于python实现的深度学习web多格式纠错系统 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 用户登录 登录功能是本系统一个非常重要的功能&#xff0c;这极大的保护了系统的安全。登录…

大模型智力升级:AI的未来之路

大模型的发展引领了人工智能的新时代&#xff0c;其强大的数据处理和学习能力在医疗、金融、教育等众多领域取得了令人瞩目的成就。然而&#xff0c;随之而来的挑战也不容忽视。尽管大模型在特定任务上展现出了卓越的性能&#xff0c;但它们在理解复杂语境、处理未见情况的能力…

Spring之 依赖项

文章目录 依赖注入基于构造函数的依赖注入基于 Setter 的依赖注入依赖解析过程依赖注入的示例 依赖关系和配置详细信息直接值&#xff08;原语、字符串等&#xff09;idref标签References to Other Beans &#xff08;对其他 Bean的引用&#xff09;Inner Beans&#xff08;内部…

【NumPy】全面解析add函数:高效数组加法操作

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

【全开源】Java共享茶室棋牌室无人系统支持微信小程序+微信公众号

打造智能化休闲新体验 一、引言&#xff1a;智能化休闲时代的来临 随着科技的飞速发展&#xff0c;智能化、无人化服务逐渐渗透到我们生活的各个领域。在休闲娱乐行业&#xff0c;共享茶室棋牌室无人系统源码的出现&#xff0c;不仅革新了传统的休闲方式&#xff0c;更为消费…

聊聊最近很火的混合专家模型(MoE)

前段时间&#xff0c;在2024年NVIDIA GTC大会上&#xff0c;英伟达不小心透露了GPT-4采用了MoE架构&#xff0c;模型有1.8万亿参数&#xff0c;由8个220B模型组成&#xff0c;与此前的GPT-4泄露的信息一致。 近半年多以来&#xff0c;各类MoE大模型更是层出不穷。在海外&#…

【Go】十一、标准化请求返回与viper管理配置文件的简单使用

请求返回的返回方法 这里指的是&#xff1a;传参的方式&#xff0c;类似与Java的r.setData() 创建目录&#xff1a; user-web global response user.go 定义一个结构体用于接收返回值&#xff0c;这里的 json 属于将对象转换为 json 时的规则定义。 时间处理 方法一&#x…

【机器分配问题】

问题&#xff1a; 现有设备n台&#xff0c;可投放到m个项目中&#xff0c;每个项目的产量与投入该项目的设备数量有关。如表2所示为三个项目的产量&#xff08;吨&#xff09;和投入设备&#xff08;台&#xff09;的关系。求对m个项目的最优设备分配&#xff0c;使总产量效益…

2024年QMT智能量化交易全解读:一文带你深入了解什么是QMT

随着科技的飞速发展和金融市场的日益成熟&#xff0c;量化交易逐渐成为投资者关注的焦点。QMT&#xff08;Quantitative Market Trading&#xff09;智能量化交易系统&#xff0c;作为量化交易领域的重要工具&#xff0c;以其高效、精准、自动化的特点&#xff0c;受到越来越多…

【TensorFlow深度学习】Dropout层工作原理与实际运用

Dropout层工作原理与实际运用 Dropout层工作原理与实际运用Dropout&#xff1a;随机失活的艺术工作机制实现代码示例实际运用成效结语 Dropout层工作原理与实际运用 在深度学习的征途中&#xff0c;模型的过拟合问题一直是研究者们面临的一大挑战。过拟合意味着模型在训练数据…

Ableton Live 11 Suite for Mac:音乐创作的全能伙伴

在数字音乐创作的广阔天地中&#xff0c;Ableton Live 11 Suite for Mac无疑是一颗璀璨的明星。作为一款专业的音乐制作软件&#xff0c;它集合了音频录制、编辑、混音、母带制作等全方位功能&#xff0c;为Mac用户提供了无与伦比的音乐创作体验。 Ableton Live 11 Suite拥有直…

Ubuntu/Linux 安装Paraview

文章目录 0. 卸载已有ParaView1. 安装ParaView1.1 下载后安装 2.进入opt文件夹改名3. 更改启动项4. 创建硬链接5. 添加桌面启动方式6. 即可使用 0. 卸载已有ParaView YUT 1. 安装ParaView https://www.paraview.org/ 1.1 下载后安装 找到下载的文件夹&#xff0c;文件夹内…

NTLM Relay Gat:自动化NTLM中继安全检测工具

关于NTLM Relay Gat NTLM Relay Gat是一款功能强大的NTLM中继威胁检测工具&#xff0c;该工具旨在利用Impacket工具套件中的ntlmrelayx.py脚本在目标环境中实现NTLM中继攻击风险检测&#xff0c;以帮助研究人员确定目标环境是否能够抵御NTLM中继攻击。 功能介绍 1、多线程支持…

日用百货元宇宙 伊利牛奶亮相博鳌论坛

近日,博鳌亚洲论坛2024年会在海南博鳌举行,本次年会以“亚洲与世界:共同的挑战,共同的责任”为主题,受到了亚洲各国的高度重视。在本次论坛上,伊利牛奶旗下的金典鲜牛奶作为博鳌亚洲论坛2024年年会官方唯一指定鲜奶亮相,以顶配鲜活营养,向世界贡献中国的健康方案。据悉,这是伊利…

AdaBoost 乳腺癌数据挖掘

目录 1.数据集背景 2 集成学习方法 AdaBoost集成过程 3 个体学习器 结果评价 准确率以及混淆矩阵 评估集成学习模型的泛化学习能力 评估集成学习模型的多样性 结论 源码 1.数据集背景 乳腺癌数据集是一个非常经典的二元分类数据集&#xff0c;被广泛应用…

LSTM长短时记忆网络:推导与实现(pytorch)

LSTM长短时记忆网络&#xff1a;推导与实现&#xff08;pytorch&#xff09; 背景推导遗忘门输入门输出门 LSTM的改进&#xff1a;GRU实现 背景 人类不会每秒钟都从头开始思考。当你阅读这篇文章时&#xff0c;你会根据你对以前单词的理解来理解每个单词。你不会把所有东西都扔…