xenomai 应用开发 7:中断服务程序 --WT

本文详细介绍了在Xenomai环境下,如何使用中断服务程序以及实时GPIO设备驱动进行读写操作。重点讨论了中断处理的重要性、RTDM实时驱动模型以及如何在用户空间中处理中断。通过具体的GPIO引脚设置,展示了初始化GPIO、读取和写入GPIO值的过程,并给出了实验案例,涉及中断触发、周期性闪烁和中断计数。
摘要由CSDN通过智能技术生成

一、中断

中断处理在实时操作系统中非常重要,因为通过中断机制,系统可以感知外部事件。系统对中断的响应速度是许多实时系统的一个重要特性。
与Xenomai的GPIO管脚实时交互需要一个实时设备驱动程序。

设备驱动

对于添加到计算机中的每一个新硬件,计算机都需要一个所谓的硬件驱动程序来与之交互。对于linux,硬件驱动程序是使用内核模块实现的。这样的硬件驱动程序可以通过所谓的设备文件访问用户空间。用户空间程序可以通过使用open函数打开此设备文件来与硬件交互 :
int fd=open("/dev/devicefile", …)
open调用向设备返回一个文件句柄。这个句柄可以用于从设备读取数据,也可以使用读写函数将数据写入设备。例如:
int value;
read(fd1, &value, 4);
write(fd2, &value, sizeof(value));
请注意,要读取和写入一个GPIO引脚,需要初始化两个文件句柄,如下所述。
基本上,linux通过将设备表示为虚拟文件来使用文件API与设备交互。然而,设备通常更复杂,它们支持比读取和写入数据更专门的交互。对于这些交互,linux支持ioctl函数,它有如下接口:
int ioctl(int fd, int request, …);

第一个参数fd必须是设备的打开文件描述符。第二个参数是设备相关的请求代码。第三个参数是指向内存的无类型指针,它的使用取决于特定的请求代码。通过这种方式,可以提供几个请求代码来实现特定设备的专门交互。

可以使用/dev/中的设备驱动程序从linux控制Raspberry Pi(树莓派)上的GPIO管脚,其中每个管脚都有一个单独的驱动程序来控制。然而,在Xenomai中使用linux设备驱动程序时,程序执行会从高优先级实时内核转移到低优先级的linux内核因此,实时内核需要专门的驱动程序。

实时设备驱动(RTDM)

Xenomai使用实时驱动模型(RTDM)来实现实时驱动。在这些练习中,我们使用一个已经实现的RTDM驱动程序,用于树莓派上的GPIO管脚,称为xeno_GPIO

本课程中使用的sd卡上的映像会在启动时自动加载xeno_gpio RTDM设备驱动程序。在命令行中键入“lsmod”可以看到,其中列出了当前加载的内核模块:

sikander@pc:~$ lsmod
Module                  Size  Used by
xeno_gpio               4531  0
ccm                     7391  2
rfcomm                 57295  0
bnep                   13213  2
snd_hda_codec_hdmi     37022  1
snd_hda_codec_conexant    11105  1
kvm_amd              2157076  0
arc4                    1784  2
snd_hda_codec_generic    59052  1 snd_hda_codec_conexant
kvm                   493834  1 kvm_amd
snd_hda_intel          27448  7
irqbypass               2791  1 kvm
rtl8723be              76614  0
snd_hda_codec         105077  4 snd_hda_intel,snd_hda_codec_conexant,snd_hda_codec_hdmi,snd_hda_codec_generic

要将RTDM设备驱动程序与linux设备驱动程序分开,它们的设备文件位于/dev/RTDM/子目录中。对于每个GPIO pin都有这样一个文件 :
$ cd /dev/rtdm/pinctrl-bcm2835/
$ ls
gpio0 gpio12 gpio16 gpio2 gpio23 gpio27 gpio30 gpio34 gpio38 gpio41 gpio45 gpio49 gpio52 gpio9
gpio1 gpio13 gpio17 gpio20 gpio24 gpio28 gpio31 gpio35 gpio39 gpio42 gpio46 gpio5 gpio6
gpio10 gpio14 gpio18 gpio21 gpio25 gpio29 gpio32 gpio36 gpio4 gpio43 gpio47 gpio50 gpio7
gpio11 gpio15 gpio19 gpio22 gpio26 gpio3 gpio33 gpio37 gpio40 gpio44 gpio48 gpio51 gpio8
命令rmmod xeno_gpio卸载xeno_gpio RTDM设备驱动程序,lsmod将显示相应的设备文件被删除。使用modprobe xeno_gpio命令可以重新加载设备驱动程序。

使用实时GPIO设备驱动程序读取和写入GPIO引脚

我们以pin 23为例,描述了初始化一个GPIO pin以进行读取以及读取该pin的值的函数。同样的写作。
下面的代码片段不包括错误处理,例如当fd<0或ret<0。POSIX API的错误处理模式可以在 tips page of the lab site中找到。
代码片段应当包括以下内容:
包含以下头文件:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <alchemy/task.h>
#include <alchemy/timer.h>
#include <rtdm/gpio.h>

从GPIO输入端口进行读取

在驱动程序中定义了 四种 系统调用的ioctl()命令:

switch (request) {
   
	case GPIO_RTIOC_DIR_OUT:
		ret = rtdm_safe_copy_from_user(fd, &val, arg, sizeof(val));
		if (ret)
			return ret;
		ret = gpio_direction_output(gpio, val);
		if (ret == 0) {
   
			chan->has_direction = true;
			chan->is_output = true;
		}
		break;
	case GPIO_RTIOC_DIR_IN:
		ret = gpio_direction_input(gpio);
		if (ret == 0)
			chan->has_direction = true;
		break;
	case GPIO_RTIOC_IRQEN:
		if (chan->requested)
			return -EBUSY;
		ret = rtdm_safe_copy_from_user(fd, &trigger,
				       arg, sizeof(trigger));
		if (ret)
			return ret;
		ret = request_gpio_irq(gpio, pin, chan, trigger);
		break;
	case GPIO_RTIOC_IRQDIS:
		release_gpio_irq(gpio, pin, chan);
		chan->requested = false;
		break;
	default:
		return -EINVAL;
	}

GPIO_RTIOC_DIR_OUT:设置端口为输出模式

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值