学者之家电子论坛--打造电子工程师共同致富的平台's Archiver

paul85 发表于 2009-12-17 11:17

求助,ISR的数据传递

我要实现一个功能,在定时器4中断里发脉冲出去,并记录脉冲数目。并且要将脉冲数目传递给驱动程序或者应用程序。尝试在config.BIB文件中预留RAM。在驱动程序中用MmMapIoSpace来申请该RAM空间,结果编译不通过。又用virtualAlloc/copy来申请该段空间,可以申请一段空间,但是与INTR中的数值不相同,具体做法如下:

config.bib中的定义是   PRTBUF  88100000  00000080  RESERVE

在intr.c(ISR函数所在文件)中的定义是   char const*prt = (char *) ( 88100000 );

在驱动中的写法是照着GPIOdriver中的方式用virtualAlloc/copy来写的,大概的意思是
prt1 = (char *)VirtualAlloc(0,
                                        0x80,//申请长度
MEM_RESERVE,PAGE_ACCESS);
VirtualCopy((PVOID)part1,
(PVOID)0x88100000,               //申请的物理内存地址,在bib文件中定义
0x80,                                       //申请长度
PAGE_READWRITE|PAGE_NOCACHE);

运行过程中 prt[0]和prt1[0]不相同。求大侠帮忙分析。或者提供我一个可以在intr.c和驱动程序中传递参数的方法。

max 发表于 2009-12-17 13:39

1.  Timer4 是个必须选择吗? Timer4是系统tick时钟吧?这意味着你是从内核层传递数据给应用层。如果没有必要timer4,可以在驱动里面使用其他timer来实现。

2. Ram reserved的办法是可以用来通讯的,但我看到些问题,你的地址88100000是否是sdram的地址?这个地址是在bank4了,bank4可以访问吗? 另外一个问题 这个地址是cache地址,你应该把地址加上0x2000000变成uncache的,在你的例子,应该是0x8a100000.

3. 如果是wince5,在驱动和应用中访问内核地址, 你可以在访问之前,使用SetKMode(true),直接就可以使用地址

4. 另外一种常见的内核接口是KernelIOCtrol函数,类似驱动的DeviceIOCtrol

paul85 发表于 2009-12-17 17:34

看到版主的回复,我产生了一些疑惑
1.config.bib文件配置都在0x80000000以上,按规定应用程序和驱动都不可以访问0x80000000以上的空间。那如何为驱动程序预留一个RAM空间呢。
2.BOOL VirtualCopy(
  LPVOID lpvDest,
  LPVOID lpvSrc,// 申请的物理内存地址
  DWORD cbSize,
  DWORD fdwProtect
);函数中lpvsrc要求的是物理地址,这里的物理地址是否一定是硬件上面ram空间对应的硬件地址呢?还是经过转换以后的虚拟地址。我在其他的帖子上看到说这里应该用的是0--4G的空间上的虚拟地址。这个地方很困惑。并且为什么地址还要">>8"呢?
3.书上说虚拟地址0x80000000--0x9fffffff是cache地址,0xa0000000--0xbfffffff是uncache地址。那0x80000000+0x2000000为何又可以变成uncache的呢?

max 发表于 2009-12-17 18:02

1. 是的,按规定是不可以用, 但为了提高性能,ce5有一个kennel mode,允许驱动和应用访问全地址空间。

2.  >>8 你搜索一下别人的帖子。 你先用1的办法 调试 测试,完了再考虑这个。

3. sorry! 是我记错了。你是对的。

max 发表于 2009-12-17 18:04

何以变成uncache? ce 内核 初始化MMU时候这么 设置的。

paul85 发表于 2009-12-17 18:14

那在什么情况下可以进入kennel mode呢。我们正常情况下是出于用户模式的吗?

paul85 发表于 2009-12-17 18:18

BOOL VirtualCopy(
  LPVOID lpvDest,
  LPVOID lpvSrc,// 申请的物理内存地址
  DWORD cbSize,
  DWORD fdwProtect
);函数中lpvsrc要求的是物理地址,这里的物理地址是否一定是硬件上面ram空间对应的硬件地址呢?还是经过转换以后的虚拟地址。

max 发表于 2009-12-17 18:49

应用程序使用SetKmode(TRUE)进入 kernel mode, 使用SetKmode(FALSE)推出。

是物理地址. >>8 是因为指定了PAGE_PHYSICAL这个flag,msdn上面有说。估计和内存分页机制有关,没有必要追求了。你可以自己搜一下了,很多文章讨论这个。

max 发表于 2009-12-17 18:57

关于 kmode, 更详细点说, 和image定制时候 的 build option也有关。 ce5定制时候有一个 build option指定k mode。

另外, 你进入kmode后, 就有了和内核一样的访问4G全地址空间的特权, 省略掉了VirtualCopy的步骤。所以我建议,你先这么调试测试 ,简单明了。

paul85 发表于 2009-12-17 19:02

恩,谢谢大侠max。我先试试看,再来回话。

max 发表于 2009-12-17 19:04

hi, paul85, 不客气。

欢迎您把 测试结果 总结出来,放入精华。

paul85 发表于 2009-12-18 10:15

用 VirtualCopy 测试了一下没有成功。
我还不清楚用SetKmode(TRUE)后,该怎么访问地址呢? 直接取(char *)0x88100000可以吗?

max 发表于 2009-12-18 14:53

我们的ftp提供的demo里面有这样的演示程序源代码。 最容易验证的是写显存,直接可以观察到
0xA0100000是framebuffer的地址。uncache的。

                        SetKMode(TRUE);                       
                        memcpy((void *)0xA0100000,g_FrameScreen->m_buffer, 320*240*2);
                        SetKMode(FALSE);

paul85 发表于 2009-12-18 18:17

有setkmod的方法试验成功!感谢max!

paul85 发表于 2009-12-18 19:15

对所做的实验做个总结:
1.用prt1 = (char *)VirtualAlloc(0,0x80,//申请长度
                    MEM_RESERVE,PAGE_ACCESS);
VirtualCopy((PVOID)part1,(PVOID)0x88100000,               //申请的物理内存地址,在bib文件中定义
              0x80,                                       //申请长度
              PAGE_READWRITE|PAGE_NOCACHE);
的方式。考虑到VirtualCopy申请的物理内存地址的概念不是很清楚。我在此处选用了多种地址0x30000000,0x4f0000d0,0x88100000等地址,都出现问题。包括中断初始化后系统不再有反应,只要给prt1 [0]赋值,系统就会死机。
2.尝试setkmod的方式,如max所说的。
我在中断处理文件intr.C中定义了 char * prt= (char *)0x80020000;
在OALInterputerHandle()(即ISR中)的外部中断3中写入prt[0]++;

又在我的驱动程序.cpp文件中的外部中断3的ist函数中写入
setkmod(true);
char *prt =(char *)0x80020000;
显示 prt[0];
setkmod(false);

系统运行的时候触发外部中断3,每触发一次,显示的prt[0]的值都递增1.
由此可见setkmod(true)可以设置目前为内核模式。
但第一种方式不知道怎么使用,希望有高人能解答。

max 发表于 2009-12-19 04:07

paul85,恭喜。

不过,你的这种情况还是应该使用uncache地址才是合理的,你现在可能没体会到。
VirtualCopy别着急了,完整的弄完1,2个驱动就会用的很熟练,我相信到时候自己就有答案了。

paul85 发表于 2009-12-19 10:55

嗯,是的。我原以为系统会自己加上0x20000000的。不知道会不会加。如果是cache,ist读到的数可能会慢一个节拍。

woshichuanqi 发表于 2010-3-5 15:27

搞的真复杂

woshichuanqi 发表于 2010-3-5 15:27

晕倒

页: [1]

Powered by Discuz! Archiver 7.1  © 2001-2009 Comsenz Inc.

302 Found

302 Found


nginx/1.8.0