栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

linux系统irq中断系统(结合input子系统代码为例)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux系统irq中断系统(结合input子系统代码为例)

1、上半部和下半部
由于中断随时可能发生,所以必须保证中断处理程序可以快速执行;但是中断处理程序可能又会处理大量的任务,两者之间存在矛盾,所以一般会把中断处理的过程分成两部分:上半部和下半部。

上半部也叫硬中断,是通常意义上的中断处理程序,用来接收中断,和简单的、有时限的处理工作,例如对中断接收后进行应答或者复位硬件等需要在所有中断被禁止的情况下完成的工作。而其他的允许稍后完成的工作,则会推迟到下半部在合适的时间完成。Linux有多种机制来实现下半部,其中一种就是软中断。

对于网卡的中断处理,上半部会执行 通知硬件、拷贝网络数据报到内存并继续读取新数据包,这些重要、紧急且与硬件相关的工作,因为网卡接收的网络数据包的缓存大小通常是固定的、有限的,一旦被延迟可能造成缓存溢出。而数据包的处理等操作,则由下半部来完成。

2、下半部主要用来处理一些比较耗时的操作,linux有很多中实现方式,包括tasklet、软中断、工作队列。即软中断是下半部的一种实现方式。

3、下面是以9x07平台为例实现gpio发生中断后,cpu通过iic去读sensor(smi230)数据,然后通过input子系统把数据上报

申请irq

	err = smi230_request_irq(client_data);
	if (err < 0) {
		PERR("Request irq failed");
		goto exit_cleanup_sysfs;
	}

中断部分代码:
在smi230_new_data_ready_handle(client_data);中通过input上报数据

static void smi230_irq_work_func(struct work_struct *work)
{
#ifndef CONFIG_SMI230_DATA_SYNC
	struct smi230_client_data *client_data =
		container_of(work, struct smi230_client_data, irq_work);

#ifdef CONFIG_SMI230_GYRO_FIFO
	smi230_gyro_fifo_handle(client_data);
#else
	smi230_new_data_ready_handle(client_data);
#endif

#endif
}

static irqreturn_t smi230_irq_handle(int irq, void *handle)
{
	struct smi230_client_data *client_data = handle;
	int err = 0;

	err = schedule_work(&client_data->irq_work);
	if (err < 0)
		PERR("schedule_work failedn");

	return IRQ_HANDLED;
}

static void smi230_free_irq(struct smi230_client_data *client_data)
{
	cancel_work_sync(&client_data->irq_work);
	free_irq(client_data->IRQ, client_data);
	gpio_free(client_data->gpio_pin);
}

static int smi230_request_irq(struct smi230_client_data *client_data)
{
	int err = 0;

	INIT_WORK(&client_data->irq_work, smi230_irq_work_func);

	

    client_data->gpio_pin = 34;
	PINFO("SMI230_GYRO gpio number:%dn", client_data->gpio_pin);
	err = gpio_request_one(client_data->gpio_pin,
				GPIOF_IN, "smi230_gyro_interrupt");
	if (err < 0) {
		PDEBUG("gpio_request_onen");
		return err;
	}
	err = gpio_direction_input(client_data->gpio_pin);
	if (err < 0) {
		PDEBUG("gpio_direction_inputn");
		return err;
	}
	client_data->IRQ = gpio_to_irq(client_data->gpio_pin);
	err = request_irq(client_data->IRQ, smi230_irq_handle,
			IRQF_TRIGGER_RISING,
			SENSOR_GYRO_NAME, client_data);
	if (err < 0) {
		PDEBUG("request_irqn");
		return err;
	}
	return err;
}

注册input设备

	err = smi230_input_init(client_data);
	if (err < 0) {
		PERR("input init failed");
		goto exit_free_client_data;
	}

	
	err = sysfs_create_group(&client_data->input->dev.kobj,
			&smi230_attribute_group);
	if (err < 0) {
		PERR("sysfs create failed");
		goto exit_cleanup_input;
	}

smi230_input_init实现

static struct attribute *smi230_attributes[] = {
	&dev_attr_chip_id.attr,
	&dev_attr_regs_dump.attr,
	&dev_attr_fifo_wm.attr,
	&dev_attr_pwr_cfg.attr,
	&dev_attr_bw_odr.attr,
	&dev_attr_range.attr,
	&dev_attr_gyro_value.attr,
	&dev_attr_driver_version.attr,
	NULL
};

static struct attribute_group smi230_attribute_group = {
	.attrs = smi230_attributes
};

static int smi230_input_init(struct smi230_client_data *client_data)
{
	int err = 0;
	struct input_dev *dev = input_allocate_device();

	if (dev == NULL)
		return -ENOMEM;

	dev->id.bustype = BUS_I2C;
	dev->name = SENSOR_GYRO_NAME;
	dev_set_name(&dev->dev, SENSOR_GYRO_NAME);
	input_set_drvdata(dev, client_data);
	client_data->input = dev;

	input_set_capability(dev, EV_MSC, MSC_RAW);
	input_set_capability(dev, EV_MSC, MSC_GESTURE);
	input_set_abs_params(dev, ABS_X, SMI230_MIN_VALUE, SMI230_MAX_VALUE, 0, 0);
	input_set_abs_params(dev, ABS_Y, SMI230_MIN_VALUE, SMI230_MAX_VALUE, 0, 0);
	input_set_abs_params(dev, ABS_Z, SMI230_MIN_VALUE, SMI230_MAX_VALUE, 0, 0);

	err = input_register_device(dev);
	if (err)
		input_free_device(dev);
	return err;
}

数据上报,在中断中调用

static void smi230_new_data_ready_handle(
	struct smi230_client_data *client_data)
{
	struct smi230_sensor_data gyro_data;
	int err = 0;

	err = smi230_gyro_get_data(&gyro_data, p_smi230_dev);  //通过iic读数据
	if (err != SMI230_OK)
		return;

	input_event(client_data->input, EV_MSC, MSC_GESTURE, (int)gyro_data.x);
	input_event(client_data->input, EV_MSC, MSC_GESTURE, (int)gyro_data.y);
	input_event(client_data->input, EV_MSC, MSC_GESTURE, (int)gyro_data.z);

	input_sync(client_data->input);
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/511824.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号