WINCE5.0的中断深入了解

转至:http://www.hzlitai.com.cn/bbs/viewthread.php?tid=11507&extra=page%3D2

 

When an interrupt is processed, a specific sequence of events takes place.
你需要为你的设备驱动写好中断处理请求(ISR)和中断服务线程(IST),并牢记这些事件的顺序:

 

1,当一个中断发生,处理器跳转到核心的中断处理程序(exception handler );
2,这个中断处理程序禁止所有同级或低优先级的其他中断,然后为当前的IRQ调用对应的ISR;
3,ISR中会按照中断标识的形式,返回一个逻辑中断号给中断处理程序,并会置位板级设备中断;
4,中断处理程序重新使能所有的中断,而目前的中断已经在上一步中置位了,然后就触发对应的IST事件;
5,IST就绪,服务于中断设备,然后完成对中断的处理;
6,IST调用InterruptDone函数,该函数将顺序调用OAL层的OEMInterruptDone函数,它将重新使能当前的中断。

原文:
When an interrupt occurs, the microprocessor jumps to the kernel exception handler.
The exception handler disables all interrupts of an equal and lower priority at the microprocessor, and then calls the appropriate ISR for the physical interrupt request (IRQ).
The ISR returns a logical interrupt, in the form of an interrupt identifier, to the interrupt handler and typically masks the board-level device interrupt.
The interrupt handler re-enables all interrupts at the microprocessor, with the exception of the current interrupt, which is left masked at the board, and then signals the appropriate IST event.
The IST is scheduled, services the hardware, and then finishes processing the interrupt.
The IST calls the InterruptDone function, which in turn calls the OEMInterruptDone function in the OAL.
OEMInterruptDone re-enables the current interrupt.

用电源按键pwrbutton驱动来对应这个序列。


1,物理中断和逻辑中断的对应关系如何建立?


这个函数用将物理中断号来获取逻辑中断号:


KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_PwrButtonIrq, sizeof(UINT32), &g_PwrButtonSysIntr, sizeof(UINT32), NULL))


其中:UINT32 g_PwrButtonIrq = IRQ_EINT0;
从help里面查出,KernelIoControl函数最终是调用OEMIoControl函数。
WINCE500/PLATFORM/COMMON/SRC/COMMON/IOCTL/ioctl.c里找到它的定义了,关键代码:
// Execute the handler
    rc = g_oalIoCtlTable.pfnHandler(
        code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
    );

 

在SMDK2440/Src/Kernel/Oal/ioctl.c中可以找到:
const OAL_IOCTL_HANDLER g_oalIoCtlTable[] = {
#include "ioctl_tab.h"
};
在SMDK2440/Src/Inc/ioctl_tab.h文件中,找到这个表的定义。这个命令对应的函数是OALIoCtlHalRequestSysIntr。
PLATFORM/COMMON/SRC/COMMON/IOCTL/ioctl.c找到这个函数定义:
// Find if it is new or old call type
    if (inpSize > sizeof(UINT32) && pInpData[0] == -1) {
        // Second UINT32 contains flags, third and subsequents IRQs
        sysIntr = OALIntrRequestSysIntr(
            inpSize/sizeof(UINT32) - 2, &pInpData[2], pInpData[1]
        );
    } else {       
        // This is legacy call, first UINT32 contains IRQ
        sysIntr = OALIntrRequestSysIntr(1, pInpData, 0);
    }
WINCE500/PLATFORM/COMMON/SRC/COMMON/INTR/BASE/map.c找到OALIntrRequestSysIntr定义:
irq = pIrqs[0];
sysIntr = g_oalIrq2SysIntr[irq];
在同一个文件中定义:
static UINT32 g_oalIrq2SysIntr[OAL_INTR_IRQ_MAXIMUM];
对这个表格赋值仅有两个地方:
VOID OALIntrStaticTranslate(UINT32 sysIntr, UINT32 irq)
{
    OALMSG(OAL_FUNC&&OAL_INTR, (
        L"+OALIntrStaticTranslate(%d, %d)/r/n", sysIntr, irq
    ));
    if (irq < OAL_INTR_IRQ_MAXIMUM && sysIntr < SYSINTR_MAXIMUM) {
        g_oalSysIntr2Irq[sysIntr] = irq;
        g_oalIrq2SysIntr[irq] = sysIntr;
    }       
    OALMSG(OAL_FUNC&&OAL_INTR, (L"-OALIntrStaticTranslate/r/n"));
}


OALIntrStaticTranslate和OALIntrRequestSysIntr本身两个函数负责建立对应表。后者如果在现有的中断表中找不到已经建立的对应关系,就会分配一个未定义的Sysintr逻辑中断号给这个物理中断号。因此逻辑中断和物理中断的对应,可以说是随机的,只要保证两者是一一对应就好了,不必要硬性建立一个中断号表格(像WINCE4.2那样)。
代码中只找到OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBH);是静态对应。
当中断处理程序获得了逻辑中断号,那么就会触发该中断号关联着的事件。

2,核心部分的中断处理程序如何获得物理中断号?(这个问题的目的是:如何添加一个原来系统中没有的物理中断)

Physical interrupts (IRQs) are hardware lines over which devices can send interrupt signals to the microprocessor. Logical interrupts (SYSINTRs) are a mapping of the IRQ, which the OAL specifies.

 

一般情况下将ISR与中断处理程序相关联的注册在系统启动的时候进行。在启动过程中,在OAL层kernel调用OEMInit函数。然后,OEMInit调用HookInterrupt 函数来通知中断处理程序,哪些ISR对应到某个物理中断。
原文:You generally register your ISRs with the exception handler at system boot time. During boot, the kernel calls the OEMInit function in the OEM Adaptation Layer (OAL). Next, OEMInit calls the HookInterrupt function to inform the exception handler of which ISRs correspond to individual physical interrupt lines. A few subroutines in the OAL, such as the OEMInterruptEnable, OEMInterruptDisable, and OEMInterruptDone functions, are also used in interrupt processing.

 


WINCE500/PUBLIC/COMMON/OAK/INC/nkintr.h,定义了某些逻辑中断号,声明了hookInterrupt等函数。除此之外,再没有hookInterrupt的定义。
看看WINCE500/PLATFORM/SMDK2440A/src/kernel/oal/init.c里面的OEMinit函数做了些什么:
// Initialize interrupts
    if (!OALIntrInit()) {
        OALMSG(OAL_ERROR, (
            L"ERROR: OEMInit: failed to initialize interrupts/r/n"
        ));
    }

OALIntrInit函数在WINCE500/PLATFORM/COMMON/SRC/ARM/SAMSUNG/S3C2440A/Intr/intr.c文件中定义:
调用OALIntrMapInit()函数
初始化寄存器;
最后调用:
#ifdef OAL_BSP_CALLBACKS
    // Give BSP change to initialize subordinate controller
    rc = BSPIntrInit();
#else
    rc = TRUE;
#endif


OALIntrMapInit()函数里面对两个中断表做了初始化:
    for (i = 0; i < SYSINTR_MAXIMUM; i++) {
        g_oalSysIntr2Irq = OAL_INTR_IRQ_UNDEFINED;
    }
    for (i = 0; i < OAL_INTR_IRQ_MAXIMUM; i++) {
        g_oalIrq2SysIntr = SYSINTR_UNDEFINED;
    }

 

WINCE500/PLATFORM/COMMON/SRC/ARM/SAMSUNG/S3C2440A/Intr/sources:

 

TARGETNAME=oal_intr_s3c2440a
TARGETTYPE=LIBRARY
SYNCHRONIZE_DRAIN=1
NOMIPS16CODE=1

 

CDEFINES=$(CDEFINES) -DCEDDK_USEDDKMACRO -DOAL_BSP_CALLBACKS
----------------------------------------------------------------------------------
CDEFINES=-DSomeDef : This sets one or more preprocessor definitions. You must include the -D switch on each define you add. You can add new defines by using this syntax: "CDEFINES=$(CDEFINES) -DAnotherDef", or you can ignore existing settings with this syntax: "CDEFINES=-DOnlyDef".
----------------------------------------------------------------------------------
因此BSPIntrInit会被执行。
在WINCE500/PLATFORM/SMDK2440A/Src/Kernel/Oal/intr.c有这个函数的定义:
做了:
// Set GPG1 as EINT9
// Add static mapping for Built-In OHCI 
OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBH);
到这里,无法了解如何添加一个物理中断。

文章《wince5.0中断的详细解释》地址:http://www.hzlitai.com.cn/article/ARM9-article/system/wince_interrupt.html
其中说“在CPU接收到中断后,对中断的处理是在 OEMInterruptHandler()中,该函数的首先屏蔽该中断,最后得到实际中断IRQ所对应的sysintr的值”
OEMInterruptHandler函数在WINCE500/PLATFORM/COMMON/SRC/ARM/SAMSUNG/S3C2440A/Intr/intr.c文件中,感觉到它实际上就是上面中断序列中谈到的“中断处理程序”和ISR。就是说,中断发生之后,CPU并不知道到底是哪个中断发生了,实际上WINCE中也没有建立中断矢量表,而是直接跳转到OEMInterruptHandler函数,然后在其中查看g_pIntrRegs->INTOFFSET寄存器,来查看到底发生了什么中断。
在s3c2440a_intr.h文件里面有中断号宏定义:

 

#define IRQ_EINT0           0           // Arbiter 0
#define IRQ_EINT1           1
#define IRQ_EINT2           2
#define IRQ_EINT3           3

 

 

 

 

......
INTOFFSET寄存器的值与这个宏定义是完全一一对应。
这样,也就搞清楚了物理中断号如何获得,又如何对应到逻辑中断号,最后,触发了IST,整个中断处理就结束了。2440全部的中断源都已经被纳入了,添加一个采用某个中断源的设备驱动,只需要用kernelIOControl函数通过物理中断产生一个逻辑中断号就可以了!

这样的话,只要在0x18位置有一个跳转指令就可以了(但还没有找到这条跳转指令)。

3,其他中断相关函数了解

关注WINCE500/PLATFORM/COMMON/SRC/ARM/SAMSUNG/S3C2440A/Intr/intr.c中的其他函数:
OEMInterruptHandler包含了对以下中断的判断和处理:
IRQ_TIMER4,这个是系统节拍;
IRQ_TIMER2,作用未知(Profiling timer);
IRQ_EINT4_7,EINT8_23,外部中断;
任何一个中断发生后,先mask该中断(禁止中断),然后再清除中断请求:
mask = 1 << irq;
            SETREG32(&g_pIntrRegs->INTMSK, mask);
            OUTREG32(&g_pIntrRegs->SRCPND, mask);
            OUTREG32(&g_pIntrRegs->INTPND, mask);

其它中断获取逻辑中断号:
// First find if IRQ is claimed by chain
        sysIntr = NKCallIntChain((UCHAR)irq);
        if (sysIntr == SYSINTR_CHAIN || !NKIsSysIntrValid(sysIntr)) {
            // IRQ wasn't claimed, use static mapping
            sysIntr = OALIntrTranslateIrq(irq);
        }

关于NKCallIntChain的说明:
如果没有与ISR关联的IRQ事件,返回SYSINTR_CHAIN ;
除此之外,将返回IRQ对应的SYSINTR值。

 

If no ISR has handled the IRQ event, SYSINTR_CHAIN is returned.

 

Otherwise, a valid SYSINTR value is returned to the OEM. The OEM must then pass this value back to the kernel so the IST can be triggered.
增加一个采用中断的设备驱动,这个函数不用修改。

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值