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编辑  收藏  举报

导航