5302|14

75

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

app中 设置GPIO [复制链接]

分配虚拟地址,并映射到指定物理地址
         m_IOPreg = (volatile IOPreg *)VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE,PAGE_READWRITE|PAGE_NOCACHE);
        if(m_IOPreg ==NULL)
        {
                ERR = GetLastError();
                RETAILMSG(1,(TEXT("ALLOC IOreg failed for %d!\n"),ERR));
        }
        if(!VirtualCopy((LPVOID)m_IOPreg,(LPVOID)(IOP_BASE>>8),sizeof(IOPreg),PAGE_READWRITE|PAGE_PHYSICAL))
        {
                ERR = GetLastError();
                RETAILMSG(1,(TEXT("IOPreg COPY TO PHICICAL failed for the error %d\n"),ERR));
        }
        m_PWMreg = (volatile PWMreg *)VirtualAlloc(0,sizeof(PWMreg),MEM_RESERVE,PAGE_READWRITE|PAGE_NOCACHE);
        if(m_PWMreg ==NULL)
        {
                ERR = GetLastError();
                RETAILMSG(1,(TEXT("ALLOC PWMreg FAILED for the Error %d\n"),ERR));
        }
        if(!VirtualCopy((LPVOID)m_PWMreg,(LPVOID)(PWM_BASE>>8),sizeof(PWMreg),PAGE_READWRITE|PAGE_PHYSICAL))
        {
                ERR = GetLastError();
                RETAILMSG(1,(TEXT("PWMreg COPY TO PHICICAL failed for the error %d\n"),ERR));
        }
问题是:VirtualAlloc分配虚拟地址,指定成指定成MEM_RESERVE没有问题,但指定成MEM_COMMIT就出错,GetLastError = 87
还有,即便是指定成MEM_RESERVE,对寄存器设置也没有效果,这是为何?

最新回复

问题在于关联的寄存器不是datasheet的初始值,而是在BSP中设定的,系统启动时做的若干×××_init()里设置的值,仔细比对一下,发现关联的寄存器是我想要的,于是问题就是为什么PWM波没有产生,问题出在 rTCON |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0 rTCON &= ~2; //clear manual update bit 最后一个设置是为下一次写pwm寄存器做的手动复位,与上面的设置没有关系,要插一个Sleep()在中间,就能发出PWM波了,否则,只有瞬间的波形输出,读TCNTO0寄存器Timer 0 count observation register打印全是0,如果Sleep()一下,再rTCON&=~2,就正常,Timer 0 count observation register打印的是即时数。  详情 回复 发表于 2009-8-11 22:27
点赞 关注

回复
举报

76

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
对寄存器的设置有没有效果,如何去验证,我要输出PWM波,从示波器上看不到波形,
寄存器的设置是按照2440test给出的,
rGPBCON &= ~3;                        //set GPB0 as tout0, pwm output
        rGPBCON |= 2;
               
        rTCFG0 &= ~0xff;
        rTCFG0 |= 15;                        //prescaler = 15+1
        rTCFG1 &= ~0xf;
        rTCFG1 |= 2;                        //mux = 1/8
        rTCNTB0 = (PCLK>>7)/freq;                       
        rTCMPB0 = rTCNTB0>>1;        // 50%
        rTCON &= ~0x1f;
        rTCON |= 0xb;                        //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
        rTCON &= ~2;                        //clear manual update bit
其中PCLK赋值0x8000000
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
如果是VirtualAlloc时,指定type为MEM_RESERVE,是不是没有办法改动寄存器
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

4
 
TCNTO0寄存器Timer 0 count observation register,打印出的值始终是0(默认值),看来设置根本没有效果
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

5
 
去看看SFR的内容
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

6
 
给你两个建议,说是说尝试都行

就用MEM_RESERVE,因为后面的VirtualCopy已经提交了,所以这里只需设成MEM_RESERVE。


1.去掉if(!VirtualCopy((LPVOID)m_IOPreg,(LPVOID)(IOP_BASE>>8),sizeof(IOPreg),PAGE_READWRITE|PAGE_PHYSICAL))  中的IOP_BASE>>8,改成IOP_BASE。不要右移八位。

2.你的这个配置寄存器的用法rGPBCON&= ~3,不一定正确。也许这些寄存器是在结构体里配置,然后分配地址。具体的说是不是可以这样用 s2440->rGPBCON&= ~3.

上面这两个方法你可以尝试一下,我觉得应该可以解决你的问题   good luck
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

7
 
在app中最好使用了MmMapIoSpace以及MmUnmapIoSpace函数
方便可靠,简单啊
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

8
 
引用 5 楼 hitszj604 的回复:
给你两个建议,说是说尝试都行

就用MEM_RESERVE,因为后面的VirtualCopy已经提交了,所以这里只需设成MEM_RESERVE。


1.去掉if(!VirtualCopy((LPVOID)m_IOPreg,(LPVOID)(IOP_BASE>>8),sizeof(IOPreg),PAGE_READWRITE|PAGE_PHYSICAL))? 中的IOP_BASE>>8,改成IOP_BASE。不要右移八位。

2.你的这个配置寄存器的用法rGPBCON&= ~3,不一定正确。也许这些寄存器是在结构体里配置,然后分配地址。具体的说是不是可以这样用 s2440->rGPBCON&= ~3.

上面这两个方法你可以尝试一下,我觉得应该可以解决你的问题? good luck

感谢您的回复,忘了说了,我用的wince 5.0,如果指定PAGE_PHSICAL,必须要对物理地址右移8位.

关于您给的提示
按照MEM_RESERVE设置,进行断点调试,从内存中读出的数与datasheet给出的默认值不一样,想问一下,是不是VirtualCopy执行之后,关联物理地址了,内存中的值就应该是寄存器的值.
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

9
 
引用 6 楼 gooogleman 的回复:
在app中最好使用了MmMapIoSpace以及MmUnmapIoSpace函数
方便可靠,简单啊

"方便可靠,简单啊",这话说出来也挺简单
"MmMapIoSpace这个函数....源码中是调用了virtualalloc来预留虚拟内存,然后virtualcopy来做映射的。这两个函数都不需要Kernel权限,所以没有Full Kernel也可以用。
PS:在非full kern模式下,映射物理内存可能会失败,但是可以调用。"
我在full kern模式下做的,可能失败.上面那句话我可能没理解明白,是吧?
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

10
 
我单步调试是,在VirtualAlloc之后内存'预留'的空间都是00,执行完VirtualCopy,'预留'的空间变了数,我猜是关联到了物理地址,所以值改变了,但是值和datasheet上给出的寄存器默认值不一致,但我又找不到内存中的值和datasheet中的哪些寄存器的值一致,看样关联的不是物理内存.大家说呢
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

11
 
引用 6 楼 gooogleman 的回复:
在app中最好使用了MmMapIoSpace以及MmUnmapIoSpace函数
方便可靠,简单啊


这两个我经常使用啊,我们很多人写应用调试软件也是这么做的。
即使在wince6.0下,我们写驱动和应用配合,也会在驱动中放MmMapIoSpace以及MmUnmapIoSpace
可行的,
sunrain_hjb的那个有用工具wince5.0和wince6.0 都能用,就采用了MmMapIoSpace以及MmUnmapIoSpace放在一个驱动中。
wince5.0 直接放到应用上,我试过,效果很理想。
把VirtualCopy等包装起来不更好吗?
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

12
 
PS:在非full kern模式下,映射物理内存可能会失败,但是可以调用。"
我在full kern模式下做的,可能失败.上面那句话我可能没理解明白,是吧?
——不明白,因为我这样用没有失败过,
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

13
 
1.去掉if(!VirtualCopy((LPVOID)m_IOPreg,(LPVOID)(IOP_BASE>>8),sizeof(IOPreg),PAGE_READWRITE|PAGE_PHYSICAL))  中的IOP_BASE>>8,改成IOP_BASE。不要右移八位。
——这个事道理,你看PB帮助,什么时候需要IOP_BASE>>8是有条件的。
在4.2BSP通常使用不动的方式。
楼主的应该是4.2BSP架构的
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

14
 
不知道你的问题解决没有,我也是初学者,好多都不懂,给你的是个建议你试试吧。

你说寄存器的值是不是和内存的值一样,按照我的理解,应该是一样的。但是为什么你读出的数不一样,可能就是你访问的方法不对,导致你读的数根本就不是寄存器的默认值。

希望对你有帮助!
 
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

15
 
问题在于关联的寄存器不是datasheet的初始值,而是在BSP中设定的,系统启动时做的若干×××_init()里设置的值,仔细比对一下,发现关联的寄存器是我想要的,于是问题就是为什么PWM波没有产生,问题出在
rTCON |= 0xb;
//disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
rTCON &= ~2; //clear manual update bit
最后一个设置是为下一次写pwm寄存器做的手动复位,与上面的设置没有关系,要插一个Sleep()在中间,就能发出PWM波了,否则,只有瞬间的波形输出,读TCNTO0寄存器Timer 0 count observation register打印全是0,如果Sleep()一下,再rTCON&=~2,就正常,Timer 0 count observation register打印的是即时数。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表