博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
软中断
阅读量:4320 次
发布时间:2019-06-06

本文共 2461 字,大约阅读时间需要 8 分钟。

linux中断的处理分为顶半部和低半部,顶半部在硬件中断处理函数中实现(request_irq()中可申请用户回调函数),底半部的实现机制有三种:软中断/tasklet/workqueue。

软中断的执行时机通常是顶半部返回的时候,tasklet是基于软中断实现的,因此也运行于软中断上下文。

在linux内核中,用softirq_action结构体表征一个软中断,这个结构体包含软中断处理函数指针和传递给该函数的参数。使用open_softirq()函数可以注册软中断对应的处理函数,而raise_softirq()函数可以触发一个软中断。

local_bh_disable()和local_bh_enable()是内核中用于禁止和使能软中断及tasklet底半部机制的函数。

本文档描述基于3.14.77内核。

1. 定义

softirq定义在linux/interrupt.h中,实现在kernel/softirq.c中。tasklet是基于软中断实现的,相关代码也在这两个文件中。

enum{    HI_SOFTIRQ=0,    TIMER_SOFTIRQ,    NET_TX_SOFTIRQ,    NET_RX_SOFTIRQ,    BLOCK_SOFTIRQ,    BLOCK_IOPOLL_SOFTIRQ,    TASKLET_SOFTIRQ,    SCHED_SOFTIRQ,    HRTIMER_SOFTIRQ,    RCU_SOFTIRQ,    /* Preferable RCU should always be the last softirq */    NR_SOFTIRQS};#define SOFTIRQ_STOP_IDLE_MASK (~(1 << RCU_SOFTIRQ))/* map softirq index to softirq name. update 'softirq_to_name' in * kernel/softirq.c when adding a new softirq. */extern const char * const softirq_to_name[NR_SOFTIRQS];/* softirq mask and active fields moved to irq_cpustat_t in * asm/hardirq.h to get better cache usage.  KAO */struct softirq_action{    void    (*action)(struct softirq_action *);};

说明:之前linux版本,struct softirq_action包含两项action(软中断服务程序)和data(服务程序输入参数),因为其参数为softirq_action,可定义为全局变量而省去data定义。

static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;

softirq相关函数

asmlinkage void do_softirq(void);asmlinkage void __do_softirq(void);#ifdef __ARCH_HAS_DO_SOFTIRQvoid do_softirq_own_stack(void);#elsestatic inline void do_softirq_own_stack(void){    __do_softirq();}#endifextern void open_softirq(int nr, void (*action)(struct softirq_action *));extern void softirq_init(void);extern void __raise_softirq_irqoff(unsigned int nr);extern void raise_softirq_irqoff(unsigned int nr);extern void raise_softirq(unsigned int nr);

 2. 实现机制

 软中断守护程序是软中断机制实现的核心,它的实现过程简单。通过查询软中断的状态来判断是否发生事件,当发生事件就会映射软中断向量表,调用执行注册的action()函数就可以了。从这一点分析可以看出,软中断的服务程序是daemon。在linux中软中断daemon线程函数为do_softirq()。

asmlinkage void do_softirq(void){    __u32 pending;    unsigned long flags;    if (in_interrupt())        return;    local_irq_save(flags);    pending = local_softirq_pending();    if (pending)        do_softirq_own_stack();    local_irq_restore(flags);}

 网络软中断举例:

当网络上有数据时,发生了硬件中断,硬件中断服务程序会接收网络数据,设置中断状态,并将网络数据挂接到链表中,进行中断调度,这一步可以通过net_schedule()函数完成。硬件中断服务程序最后退出并且CPU开始调度软中断,软中断daemon会发现网络软中断发生了事件,其会执行网络中断对应的服务程序,即进入网络协议栈处理程序。

 

参考:

1.

2.

3. 设备驱动开发详解 宋宝华

4. linux网络编程 宋敬彬

 

转载于:https://www.cnblogs.com/embedded-linux/p/9189930.html

你可能感兴趣的文章
html知识2
查看>>
Python—面向对象01
查看>>
Android DDMS ADB Hierarchy Viewer Lint
查看>>
Linux命令学习(5):more和less
查看>>
Linux 三剑客之sed命令总结
查看>>
倒计时
查看>>
36.Altium Designer(Protel)网络连接方式Port和Net Label详解
查看>>
读《分布式一致性原理》CURATOR客户端3
查看>>
iOS 虚拟机测试出现的相关问题
查看>>
MySQL crash-safe replication(3): MySQL的Crash Safe和Binlog的关系
查看>>
mac 无法打开xx ,因为无法确认开发者身份
查看>>
简单的排序算法(冒泡、选择、插入)
查看>>
[剑指Offer] 11.二进制中1的个数
查看>>
重置报表输出选择
查看>>
ip代理池抓取qq音乐热歌前300
查看>>
Android面试题集合
查看>>
Android NDK开发
查看>>
Centos中安装和配置vsftp简明教程
查看>>
spring源码学习之AOP(一)
查看>>
AES加密算法动画演示
查看>>