分析三星5.0BSP中断

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

看三星的5.0中断,看的一头雾水,相当郁闷。现在重新理清一下。

sontitan牛人也指示过一些。

引用楼主 wangxin_801115 的帖子:
请问这两个函数KernelIoControl和InterruptInitialize函数的区别是什么呢??
个人理解:先用KernelIoControl申请中断号
          然后利用InterruptInitialize把 (从KernelIoControl申请的)中断号与事件相关联
          主要作用是使能waitForSingleObject中挂起的事件
KernelIoControl这个函数有很多人都说不能申请成功
那么是否还有另外一种所谓的静态申请中断号的方法
在oalintr.h中添加中断的宏定义
然后…
 

1 2个函数没有任何关系;KernelIoControl是驱动/应用程序和kernel通讯的一个接口函数,具体的调用意义是看该函数的IOCTRL是什么以及kernel中对应的处理函数(ioctrl table);
2 关于中断,WINCE 5之前都是静态中断,从CE 5开始中断申请分为动态申请和静态分配2种;楼主用的KernelIoControl+IOCTL_HAL_REQUEST_SYSINTR就是动态申请的方法;静态分配其实很简单,在OEMInterruptHandler里直接switch case即可;具体实现很多,各家BSP不一样,但是道理都是如此;
其实,动态申请就是由系统维护一个table,使得OEM允许其他厂商的驱动以安装的形式动态加到这个table里。作为OEM自己,其实维护一个静态的中断分配就可以了,驱动完全不用动态申请。只不过很多参考BSP用了这个形式,导致大家都在动态申请。

后来有人提示,我们来分析如下代码

// read registry settings

    // read the SDIO SYSINTR value
    m_dwSDIOIrq = regDevice.ValueDW( SDIO_IRQ_TEXT, 0xffffffff );
    if( m_dwSDIOIrq == 0xffffffff )
    {
        // invalid SDIO IRQ value!
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("invalid SDIO IRQ value!/r/n")));
        fRetVal = FALSE;
        goto FUNCTION_EXIT;
    }

    // convert the SDI hardware IRQ into a logical SYSINTR value
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &m_dwSDIOIrq, sizeof(DWORD), &m_dwSDIOSysIntr, sizeof(DWORD), NULL))
    {
        // invalid SDIO SYSINTR value!
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("invalid SDIO SYSINTR value!/r/n")));
        m_dwSDIOSysIntr = SYSINTR_UNDEFINED;
        fRetVal = FALSE;
        goto FUNCTION_EXIT;
    }
m_dwSDIOSysIntr 这个变量是在哪里定义的呢?;不过根据m_dwSDIOSysIntr = SYSINTR_UNDEFINED;
这个可以看出,这个明显和中断相关了。因为刚开始初始化中断都是m_SYSINTR_UNDEFINED的;

后来找到m_dwSDIOSysIntr有关的SD中断线程绑定

 //----- 10. Setup the IST for handling SDIO data transfer interrupts -----
    m_hSDIOInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    
    if(NULL == m_hSDIOInterruptEvent) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }

    // initialize the card insertion interrupt event
    if(!InterruptInitialize (m_dwSDIOSysIntr, m_hSDIOInterruptEvent,
                             NULL, 0)) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }

    m_hSDIOInterruptThread = CreateThread(NULL, 0,
                                          (LPTHREAD_START_ROUTINE)SD_IOInterruptIstThread,
                                          this, 0, &threadID);
后来又找到了如下函数

//----- 2. Disable and cleanup the ISTs/events ------
    InterruptDisable (m_dwSDIOSysIntr);
//=====================================================
 case SDHCDAckSDIOInterrupt:                                     
            
            DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDAckSDIOInterrupt/r/n")));
            //----- 2. Clear the SDIO interrupt pending bit -----
            Ack_SDIO_Interrupts();
            InterruptDone(m_dwSDIOSysIntr);//--------和4.2的有什么区别?
后来我又找到了如下代码
//--IRQ_EINT0是在 s3c2440a_intr.h中定义的,现在就越来越明朗了
//--而IRQ_SDI为什么没有如下的赋值呢?因为SD卡中断在注册表中设置了
//#define IRQ_SDI  21--在注册表也设置为21,这个原理和IRQ_EINT0等价了
UINT32 g_PwrButtonIrq = IRQ_EINT0;
UINT32 g_PwrButtonSysIntr = SYSINTR_UNDEFINED;
UINT32 g_RebootButtonIrq = IRQ_EINT2;
UINT32 g_RebootButtonSysIntr = SYSINTR_UNDEFINED;
 

到现在已经可以对5.0的BSP方法做个推断了:5.0BSP的所谓动态中断设置方法,就是在驱动中才初始化中断(在4.2下是静态中断,在OAL中初始化的)和注册表等结合起来。使用kernelIoControl这个函数来转换物理中断和逻辑中断(至于为什么要做个转换,我真的有点不了解,有点浪费时间,也许我等级太低了。)

但是在OAL又必须初始化什么呢?以前看了好多,一直带着4.2的影子去看程序——哎,老毛病。

现在再来看看OAL的OEMInit函数以及被他调用的函数。

//------------------------------------------------------------------------------
//
//  Function:  OEMInit
//
//  This is Windows CE OAL initialization function. It is called from kernel
//  after basic initialization is made.
//
void OEMInit()
{
    OALMSG(OAL_FUNC, (L"+OEMInit/r/n"));

    CEProcessorType=PROCESSOR_STRONGARM;

    // Set memory size for DrWatson kernel support
    dwNKDrWatsonSize = 128 * 1024;

    // Initilize cache globals
    OALCacheGlobalsInit();

    OALLogSerial(
        L"DCache: %d sets, %d ways, %d line size, %d size/r/n", 
        g_oalCacheInfo.L1DSetsPerWay, g_oalCacheInfo.L1DNumWays,
        g_oalCacheInfo.L1DLineSize, g_oalCacheInfo.L1DSize
    );
    OALLogSerial(
        L"ICache: %d sets, %d ways, %d line size, %d size/r/n", 
        g_oalCacheInfo.L1ISetsPerWay, g_oalCacheInfo.L1INumWays,
        g_oalCacheInfo.L1ILineSize, g_oalCacheInfo.L1ISize
    );
    
    // Initialize interrupts
    if (!OALIntrInit()) {
        OALMSG(OAL_ERROR, (
            L"ERROR: OEMInit: failed to initialize interrupts/r/n"
        ));
    }

    // Initialize system clock
    OALTimerInit(1, 17, 0); //S3C2440A_PCLK/245/16/1000=16.992

    ConfigureGPIO();

    InitDisplay();

    // Initialize the KITL connection if required
    OALKitlStart();

    OALMSG(OAL_FUNC, (L"-OEMInit/r/n"));
}
我们要找的是OALIntrInit这个函数

C:/WINCE500/PLATFORM/SMDK2440A/Src/Common/Intr_dvs/intr.c(74)://  Function:  OALIntrInit


//------------------------------------------------------------------------------
//
//  Function:  OALIntrInit
//
//  This function initialize interrupt mapping, hardware and call platform
//  specific initialization.
//
BOOL OALIntrInit()
{
    BOOL rc = FALSE;
    
    OALMSG( OAL_FUNC&&OAL_INTR, (L"+OALInterruptInit/r/n") );

    // Initialize interrupt mapping
    OALIntrMapInit();

    // First get uncached virtual addresses
    g_pIntrRegs = (S3C2440A_INTR_REG*)OALPAtoVA(
        S3C2440A_BASE_REG_PA_INTR, FALSE
    );
    g_pPortRegs = (S3C2440A_IOPORT_REG*)OALPAtoVA(
        S3C2440A_BASE_REG_PA_IOPORT, FALSE
    );
#ifdef DVS_EN
    g_pLCDRegs = (S3C2440A_LCD_REG*)OALPAtoVA(
        S3C2440A_BASE_REG_PA_LCD, FALSE
    );
#endif
    
    // Mask and clear external interrupts
    OUTREG32(&g_pPortRegs->EINTMASK, 0xFFFFFFFF);
    OUTREG32(&g_pPortRegs->EINTPEND, 0xFFFFFFFF);

    // Mask and clear internal interrupts
    OUTREG32(&g_pIntrRegs->INTMSK, 0xFFFFFFFF);
    OUTREG32(&g_pIntrRegs->SRCPND, 0xFFFFFFFF);

    // S3C2440A developer notice (page 4) warns against writing a 1 to any
    // 0 bit field in the INTPND register.  Instead we'll write the INTPND
    // value itself.
    OUTREG32(&g_pIntrRegs->INTPND, INREG32(&g_pIntrRegs->INTPND));

    // Unmask the system tick timer interrupt
    //看来在OAL中只有定时器中断这个心脏没有停止
    CLRREG32(&g_pIntrRegs->INTMSK, 1 << IRQ_TIMER4);

#ifdef OAL_BSP_CALLBACKS
    // Give BSP change to initialize subordinate controller
    // 在BSP中初始化中断
    rc = BSPIntrInit();
#else
    rc = TRUE;
#endif

    OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALInterruptInit(rc = %d)/r/n", rc));
    return rc;
}
 

既然又出来个BSPIntrInit,那我就再往下查。——果然有新发现。

C:/WINCE500/PLATFORM/SMDK2440A/Src/Kernel/Oal/intr.c(24):BOOL BSPIntrInit()


//------------------------------------------------------------------------------
//
//  Function:  BSPIntrInit
//
BOOL BSPIntrInit()
{
    S3C2440A_IOPORT_REG *pOalPortRegs;
    ULONG value;

    OALMSG(OAL_INTR&&OAL_FUNC, (L"+BSPIntrInit/r/n"));
    
    // Then get virtual address for IO port
    pOalPortRegs = OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE);

    // Set GPG1 as EINT9这个EINT9用来干什么呢?
    value = INREG32(&pOalPortRegs->GPGCON);
    OUTREG32(&pOalPortRegs->GPGCON, (value & ~(3 << 2))|(2 << 2));

    // Disable pullup
    value = INREG32(&pOalPortRegs->GPGUP);
    OUTREG32(&pOalPortRegs->GPGUP, value | (1 << 1));

    // High level interrupt
    value = INREG32(&pOalPortRegs->EXTINT1);
    OUTREG32(&pOalPortRegs->EXTINT1, (value & ~(0xf << 4))|(0x1 << 4));

    // Add static mapping for Built-In OHCI 
    OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBH);

    // OALIntrStaticTranslate(SYSINTR_USBFN, IRQ_USBFN);
    OALMSG(OAL_INTR&&OAL_FUNC, (L"-BSPIntrInit(rc = 1)/r/n"));
    return TRUE;
}
看来现在终于可以对5.0中断做个总结了——5.0BSP中断方法

一、静态中断——使用BSPIntrInit 不是必须的,在OAL中初始化。

二、动态中断——使用kernelIoControl——在驱动中加载/删除。

经验教训:不要乱看代码,要抓住中断流程,抓住OEMInit这个函数是关键。

看来网上有些说法未必正确。——5.0BSP中断总结,完!


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gooogleman/archive/2008/11/10/3266018.aspx

 

S3C44B0X开发板VxWorks BSP移植实战详解 S3C44B0X是三星基于ARM7TDMI内核设计的16/32位RISC处理器,主频可达66MHz,具备低功耗与高集成度特性。其三级流水线结构支持Thumb指令集,提升代码密度与执行效率。定义关键宏如_S3C44B0X_,并在Makefile中传入:链接脚本link.cmd定义内存布局:SECTIONS确保代码正确映射至物理地址空间,为后续MMU配置打下基础。 阅读详情

相关推荐

瑞萨RA4M2实现AGT基本定时功能(FSP库驱动).zip

瑞萨RA4M2驱动程序,Keil开发环境,FSP库驱动。 项目代码可直接编译运行~

signature=ca3da65e915f7d09b6ae2068371c31d1,lua-resty-jwt/sign-verify.t at ee1d024071f872e2b5a66eaaf9...

use Test::Nginx::Socket::Lua;repeat_each(2);plan tests => repeat_each() * (3 * blocks());our $HttpConfig = <lua_package_path 'lib/?.lua;;';_EOC_no_long_string();run_tests();__DATA__=== TEST 1: J...

weixin_39979948的博客 4133

22.修复nanopi t2 cpu调频不起作用 nxp-cpufreq nxp-cpufreq.0: Cannot get regulator for DVS supply vdd_arm_1.3V

[root@minicoco ~]# dmesg | grep cpu [ 0.000000] Initializing cgroup subsys cpuset [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] PERCPU: Embedded 9 pages/cpu @c136a000 s12352 r8192 d16320 u36864 [ 0.000000] pcpu-alloc: s12352 r8192 d163

柏鑫的博客 2288

DAVIS Driving Dataset 2020 (DDD20) 【转载】

DDD20 是一个非常棒是数据集,DDD20 的 readme 文件在,方便国内研究这参考。 【转载】https://docs.google.com/document/d/1Nnyjo4j0rvdgHQ0cS8z0Q1QBRLHDtwh7XW1u9ygmQEs/edit# DAVIS Driving Dataset 2020 (DDD20) Yuhuang Hu, Jonathan Binas, Daniel Neil, Shih-Chii Liu, Tobi Delbruck March 202.

u014546828的博客 9348

再次分析5.0BSP中断

三星5.0中断,看的一头雾水,相当郁闷。现在重新理清一下。sontitan牛人也指示过一些。引用楼主 wangxin_801115 的帖子:请问这两个函数KernelIoControl和InterruptInitialize函数的区别是什么呢?? 个人理解:先用KernelIoControl申请中断号           然后利用InterruptInitialize把 (从Kerne

gooogleman#foxmail.com 3215

重装linux内核启动不了,韦东山-内核启动挂接跟文件Failed to execute /linuxrc. - 百问网嵌入式问答社区...

+---------------------------------------------+| S3C2440A USB Downloader ver R0.03 2004 Jan |+---------------------------------------------+USB: IN_ENDPOINT:1 OUT_ENDPOINT:3FORMAT: +++NOTE: Power off...

weixin_33648177的博客 1052

嵌入式Linux 设备树 中断详解 示例分析 三星 NXP RK

由于学习过程中很少接触实际不同平台的设备树案例,为了更好地掌握设备树,我们通过分析不同的平台中断案例,来理论结合实际掌握设备树。

你要拥有一个你喜欢并且热爱的人生 9888

分析5.0BSP中断

三星5.0中断,看的一头雾水,相当郁闷。现在重新理清一下。sontitan牛人也指示过一些。引用楼主 wangxin_801115 的帖子:请问这两个函数KernelIoControl和InterruptInitialize函数的区别是什么呢?? 个人理解:先用KernelIoControl申请中断号           然后利用InterruptInitialize把 (从Kerne

ymzhou117的专栏 605

wince5.0 标准三星BSPOAL详细分析

首先看如下函数,是OAL的初始化函数,我看后大吃一惊,因为和4.2升级到5.0BSP相差太大了。//------------------------------------------------------------------------------ // //  Function:  OEMInit // //  This is Windows CE OAL 

gooogleman#foxmail.com 1574

WINCE 下 NANDFLASH 文件系统不能写

WINCE 下 NANDFLASH 文件系统不能写 [问题点数:100分,结帖人:GaryLiu1104] GaryLiu1104 (Gary Liu) 等 级: 结帖率:100.00% 楼主发表于:2009-12-24 13:52:19 ATMEL at91sam9261,操作系统Wince5.0,256M的三星K9F2G08闪存,系统用了32M,其他是NandFlash文件系统,BSP...

weixin_34109408的博客 191

驱动程序实例(五):LCD驱动程序分析(Samsung LCD)

/************************************************************************************ *本文为个人学习记录,如有错误,欢迎指正。 *本文参考资料: *        朱有鹏嵌入式课程 *        https://blog.csdn.net/ultraman_hs/article/details/5...

weixin_30878501的博客 199

TLV320AIC3x音频编解码器在WinCE 5.0上的驱动开发与移植实战

音频编解码器(Codec)是嵌入式音频系统的核心,负责数字与模拟信号的转换。其驱动开发涉及对硬件接口(如SPI/I2C、I2S)和操作系统内核的深入理解,是实现高质量音频功能的基础。在嵌入式领域,稳定可靠的驱动是保障音频子系统性能与兼容性的关键,尤其在资源受限的经典操作系统(如Windows CE)上,驱动开发更具挑战。本文以TLV320AIC3x系列Codec为例,结合**SPI/I2C**总线通信和**I2S**音频接口的配置原理,深入剖析了在WinCE 5.0平台上的驱动架构设计、寄存器配置、时钟管理

weixin_34416754的博客 469

Windows CE 休眠唤醒全面解析

欢迎加入Wince技术讨论群QQ#326444254 Windows CE 休眠唤醒全面解析(基于2440平台) Windows CE 作为一个广泛应用于移动便携设备上的操作系统,提供了完善的电源管理的功能。其中,休眠唤醒便是一个重要的功能。那么,休眠唤醒是什么原理呢,这首先要从硬件说起。这里呢,我就拿用自己得最熟练的三星平台的2440 CPU为例来和大家探讨一下。

u011610939的专栏 736

四极管:Windows CE 休眠唤醒全面解析(基于2440平台)

Windows CE 休眠唤醒全面解析(基于2440平台)(1) Windows CE 休眠唤醒全面解析(基于2440平台) Windows CE 作为一个广泛应用于移动便携设备上的操作系统,提供了完善的电源管理的功能。其中,休眠唤醒便是一个重要的功能。那么,休眠唤醒是什么原理呢,这首先要从硬件说起。这里呢,我就拿用自己得最熟练的三星平台的2440 CPU为例来和大家探讨一下。

杨琦(四极管) 1352

Windows CE 休眠唤醒全面解析(转)

Windows CE 休眠唤醒全面解析(基于2440平台)发 布 时 间 : 2009-03-20    来 源 : http://www.cnblogs.com/zq2002/archive/2008/09/05/1    作 者 : 匿名   浏 览 : 2896 <br /><br /><br />Windows CE 作为一个广泛应用于移动便携设备上的操作系统,提供了完善的电源管理的功能。其中,休眠唤醒便是一个重要的功能。那么,休眠唤醒是什么原理呢,这首先要从硬件说起。这里呢,我就拿用自己得

tangchao198507的专栏 849

Windows CE 休眠唤醒全面解析(基于2440平台) ——转载

 Windows CE 作为一个广泛应用于移动便携设备上的操作系统,提供了完善的电源管理的功能。其中,休眠唤醒便是一个重要的功能。那么,休眠唤醒是什么原理呢,这首先要从硬件说起。这里呢,我就拿用自己得最熟练的三星平台的2440 CPU为例来和大家探讨一下。首先看2440 Datasheet 里关于休眠部分的描述SLEEP ModeThe block disconnects the in

冷饮 940

uboot分析之 内存分配

2.u-boot映像的地址0并非指物理地址0,由不同的启动方式映射到不同的地址。例如v210是映射到0xD0000000处的irom。 3.TEXT_BASE等指向SDRAM的地址均为虚拟地址。 4.TEXT_BASE为顶层Makefile中定义的,例如三星官方BSP中定义的是0xC3E00000,它是程序实际的链接首地址。 5.SDRAM_BASE被MMU映射在0xC00000

Tim 1303
上一篇: wince中断体系重要文件nkintr.h分析
下一篇: 中断代码结构比较之WinCE4.2 VS WinCE5.0
勇敢飞
博客等级 码龄18年 21粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值