wince5 ISR中如何传递数据(高分求助)

tee4509 2010-08-19 12:23:00
我用isr-ist模式的中断做过实验,最快差不多响应0.8khz的中断,IST中不用InterruptDone直接操作寄存器后差不多能响应2khz的中断.3khz的时候3k个波差不多要丢失15个左右. 测试方法是用单片机在io输出3k个波,然后在驱动中统计,读完后打印出来.

现在的问题是我需要更高级别的中断响应,于是采用isr模式,看了网上一些文章,大致了解了些,现在最主要的问题是数据传输的问题.
在config.bib文件中增加
RES a0020000 00000800 RESERVED
在common\intr.c中增加
volatile int * m_iUserCnt = (int *)0xa0020000;
volatile int * m_iMaxUserCnt = (int *)0xa0020004;


OEMInterruptHandler函数中增加2个判断
else if (irq == IRQ_EINT2)
{
// Mask and Clear the interrupt.

mask = 1 << irq;
SETREG32(&g_pIntrRegs->INTMSK, mask);
OUTREG32(&g_pIntrRegs->SRCPND, mask);
OUTREG32(&g_pIntrRegs->INTPND, mask);
(*m_iUserCnt)++;

// OUTREG32(&g_pIntrRegs->SRCPND, mask);
CLRREG32(&g_pIntrRegs->INTMSK, mask);
// RETAILMSG(1,(TEXT("int2 occurcnt = %d \r\n",*m_iUserCnt)));
sysIntr = OALIntrTranslateIrq(irq);
}
else if (irq == IRQ_EINT0)
{
// Mask and Clear the interrupt.
mask = 1 << irq;
SETREG32(&g_pIntrRegs->INTMSK, mask);
OUTREG32(&g_pIntrRegs->SRCPND, mask);
OUTREG32(&g_pIntrRegs->INTPND, mask);
(*m_iMaxUserCnt)++;

// OUTREG32(&g_pIntrRegs->SRCPND, mask);
CLRREG32(&g_pIntrRegs->INTMSK, mask);

RETAILMSG(1,(TEXT("int0 occurcnt = %d \r\n",*m_iMaxUserCnt)));
RETAILMSG(1,(TEXT("int2 occurcnt = %d \r\n",*m_iUserCnt)));
sysIntr = OALIntrTranslateIrq(irq);
}
ent2就是需要响应高优先级中断,int0主要是为了输出调试数据,可测试发现始终输出
int0 occurcnt = 1
int2 occurcnt = -2143263584
不知道是什么原因,求大虾帮忙.

另外common的代码是不是每次都要重新sysgen一下,直接build current不行,这样调试起来好浪费时间啊,各位用什么方法呢?
...全文
319 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
tee4509 2010-11-04
  • 打赏
  • 举报
回复
不好意思,这个帖子被我搞忘记了,今天用ce6才想起来
在驱动中
volatile UINT32 *pDrvGlobal;
pDrvGlobal = (volatile UINT32 *)0x8000a000;
RETAILMSG(1, (TEXT("ist-pDrvGlobal:%d \r\n"),*pDrvGlobal));
就可以了,很简单,这个地址直接是物理地址.
跟isr中变量的地址设置一致就可以了
qianjun1978 2010-09-10
  • 打赏
  • 举报
回复
楼主是怎样做到的呢,我的程序也如你的一样,不能累加,值永远等于1.能把你后来解决的方法告诉大家吗?
tee4509 2010-08-21
  • 打赏
  • 举报
回复
周5已经实验成功了,等下周1去试下isr的响应最高频率再把完整的步骤发出来,先结贴给分先~~
tee4509 2010-08-20
  • 打赏
  • 举报
回复
打错了 RETAILMSG(1,(TEXT("irq is = %d \r\n",irq)));
tee4509 2010-08-20
  • 打赏
  • 举报
回复
按上面的方法定义是为了后面能在ist里读取这个数据,static DWORD EnterEINT2Count=0,EnterEINT0Count=0;
这样定义ist里怎么读呢...
不过我试验你的方法了,这样定义也输出不正确,我甚至直接
RETAILMSG(1,(TEXT("irq is = %d \r\n",&irq)));
也输出不正常,难道是RETAILMSG输出的时候已经是用户模式了?继续研究中...
chinesedragon2010 2010-08-19
  • 打赏
  • 举报
回复
"在config.bib文件中增加
RES a0020000 00000800 RESERVED
在common\intr.c中增加
volatile int * m_iUserCnt = (int *)0xa0020000;
volatile int * m_iMaxUserCnt = (int *)0xa0020004;
"
楼主为什么一定要按照上面的方式来定义了,不能在common\intr.c下面的函数OEMInterruptHandler中如下定义吗?
static DWORD EnterEINT2Count=0,EnterEINT0Count=0;
tee4509 2010-08-19
  • 打赏
  • 举报
回复
忘记补充了,我的板子cpu是2440,wince是5.0
楼上说的有道理,我已经改正了,加了初始化了,问题还是没有解决。哭啊,这个问题愁了我一天了。。。
chinesedragon2010 2010-08-19
  • 打赏
  • 举报
回复
“就是不初始化,初值不确定,后面我执行++操作,至少这个值也应该要变才对,现在问题是这个值始终不变”
假如本来之前指向的值我们不确定,或者说是这个值的类型超过了%d表示的范围,那么你++之后会有什么变化呢?说实话,我也不知道,只是觉得可能%d表示不了这个值的范围。
tee4509 2010-08-19
  • 打赏
  • 举报
回复
ent2我接的单片机的io口,ent0接的是个开关按键,2个中断都会进入,只是在进ent0的时候会打印ent2发生的次数。ent0只有测试的时候按下按键才会进入。00020004地址我已经改为80020000与80020004,就是cachce的地址,而且初始化了(就是不初始化,初值不确定,后面我执行++操作,至少这个值也应该要变才对,现在问题是这个值始终不变)
chinesedragon2010 2010-08-19
  • 打赏
  • 举报
回复
楼主确定进入了在进入“else if (irq == IRQ_EINT0)”之前会先进入“else if (irq == IRQ_EINT2)”吗?或者是根本没有进入“else if (irq == IRQ_EINT2)”,首先我们不知道0xa0020004地址处保存的数据,那么*m_iUserCnt的值就不确定吧,这样应该容易出现一些异常的数据。
tee4509 2010-08-19
  • 打赏
  • 举报
回复
呵呵,对了那个ist提高响应的方法也是看到googleman发的文章才去做的,确实提高了点,呵呵,只是不能提高那么多。
tee4509 2010-08-19
  • 打赏
  • 举报
回复
There may be times when you want to pass information between an interrupt service routine (ISR) and an interrupt service thread (IST). For example, because calling an IST each time an interrupt request (IRQ) arrives is a time-consuming process, you might want to design an ISR to buffer IRQ data before calling the IST.

The ISR would return SYSINTR_NOP until the buffer was full, and then would return the appropriate SYSINTR identifier when the ISR is ready for the IST to run. Once the IST runs, it can pick up the data that the ISR has been buffering.

To pass data between an ISR and an IST

Reserve physical memory for the ISR in your Config.bib file.
Config.bib contains several examples of reserving physical memory for the serial and debug drivers.

Use the reserved memory in your ISR call.
Because the ISR runs in kernel mode, the ISR can access the reserved memory to buffer data.

Call the MmMapIoSpace function in your IST to map the physical memory to a virtual address.
MMMapIoSpace calls the VirtualAlloc and VirtualCopy functions to map the physical memory to a virtual-memory address that the IST can access.

You can also call VirtualAlloc and VirtualCopy directly. For example, you can allocate memory outside of the virtual memory space of a process by calling VirtualAlloc with its parameters set to the following values:

dwSize >= 2 MB
flAllocationType set to MEM_RESERVE
flProtect set to PAGE_NOACCESS
In Windows CE, an installable ISR can easily share data with an IST as the memory can be dynamically allocated instead of being reserved in the Config.bib file.

按照pb帮助里说的就是可以,现在就是Use the reserved memory in your ISR call.
这步还实现不了。 我是做一个中断脉冲统计,然后在ist里读(因为ist响应不了高频率的脉冲),所以在isr做统计,统计到一定的数值后再去唤醒ist,就如上面帮助说的
gooogleman 2010-08-19
  • 打赏
  • 举报
回复
这个没有做过,只是想过,楼主直接在isr 处理可以的啊。你想传递数据?
tee4509 2010-08-19
  • 打赏
  • 举报
回复
还是没有人帮忙~~再顶~~
tee4509 2010-08-19
  • 打赏
  • 举报
回复
自己顶!来人帮帮我啊
tee4509 2010-08-19
  • 打赏
  • 举报
回复
这个改过了,开始就是用的你说的那个地址,后来不行我才改到uncached上,问题依旧
Ei 2010-08-19
  • 打赏
  • 举报
回复
RES a0020000 00000800 RESERVED
改成
RES 80020000 00000800 RESERVED 试试
tee4509 2010-08-19
  • 打赏
  • 举报
回复
"另外common的代码是不是每次都要重新sysgen一下,直接build current不行,这样调试起来好浪费时间啊"
是啊,你可以把common下相关代码移植到你的\Src\Common或者\Src\Drivers下面,以便编译和控制。

首先谢谢你的回答,只是目前我还没达到移植common代码到drivers的高度.

这个问题应该是wince很常见的问题吧,怎么回答的人这么少啊?

自己顶下先
chinesedragon2010 2010-08-19
  • 打赏
  • 举报
回复
"另外common的代码是不是每次都要重新sysgen一下,直接build current不行,这样调试起来好浪费时间啊"
是啊,你可以把common下相关代码移植到你的\Src\Common或者\Src\Drivers下面,以便编译和控制。

19,519

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧