Chinaunix首页 | 论坛 | 博客
  • 博客访问: 932686
  • 博文数量: 153
  • 博客积分: 4195
  • 博客等级: 上校
  • 技术积分: 2631
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-22 11:32
文章存档

2012年(7)

2010年(35)

2009年(111)

分类:

2009-08-26 12:04:32

因为sep4020的唤醒需要用到fiq模式,上网搜索了一下linux暂时不支持fiq,但是仔细查看了entry-armv.S的文件,其实linux不是不支持linux,只是不能支持太复杂的操作(这个说法待考证,可能通过修改部分源代码也能实现,因为我在arch/arm/kernel下发现fiq.c文件,有时间再确认下),但是最基本的入口低级操作还是存在的,只需要改动相应的地方就能实现简单的功能。
 
比如我想在fiq的中断里面实现:
1.清楚wakeup中断,2启动一个蜂鸣器(不然不知道进了fiq模式了)
代码如下:
vector_fiq:

 mov r8, #0xe000000c
 orr r8, r8, #0x1000
 orr r8, r8, #0x10
 mov r9, #0x1
 str r9, [ r8 ]
 
 mov r10, #0xe0000008
 orr r10, r10,#0x0000f000
 mov r11, #0x40
 str  r11, [r10] 
 
 mov r10, #0xe0000008
 orr r10, r10, #0x10
 orr r10, r10, #0xf000
 mov r11, #0x40
 str r11, [ r10 ]
 
 subs pc, lr, #4
首先在系统初始化的时候配置gpio口线的fiq模式,使能fiq模式,(因为我是要进中断处理函数的,不是要求唤醒,关于这两个的区别看最后的注意)
这里有个注意点,linux的arm汇编好像不支持ldr rX, =0xXXX这种伪指令模式,因为如果使用这种方式系统立马会报 Bad mode in data abort handler detected: mode FIQ_32,说明取数据错了,因此我采用了上面这种方式,写的好像冗余,先把功能实现了再说,有时间再做改动。当然还有一个需要就是即使在这里也需要用虚拟地址,因为这里已经打开了mmu。
 
自己犯的几个弱智的问题,贴在下面,虽然怕各位取笑,但是更希望警示自己不再犯,也算是一个可查的记录:
 
1.我们一直说arm处理器收到一个中断后会自动调至相应的中断向量表,但是这里的中断是指经过中断控制器过滤的中断信号,也就是说即使硬件产生了中断,但是假设中断使能控制器没有使能,或者屏蔽了中断屏蔽寄存器,这时候还是产生不了cpu能够响应中断的信号,跳不到中断向量表的。
 
2.但是唤醒低功耗模式的中断(idle模式对应所有的普通中断,sleep模式对应wakeup快速中断)可以不通过中断控制器,即使中断没有使能,或者已经被屏蔽了,但是只要有了中断信号,即产生了一个未处理中断,此时就能够唤醒。
比如对于wakeup信号,由于其本身是内部中断,所以不需要配置gpio模式为中断,只要按下wakeup键立马产生唤醒信号,这wakeup信号通过pmc整形后直接作为intc fiq的一个中断源将系统唤醒。
由于idle模式任何中断都能将idle模式唤醒,倘若想用特定的中断唤醒,此时通过终端控制寄存器配置是不起作用的,只有直接切断相应的中断源才行。
 
阅读(8923) | 评论(7) | 转发(0) |
给主人留下些什么吧!~~

JackPalmStone2013-08-28 16:46:46

我这里有一个ARM926的开发板,linux平台,主频200MIPS,内存1Gbit。
今天,做过一个实验,用IRQ方式触发来外部中断,触发源来自GPIOA,下降沿方式触发,在IRQ_Handler()拉低另一个GPIOB。用示波器捕捉了一下,从GPIOA产生下降沿,到GPIOB拉低,中间经历了4个毫秒。有点太不可思议了。
我想请教一下,这种情况正常么?是否切换到FIQ方式要好一些?

qiuruofengye2009-11-17 10:57:04

我定位到stmia sp!, {r0-r7, lr}出错,还没有运行到bl timer2_irq 就已经开始报data abort 错误!我觉得可能是sp指针指错地方的问题,想请教一下sp的初始化在哪???

chinaunix网友2009-11-13 14:57:42

你的data abort是在什么时候出现的?你可以定位一下,具体细化到执行那条语句的时候,如果是在执行stmia那条指令报data abort才可能是堆栈的原因,不过个人觉得应该不是这里出问题的,应该是你的bl函数出问题的。猜测而已,欢迎继续讨论

qiuruofengye2009-11-13 09:51:54

我在中断中做了一下处理 sub sp, sp, #S_FRAME_SIZE sub lr, lr, #4 stmia sp!, {r0-r7, lr} bl timer2_irq /* 我的中断处理函数 */ ldmda sp!, {r0-r7, pc}^ 出现错误是: Bad mode in data abort handler detected 可能是我的压栈操作有错,因为没有压栈操作可正常运行。linux 内核对fiq的堆栈大小是否有限制?

myleeming2009-11-12 12:35:45

改动的地方时在arch/arm/kernel/entry-armv.s中的 vector_fiq:处。需要保存现场的,我这里面只是在fiq里面点一个灯,只是验证性的,所以没做多少工作,其实所谓的保存现场也主要是将r0-r7这几个寄存器压栈,后面的fiq有自己的一套所以不用保存,但是linux中的确是没有对快速中断做更深的实现(只是有一个入口,这个是处理器决定的),希望你的应用不要太复杂,如果想linux中的fiq和irq那样,那就需要自己写patch了,这方面可以参考atmel9200的代码,它给它的fiq打了patch