RTEMS-libbsd 解决无法使用中断问题
RTEMS-libbsd 是利用RTEMS内核,将freebsd作为一个库的系统。因此更加方便移植各种bsp支持,比如驱动等。
但是在使用中断时,对于某些bsp,会出现中断无法使用的情况。
比如本人在为beaglebone black移植USB驱动时,需要安装usb中断,但是程序运行至interrupt install 函数处会出现终止, 也就是_Terminate。
通过gdb进行debug,gdb输出信息:
(gdb) c
Continuing.
Breakpoint 3, _Terminate (the_source=the_source@entry=RTEMS_FATAL_SOURCE_BSP, the_error=the_error@entry=0) at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/../../cpukit/score/src/interr.c:34
34 {
(gdb) bt
#0 _Terminate (the_source=the_source@entry=RTEMS_FATAL_SOURCE_BSP, the_error=the_error@entry=0) at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/../../cpukit/score/src/interr.c:34
#1 0x800a71c4 in rtems_fatal (error_code=0, fatal_source=RTEMS_FATAL_SOURCE_BSP) at ../../../../../.././beagleboneblack/lib/include/rtems/fatal.h:88
#2 bsp_fatal (code=BSP_FATAL_INTERRUPT_INITIALIZATION) at ../../../../../.././beagleboneblack/lib/include/bsp/fatal.h:142
#3 omap_get_mir_reg (vector=<optimized out>, mask=<optimized out>) at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/lib/libbsp/arm/beagle/irq.c:92
#4 0x800a7270 in bsp_interrupt_vector_disable (vector=<optimized out>) at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/lib/libbsp/arm/beagle/irq.c:113
#5 0x800a7344 in bsp_interrupt_server_trigger (arg=0x8032b488, arg@entry=0x8032b480) at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/lib/libbsp/arm/beagle/../../shared/src/irq-server.c:59
#6 0x800a7584 in bsp_interrupt_server_call_helper (vector=vector@entry=18, options=options@entry=0, handler=<optimized out>, arg=arg@entry=0x800369b8 <nexus_setup_intr+148>, helper=0x800a73b0 <bsp_interrupt_server_install_helper>)
at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/lib/libbsp/arm/beagle/../../shared/src/irq-server.c:276
#7 0x800a7678 in rtems_interrupt_server_handler_install (server=server@entry=0, vector=vector@entry=18, info=<optimized out>, options=options@entry=0, handler=0x800a73b0 <bsp_interrupt_server_install_helper>,
handler@entry=0x80000898 <musbotg_wrapper_interrupt>, arg=arg@entry=0x80396a90) at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/lib/libbsp/arm/beagle/../../shared/src/irq-server.c:352
#8 0x800369b8 in nexus_setup_intr (dev=dev@entry=0x803951a8, child=child@entry=0x803954f8, res=res@entry=0x803982b0, flags=flags@entry=514, filt=filt@entry=0x0, intr=intr@entry=0x80000898 <musbotg_wrapper_interrupt>, arg=0x80396a90,
arg@entry=0x80000bac <musbotg_attach+444>, cookiep=0x8039709c, cookiep@entry=0x80000898 <musbotg_wrapper_interrupt>) at ../../rtemsbsd/rtems/rtems-kernel-nexus.c:307
#9 0x800208dc in BUS_SETUP_INTR (_cookiep=0x80000898 <musbotg_wrapper_interrupt>, _arg=0x80000bac <musbotg_attach+444>, _intr=0x80000898 <musbotg_wrapper_interrupt>, _filter=0x0, _flags=514, _irq=0x803982b0, _child=0x803954f8,
_dev=0x803951a8) at ../../rtemsbsd/include/rtems/bsd/local/bus_if.h:529
#10 _bsd_bus_setup_intr (dev=dev@entry=0x803954f8, r=0x803982b0, flags=flags@entry=514, filter=filter@entry=0x0, handler=handler@entry=0x80000898 <musbotg_wrapper_interrupt>, arg=arg@entry=0x80396a90, cookiep=cookiep@entry=0x8039709c)
at ../../freebsd/sys/kern/subr_bus.c:4584
#11 0x80000bac in musbotg_attach (dev=0x803954f8) at ../../freebsd/sys/arm/ti/am335x/am335x_musb.c:304
#12 0x8001f07c in DEVICE_ATTACH (dev=0x803954f8) at ../../rtemsbsd/include/rtems/bsd/local/device_if.h:180
#13 _bsd_device_attach (dev=dev@entry=0x803954f8) at ../../freebsd/sys/kern/subr_bus.c:2947
#14 0x8001ff44 in _bsd_device_probe_and_attach (dev=dev@entry=0x803954f8) at ../../freebsd/sys/kern/subr_bus.c:2903
#15 0x8001fff0 in _bsd_bus_generic_attach (dev=<optimized out>) at ../../freebsd/sys/kern/subr_bus.c:3714
#16 0x8001f07c in DEVICE_ATTACH (dev=0x803951a8) at ../../rtemsbsd/include/rtems/bsd/local/device_if.h:180
#17 _bsd_device_attach (dev=dev@entry=0x803951a8) at ../../freebsd/sys/kern/subr_bus.c:2947
#18 0x8001ff44 in _bsd_device_probe_and_attach (dev=dev@entry=0x803951a8) at ../../freebsd/sys/kern/subr_bus.c:2903
#19 0x800203e8 in _bsd_bus_generic_new_pass (dev=0x80392950) at ../../freebsd/sys/kern/subr_bus.c:4000
#20 0x8001eca8 in BUS_NEW_PASS (_dev=0x80392950) at ../../rtemsbsd/include/rtems/bsd/local/bus_if.h:939
#21 _bsd_bus_set_pass (pass=2147483647) at ../../freebsd/sys/kern/subr_bus.c:987
#22 0x8003e2fc in _bsd_mi_startup () at ../../freebsd/sys/kern/init_main.c:306
#23 0x80036228 in rtems_bsd_initialize () at ../../rtemsbsd/rtems/rtems-kernel-init.c:158
#24 0x800005e4 in Init (arg=<optimized out>) at ../../testsuite/usb01/init.c:110
#25 0x800ccfcc in _Thread_Handler () at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/../../cpukit/score/src/threadhandler.c:88
#26 0x800b9cb0 in _Thread_Life_action_handler (executing=0x0, action=<optimized out>, lock_context=0x0) at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/../../cpukit/score/src/threadrestart.c:379
#27 0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
(gdb) up
#3 omap_get_mir_reg (vector=<optimized out>, mask=<optimized out>) at /home/christian/rtems/rtems-sichenzhao/build/..//rtems/c/src/lib/libbsp/arm/beagle/irq.c:92
92 bsp_fatal(0);
(gdb) list
87 mir_reg = OMAP3_INTCPS_MIR2;
88 } else if (vector < 128u) {
89 mir_reg = OMAP3_INTCPS_MIR3;
90 } else {
91 /* Invalid IRQ number. This should never happen. */
92 bsp_fatal(0);
93 }
94
95 return mir_reg;
96 }
(gdb)
能够看出,代码是终止在bsp_fatal()中,也就是rtems源码中beagle的irq.c文件
这样看来,问题的原因很明显了:
am335x允许的最大合法中断向量是127,而产生了一个128的中断向量,导致fatal error。
128向量是被rtems系统内部中断服务所使用的,中断服务器是一种在中断上下文中进行较长处理的方法。中断服务是从FreeBSD那边继承的方法,若一个中断产生,一个task会被唤醒来处理,这样可以避免长的中断处理会阻塞其他中断。
在进行bsp初始化时,disable了中断,也就是调用了bsp_interrupt_vector_disable函数,这个函数并不知道哪些中断需要用,哪些中断不需要用。因此导致了128也进行了判断。128是不需要被enable或者disable的,它是一个虚拟的中断号。
解决方法非常简单,在rtems源码的beagle bsp文件夹下的irq.c文件, bsp_interrupt_vector_disable 和bsp_interrupt_vector_enable函数中,加上一个判断,如果该interrupt vector是有效的(0-127),那么才进行处理。判断函数如下:
if (bsp_interrupt_is_valid_vector(vector))
本人创建了对于beaglebone black的补丁,已经提交给rtems devel,有需要的可以进行下载:
https://lists.rtems.org/pipermail/devel/2017-June/018159.html
patch内容如下:
Enable/disable vector routines now check for a valid vector.
Without these guards, the enable/disable vector routines
will not work with the interrupt server.
---
c/src/lib/libbsp/arm/beagle/irq.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/c/src/lib/libbsp/arm/beagle/irq.c b/c/src/lib/libbsp/arm/beagle/irq.c
index d080a5e..35750ba 100644
--- a/c/src/lib/libbsp/arm/beagle/irq.c
+++ b/c/src/lib/libbsp/arm/beagle/irq.c
@@ -98,11 +98,14 @@ static uint32_t omap_get_mir_reg(rtems_vector_number vector, uint32_t *const mas
rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
{
uint32_t mask, cur;
- uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
- cur = mmio_read(omap_intr.base + mir_reg);
- mmio_write(omap_intr.base + mir_reg, cur & ~mask);
- flush_data_cache();
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
+
+ cur = mmio_read(omap_intr.base + mir_reg);
+ mmio_write(omap_intr.base + mir_reg, cur & ~mask);
+ flush_data_cache();
+ }
return RTEMS_SUCCESSFUL;
}
@@ -110,11 +113,14 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
{
uint32_t mask, cur;
- uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
- cur = mmio_read(omap_intr.base + mir_reg);
- mmio_write(omap_intr.base + mir_reg, cur | mask);
- flush_data_cache();
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
+
+ cur = mmio_read(omap_intr.base + mir_reg);
+ mmio_write(omap_intr.base + mir_reg, cur | mask);
+ flush_data_cache();
+ }
return RTEMS_SUCCESSFUL;
}
--
2.7.4
posted on 2017-06-18 15:05 sichenzhao 阅读(329) 评论(0) 编辑 收藏 举报