"); //-->
这是我曾经做产品开发时的一个案例!我做研发有个特点就是每做完一个项目习惯写些总结,这是90%搞技术的不能做到的,也许是我记性太差,怕自己忘了曾经解决问题的思路,所以要把她记录下来吧!可以我这一习惯为我研发工作积累了非常宝贵的经验,也为我日后教学准备了非常宝贵的案例教学!
如果你深入的去想想Linux kernel 中断问题,你会有一系列的疑问。按照常人,或者说自然规律的思考方式(不同的人有不同的头脑,就有不同的思维方式,也就有不同的解决问题的方法,这其中的效率完全不一样。虽然大部分人是常规思维方式,但是千万不要认为你的朋友,对手,同事的思维方式与你一样。),你会有下列疑问:
1.1:中断注册到什么地方去了? 1.2:CPU发生了中断后,kernel是怎么知道的?也就是kernel 是怎么响应到cpu的中断的? 1.3:kernel 响应CPU中断后又怎么回调到当初注册的中断里面去的?我们通常在驱动里面要注册中断,都是调用reguest_irq。因为,觉得Linux已经很成熟了,而且各大CPU的BSP也支持得很好。况且我们调试的驱动都是基于当今热门的sumsang ARM MCU。所以,更本就没有去怀疑其BSP。
可是,“最终出问题的地方往往是最先否定的地方”。
我们客户提供的kernel及sumsang 提供的bsp竟然有问题。
二:Linux中断机制流程言归正传,我带着疑问顺滕摸瓜,揭开Linux-2.6.21-s3c6400中断机制。
2.1 调用的第一个函数request_irq()我们在写驱动时往往要调用request_irq()函数。那么,我们从这里出发。Reguest_irq的函数原形为
/**见kernel/irq/manage.c
* request_irq - allocate an interrupt line
* @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs
* @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function
*
* This call allocates interrupt resources and enables the
* interrupt line and IRQ handling. From the point this
* call is made your handler function may be invoked. Since
* your handler function must clear any interrupt the board
* raises, you must take care both to initialise your hardware
* and to set up the interrupt handler in the right order.
*
* Dev_id must be globally unique. Normally the address of the
* device data structure is used as the cookie. Since the handler
* receives this value it makes sense to use it.
*
* If your interrupt is shared you must pass a non NULL dev_id
* as this is required when freeing the interrupt.
*
* Flags:
*
* IRQF_SHARED Interrupt is shared
* IRQF_DISABLED Disable local interrupts while processing
* IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
*
*/
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
{
struct irqaction *action;
int retval;
#ifdef CONFIG_LOCKDEP
/*
* Lockdep wants atomic interrupt handlers:
*/
irqflags |= IRQF_DISABLED;
#endif
/*
* Sanity-check: shared interrupts must pass in a real dev-ID,
* otherwise we'll have trouble later trying to figure out
* which interrupt is which (messes up the interrupt freeing
* logic etc).
*/
if ((irqflags & IRQF_SHARED) && !dev_id)
return -EINVAL;
if (irq >= NR_IRQS)
return -EINVAL;
if (irq_desc[irq].status & IRQ_NOREQUEST)
return -EINVAL;
if (!handler)
return -EINVAL;
action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
if (!action)
return -ENOMEM;
action->handler = handler;/*这一句要注意,我们注册的中断函数句柄就放在这里,当中断发生后,kernel就会调用到这里来,kernel怎么找到这里我后面会讲到*/
action->flags = irqflags;
cpus_clear(action->mask);
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
select_smp_affinity(irq);
#ifdef CONFIG_DEBUG_SHIRQ
if (irqflags & IRQF_SHARED) {
/*
* It's a shared IRQ -- the driver ought to be prepared for it
* to happen immediately, so let's make sure....
* We do this before actually registering it, to make sure that
* a 'real' IRQ doesn't run in parallel with our fake
*/
if (irqflags & IRQF_DISABLED) {
unsigned long flags;
local_irq_save(flags);
handler(irq, dev_id);
local_irq_restore(flags);
} else
handler(irq, dev_id);
}
#endif
retval = setup_irq(irq, action);
if (retval)
kfree(action);
return retval;
}
这个函数其实只做两件事情:
填充(增加)一个活动irq结构体(irqaction)
调用setup_irq函数
2009-2-13 下家山 写于上海.漕河泾
有什么问题可以给我邮件ximenpiaoxue4016@sina.com或加我群198204885
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
555家电自动开、停的定时电路
如何使用Microchip MAPS选择适合你的PIC® MCU
电阻标准阻值咨询
555安全可靠的间歇式电加热控制电路
利用Flash实现DSP对多个程序有选择的加载
MCP3903六通道模拟前端采样芯片
艾迈斯欧司朗推出超紧凑绿光ChipLED,以极小体积实现入耳式设备精准心率监测
瑞萨RA0单片机连载之―面向对象之I2C驱动OLED
888保险柜、冰箱开门时间过长音响报叫电路
555电子语言模特招待电路
如何建立中游领域性KG(知识图)
555使用磁牌取水的自动供水电路
全球水资源可持续发展的技术驱动型解决方案
瑞萨RA0单片机连载⸺OLED面向对象显示字符串
利用51LPC系列单片机内部比较器实现AD键盘的方法
英飞凌微控制器:以全新实惠套件和强大开发环境为开发者提供支持
谁有ARM板的实际电路图?哪里能找到?
这两天全球互联网中毒,上网速度真慢呀:(
论AGI与人形机器人
OpenCV行人检测--米尔基于全志T527核心板开发板
我想研究嵌入式Linux,请给予指点!
利用VB实现PC机与多单片机通讯
基于STM32的避障小车
运算放大器简介
利用P87LPC762 单片机设计绕线计数器的方法
【瑞萨RA2E1开发板】使用ADC功能实现位移传感器采集方案
利用串口与并口实现51内核单片机的在线编程
ARM anywhereII使用说明
迷你七位数字电位器MCP40D17/8/9
运算放大器产品组合