导航:首页 > 操作系统 > linux中断编程

linux中断编程

发布时间:2022-06-30 04:22:58

1. linux中断处理怎么处理添加

中断程序处理,使用kill或killall命令后面加上程序ID号(pid)或者程序名。再使用ps命令查看一下,原来的那个程序就没有了。 如果有多个名字相同的,waCBdZ

2. 在linux中如何终止指令的运行

具体操作步骤如下:

1、首先打开linux终端,运行一段Python程序:

3. linux中断处理程序的方法

中断程序处理,使用kill或killall命令后面加上程序ID号(pid)或者程序名。查看程序ID使用ps 命令,然后,再用kill -9 <pid> 回车就可以把指定的程序中断了。再使用ps命令查看一下,原来的那个程序就没有了。

如果有多个名字相同的程序你想中断的话,就使用killall命令来指定程序名称,就可以中断多个相同名称的程序了。格式如下:
killall -9 httpd
我这里以中断httpd程序为例子。这样也可以中断程序执行。

4. Linux中断与定时器

所谓中断是指CPU在执行程序的过程中,出现了某些突发事件急待处理,CPU必须暂停当前程序的执行,转去处理突发事件,处理完毕后又返回原程序被中断的位置继续执行。根据中断的来源,中断可分为内部中断和外部中断,内部中断的中断源来自CPU内部(软件中断指令、溢出、除法错误等,例如,操作系统从用户态切换到内核态需借助CPU内部的软件中断),外部中断的中断源来自CPU外部,由外设提出请求。根据中断是否可以屏蔽,中断可分为可屏蔽中断与不可屏蔽中断(NMI),可屏蔽中断可以通过设置中断控制器寄存器等方法被屏蔽,屏蔽后,该中断不再得到响应,而不可屏蔽中断不能被屏蔽。
根据中断入口跳转方法的不同,中断可分为向量中断和非向量中断。采用向量中断的CPU通常为不同的中断分配不同的中断号,当检测到某中断号的中断到来后,就自动跳转到与该中断号对应的地址执行。不同中断号的中断有不同的入口地址。非向量中断的多个中断共享一个入口地址,进入该入口地址后,再通过软件判断中断标志来识别具体是哪个中断。也就是说,向量中断由硬件提供中断服务程序入口地址,非向量中断由软件提供中断服务程序入口地址。
嵌入式系统以及x86PC中大多包含可编程中断控制器(PIC),许多MCU内部就集成了PIC。如在80386中,PIC是两片i8259A芯片的级联。通过读写PIC的寄存器,程序员可以屏蔽/使能某中断及获得中断状态,前者一般通过中断MASK寄存器完成,后者一般通过中断PEND寄存器完成。定时器在硬件上也依赖中断来实现,典型的嵌入式微处理器内可编程间隔定时器(PIT)的工作原理,它接收一个时钟输入,当时钟脉冲到来时,将目前计数值增1并与预先设置的计数值(计数目标)比较,若相等,证明计数周期满,并产生定时器中断且复位目前计数值。

5. linux驱动中断,程序运行几个小时后系统崩溃

中断与定时器:
中断的概念:指CPU在执行过程中,出现某些突发事件急待处理,CPU暂停执行当前程序,转去处理突发事件
,处理完后CPU又返回原程序被中断的位置继续执行
中断的分类:内部中断和外部中断
内部中断:中断源来自CPU内部(软件中断指令、溢出、触发错误等)
外部中断:中断源来自CPU外部,由外设提出请求

屏蔽中断和不可屏蔽中断:
可屏蔽中断:可以通过屏蔽字被屏蔽,屏蔽后,该中断不再得到响应
不可平布中断:不能被屏蔽

向量中断和非向量中断:
向量中断:CPU通常为不同的中断分配不同的中断号,当检测到某中断号的中断到来后,就自动跳转到与该中断号对应的地址执行
非向量中断:多个中断共享一个入口地址。进入该入口地址后再通过软件判断中断标志来识别具体哪个是中断
也就是说向量中断由软件提供中断服务程序入口地址,非向量中断由软件提供中断入口地址

/*典型的非向量中断首先会判断中断源,然后调用不同中断源的中断处理程序*/
irq_handler()
{
...
int int_src = read_int_status();/*读硬件的中断相关寄存器*/
switch(int_src){//判断中断标志
case DEV_A:
dev_a_handler();
break;
case DEV_B:
dev_b_handler();
break;
...
default:
break;
}
...
}

定时器中断原理:
定时器在硬件上也以来中断,PIT(可编程间隔定时器)接收一个时钟输入,
当时钟脉冲到来时,将目前计数值增1并与已经设置的计数值比较,若相等,证明计数周期满,产生定时器中断,并
复位计数值。

如下图所示:

Linux中断处理程序架构:
Linux将中断分为:顶半部(top half)和底半部(bottom half)
顶板部:完成尽可能少的比较紧急的功能,它往往只是简单的读取寄存器中的中断状态并清除中断标志后就进行
“登记中断”(也就是将底半部处理程序挂在到设备的底半部执行队列中)的工作
特点:响应速度快

底半部:中断处理的大部分工作都在底半部,它几乎做了中断处理程序的所有事情。
特点:处理相对来说不是非常紧急的事件

小知识:Linux中查看/proc/interrupts文件可以获得系统中断的统计信息。

如下图所示:

第一列是中断号 第二列是向CPU产生该中断的次数

介绍完相关基础概念后,让我们一起来探讨一下Linux中断编程

Linux中断编程:
1.申请和释放中断
申请中断:
int request_irq(unsigned int irq,irq_handler_t handler,
unsigned long irqflags,const char *devname,void *dev_id)
参数介绍:irq是要申请的硬件中断号
handler是向系统登记的中断处理程序(顶半部),是一个回调函数,中断发生时,系统调用它,将
dev_id参数传递给它
irqflags:是中断处理的属性,可以指定中断的触发方式和处理方式:
触发方式:IRQF_TRIGGER_RISING、IRQF_TRIGGER_FALLING、IRQF_TRIGGER_HIGH、IRQF_TRIGGER_LOW
处理方式:IRQF_DISABLE表明中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断
IRQF_SHARED表示多个设备共享中断,dev_id在中断共享时会用到,一般设置为NULL

返回值:为0表示成功,返回-EINVAL表示中断号无效,返回-EBUSY表示中断已经被占用,且不能共享
顶半部的handler的类型irq_handler_t定义为
typedef irqreturn_t (*irq_handler_t)(int,void*);
typedef int irqreturn_t;

2.释放IRQ
有请求当然就有释放了
void free_irq(unsigned int irq,void *dev_id);
参数定义与request_irq类似

3.使能和屏蔽中断
void disable_irq(int irq);//等待目前中断处理完成(最好别在顶板部使用,你懂得)
void disable_irq_nosync(int irq);//立即返回
void enable_irq(int irq);//

4.屏蔽本CPU内所有中断:
#define local_irq_save(flags)...//禁止中断并保存状态
void local_irq_disable(void);//禁止中断,不保存状态

下面来分别介绍一下顶半部和底半部的实现机制

底半部机制:
简介:底半部机制主要有tasklet、工作队列和软中断
1.底半部是想方法之一tasklet
(1)我们需要定义tasklet机器处理器并将两者关联
例如:
void my_tasklet_func(unsigned long);/*定义一个处理函数*/
DECLARE_TASKLET(my_tasklet,my_tasklet_func,data);
/*上述代码定义了名为my_tasklet的tasklet并将其余
my_tasklet_func()函数绑定,传入的参数为data*/
(2)调度
tasklet_schele(&my_tasklet);
//使用此函数就能在是当的时候进行调度运行

tasklet使用模板:
/*定义tasklet和底半部函数并关联*/
void xxx_do_tasklet(unsigned long);
DECLARE_TASKLET(xxx_tasklet,xxx_do_tasklet,0);

/*中断处理底半部*/
void xxx_do_tasklet(unsigned long)
{
...
}

/*中断处理顶半部*/
irqreturn_t xxx_interrupt(int irq,void *dev_id)
{
...
tasklet_schele(&xxx_tasklet);//调度地板部
...
}

/*设备驱动模块加载函数*/
int __init xxx_init(void)
{
...
/*申请中断*/
result = request_irq(xxx_irq,xxx_interrupt,
IRQF_DISABLED,"xxx",NULL);
...

return IRQ_HANDLED;
}

/*设备驱动模块卸载函数*/
void __exit xxx_exit(void)
{
...
/*释放中断*/
free_irq(xxx_irq,xxx_interrupt);
...
}

2.底半部实现方法之二---工作队列
使用方法和tasklet类似
相关操作:
struct work_struct my_wq;/*定义一个工作队列*/
void my_wq_func(unsigned long);/*定义一个处理函数*/
通过INIT_WORK()可以初始化这个工作队列并将工作队列与处理函数绑定
INIT_WORK(&my_wq,(void (*)(void *))my_wq_func,NULL);
/*初始化工作队列并将其与处理函数绑定*/
schele_work(&my_wq);/*调度工作队列执行*/

/*工作队列使用模板*/

/*定义工作队列和关联函数*/
struct work_struct(unsigned long);
void xxx_do_work(unsigned long);

/*中断处理底半部*/
void xxx_do_work(unsigned long)
{
...
}

/*中断处理顶半部*/
/*中断处理顶半部*/
irqreturn_t xxx_interrupt(int irq,void *dev_id)
{
...
schele_work(&my_wq);//调度底半部
...
return IRQ_HANDLED;
}

/*设备驱动模块加载函数*/
int xxx_init(void)
{
...
/*申请中断*/
result = request_irq(xxx_irq,xxx_interrupt,
IRQF_DISABLED,"xxx",NULL);
...
/*初始化工作队列*/
INIT_WORK(&my_wq,(void (*)(void *))xxx_do_work,NULL);
}

/*设备驱动模块卸载函数*/
void xxx_exit(void)
{
...
/*释放中断*/
free_irq(xxx_irq,xxx_interrupt);
...
}

6. linux 如何中断后台运行的程序

例如:中断后台运行的bash
1. ps -aux | grep 'bash'
2. 查看进程号PID 如:3306
3. kill -9 3306

7. Linux下通过哪个命令怎么查看中断

与Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq()。

C++是一种面向对象的计算机程序设计语言,由美国AT&T贝尔实验室的本贾尼·斯特劳斯特卢普博士在20世纪80年代初期发明并实现,最初它被称作“C with Classes”(包含类的C语言)。

它是一种静态数据类型检查的、支持多重编程范式的通用程序设计语言,支持过程化程序设计、数据抽象、面向对象程序设计、泛型程序设计等多种程序设计风格。

在C基础上,一九八三年又由贝尔实验室的Bjarne Strou-strup推出了C++,C++进一步扩充和完善了C语言,成为一种面向 对象的程序设计语言。

C++目前流行的编译器最新版本是Borland C++ 4.5,Symantec C++ 6.1,和Microsoft Visual C++ 2012。

8. linux系统中的中断指令是什么

什么是中断
Linux 内核需要对连接到计算机上的所有硬件设备进行管理,毫无疑问这是它的份内事。如果要管理这些设备,首先得和它们互相通信才行,一般有两种方案可实现这种功能:
轮询(polling) 让内核定期对设备的状态进行查询,然后做出相应的处理;中断(interrupt) 让硬件在需要的时候向内核发出信号(变内核主动为硬件主动)。
第一种方案会让内核做不少的无用功,因为轮询总会周期性的重复执行,大量地耗用 CPU 时间,因此效率及其低下,所以一般都是采用第二种方案 。
对于中断的理解我们先看一个生活中常见的例子:QQ。第一种情况:你正在工作,然后你的好友突然给你发送了一个窗口抖动,打断你正在进行的工作。第
二种情况:当然你有时候也会每隔 5 分钟就去检查一下 QQ
看有没有好友找你,虽然这很浪费你的时间。在这里,一次窗口抖动就可以被相当于硬件的中断,而你就相当于 CPU,你的工作就是 CPU
这在执行的进程。而定时查询就被相当于 CPU 的轮询。在这里可以看到:同样作为 CPU 和硬件沟通的方式,中断是硬件主动的方式,较轮询(CPU
主动)更有效些,因为我们都不可能一直无聊到每隔几分钟就去查一遍好友列表。
CPU
有大量的工作需要处理,更不会做这些大量无用功。当然这只是一般情况下。好了,这里又有了一个问题,每个硬件设备都中断,那么如何区分不同硬件呢?不同设
备同时中断如何知道哪个中断是来自硬盘、哪个来自网卡呢?这个很容易,不是每个 QQ 号码都不相同吗?同样的,系统上的每个硬件设备都会被分配一个
IRQ 号,通过这个唯一的 IRQ 号就能区别张三和李四了。
从物理学的角度看,中断是一种电信号,由硬件设备产生,并直接送入中断控制器(如
8259A)的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断。此后,
处理器会通知 OS 已经产生中断。这样,OS
就可以对这个中断进行适当的处理。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识,这些值通常被称为中断请求线。

9. 如何在嵌入式linux系下使用omapl138编写中断函数

linux -- omapl138 boot 启动
TI的达芬奇架构嵌入式应用处理器使用DSP与ARM结合的非对称多核结构,当然现在也有管脚全兼容的单核。本文要介绍的就是其中的一款低功耗处理器OMAP L138。

OMAP L138包括一个主频300M的ARM9处理器内核和一个300M的C6748DSP内核(均是32位处理器)。此外还有大量外设在此不做说明,与通用的ARM与DSP内核相比有如下一些不同点:

1.内存映射,该处理器的外设与内存统一编址,DSP与ARM共享4G内存空间。但其中有一部分DSP仅可见(如DSP的数据指令缓存),一部分ARM仅可见(如ARM的内部RAM),其余的两者都可以访问,具体的请参考其芯片资料。

2.中断,与通用的DSP与ARM相比,达芬奇架构并没有在这两个核中增加用于双核通信及相互控制的指令(也许是本人没发现吧!如果你发现相关的说明,请发个email告诉我,谢谢!),然而却增加两个核之间的中断,共计7个。当双核需要进行通信时,首先把数据放在双方可以访问的内存上,然后给对方一个中断,对方在中断中接收传递过来的数据,以此实现双方的通信,个人认为这就是DSP Link实现的基本原理吧:)

3.能源与休眠配置模块(PSC),这个模块主要负责整个系统的能源管理,可以使能或者休眠ARM核,DSP核以及大部分外设ARM核与DSP核的相互控制主要就依赖这个模块。
对于OMAPL138,上电时默认的是ARM核被禁止,DSP核被使能。说以开机时是DSP核先启动,然后是DSP的ROM Bootloader做一些初始化后使能ARM核后,ARM核才开始运行。不同的达芬奇处理器是不同的,比如OMAPL137就是反过来的,网上资料鱼龙混杂,弄不清楚的话就去看PSC模块中的ARM和DSP核的默认值就可以了。
1.开机上电,用户在BOOT 管脚上配置的启动方式被锁定采样到SYSCFG模块的BOOTCFG寄存器,从而确定可处理器的启动方式。

2.PSC模块中的启动默认值是:ARM核休眠,DSP核使能。所以这时候DSP启动,DSP从片内DSP L2 ROM处读取指令执行。这里有TI已经固化的仅DSP核可以访问的ROM Bloader,简称DSP RBL。

3.DSP的RBL做一些简单的初始化后,就通过PSC模块使能ARM核,休眠自己。然后ARM就开从片内的RAM Local ROM处读取指令并执行,这里面有TI已经固化好的ARM ROM Bootloader,简称ARM RBL。

4.ARM的RBL做一些初始化后,根据BOOTCFG寄存器的设定,从指定的地方读取用于启动U-Boot的Bootloader,即U-Boot BootLoader,简称UBL。UBL可以放在Nandflash,或者通过串口下载等方式取得。值得说明的是,这里的UBL是(AIS Application Image Script )格式,而不是通常的BIN格式。

5.当ARM RBL读取到UBL后就根据AIS格式中的命令初始化、加载并运行UBL。然后就是UBL加载运行U-Boot,U-Boot根据启动参数启动Linux,Linux根据启动参数加载根文件系统。

6.这时ARM核上的Linux就运行起来了,但DSP还处于休眠状态。在Linux经过一系列初始化后会执行跟文件系统中/etc/profile的指令。我们在这里添加插入DSP Link内核模块的命令,就会在/dev目录下产生一个叫dsplink的设备文件。这个DSP Link内核模块就是通过前面所说的中断和PSC设定就可以完成与DSP的通信与控制。

7. 然后再执行我们自己的ARM端程序,在ARM端程序中使用DSP Link的库函数来访问dsplink设备,从而在用户空间实现对DSP核的控制与通信。在我们写的ARM端程序中使用DSP Link库函数加载DSP端的应用程序到内存,使用DSP Link的PROC函数启动DSP核。然后ARM核和DSP核就都各自独立运行起来了,通过DSP Link来进行通信

10. 如何实现linux下的串口中断编程

#include
#include
#include
#include
#include
#include

#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* POSIX 系统相容 */
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

void signal_handler_IO (int status); /* 定义讯号处理程序 */
int wait_flag=TRUE; /* 没收到讯号的话就会是 TRUE */

main()
{
int fd,c, res;
struct termios oldtio,newtio;
struct sigaction saio; /* definition of signal action */
char buf[255];

/* 开启装置为 non-blocking (读取功能会马上结束返回) */
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd <0) {perror(MODEMDEVICE); exit(-1); }

/* 在使装置异步化前, 安装讯号处理程序 */
saio.sa_handler = signal_handler_IO;
saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);

/* 允许行程去接收 SIGIO 讯号*/
fcntl(fd, F_SETOWN, getpid());
/* 使档案ake the file descriptor 异步 (使用手册上说只有 O_APPEND 及
O_NONBLOCK, 而 F_SETFL 也可以用...) */
fcntl(fd, F_SETFL, FASYNC);

tcgetattr(fd,&oldtio); /* 储存目前的序列端口设定值 */
/* 设定新的序列端口为标准输入程序 */
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR | ICRNL;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);

/* 等待输入讯号的回圈. 很多有用的事我们将在这做 */
while (STOP==FALSE) {
printf(".\n");usleep(100000);
/* 在收到 SIGIO 后, wait_flag = FALSE, 输入讯号存在则可以被读取 */
if (wait_flag==FALSE) {
res = read(fd,buf,255);
buf[res]=0;
printf(":%s:%d\n", buf, res);
if (res==1) STOP=TRUE; /* 如果只输入 CR 则停止回圈 */
wait_flag = TRUE; /* 等待新的输入讯号 */
}
}
/* 回存旧的序列端口设定值 */
tcsetattr(fd,TCSANOW,&oldtio);
}

阅读全文

与linux中断编程相关的资料

热点内容
文件夹怎么做标题 浏览:31
腾讯云服务器如何防止被攻击 浏览:879
六棱柱的体积算法 浏览:933
淘宝什么云服务器好用 浏览:340
pythonoa项目 浏览:307
android杜比音效 浏览:341
杀手47为什么连接不了服务器 浏览:108
静态路径命令 浏览:533
一直编译不过怎么办 浏览:829
汽车串联并联算法 浏览:458
助眠解压的声音音频小哥哥 浏览:277
pythoncmd换行 浏览:376
linux取消行号 浏览:355
安卓原生系统官网是什么 浏览:444
底部主图源码 浏览:878
服务器崩了有什么提示 浏览:780
远程海康服务器用什么浏览器 浏览:232
解压报纸图片 浏览:956
python微信公众号开发平台 浏览:895
知识付费网站java源码 浏览:255