查看: 15194|回复: 7

beaglebone 点灯笔记(转)

  [复制链接]
  • TA的每日心情
    开心
    2015-1-1 01:21
  • 签到天数: 354 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2013-3-9 16:10:57 | 显示全部楼层 |阅读模式
    分享到:

    历尽千幸万苦,终于把beaglebone上的LED点亮了.现在记录一下,以免以后忘记.
    首先想到的是写寄存器的方式进行点灯.虽然TI的文档相当地烂,不过我还是找到了LED所在的GPIO相关寄存器.

    123456789#define TIA8_GPIO1_PA           (0x4804C000)#define TIA8_GPIO_CLEARDATAOUT           (0x190)#define TIA8_GPIO_SETDATAOUT           (0x194)#define TIA8_GPIO_CTRL                   (0x130)#define TIA8_GPIO_OE                   (0x134)#define LED1                        ( 1 << 21)#define LED2                        ( 1 << 22)#define LED3                        ( 1 << 23)#define LED4                        ( 1 << 24)

    然后在驱动中直接使用__raw_writel()进行写内存.结果不行.后来根据出错信息发现__raw_writel只是写的虚拟地址.得建立一个物理地址到虚拟地址的映射才行.接下来又学会了使用ioremap.

    1234567891011volatile unsigned long *p = ioremap(TIA8_GPIO1_PA,0x2048); __raw_writel((2<<1),(p+TIA8_GPIO_CTRL));tmp = __raw_readl(p+TIA8_GPIO_OE);tmp&=(~(LED1|LED2|LED3|LED4));__raw_writel(tmp,(p+TIA8_GPIO_OE)); __raw_writel(LED1,(base+TIA8_GPIO_SETDATAOUT));__raw_writel(LED2,(TIA8_GPIO_SETDATAOUT+base));__raw_writel(LED3,(TIA8_GPIO_CLEARDATAOUT+base));__raw_writel(LED4,(TIA8_GPIO_CLEARDATAOUT+base));

    经过这样修改后,发现依然不成功.也使用过这样的方式.依旧不行.

    123456*(p+TIA8_GPIO_SETDATAOUT)=LED1;*(p+TIA8_GPIO_SETDATAOUT)=LED2;*(p+TIA8_GPIO_CLEARDATAOUT)=LED3;*(p+TIA8_GPIO_CLEARDATAOUT)=LED4;/* 经过被多人打脸,unsigned long *p指针+1 实际地址会是+unsigned long所占的字节数.所以上面的代码肯定不行*//* 典型的不会用指针屌丝 */

    问题出在什么地方呢??在写虚拟内存时,被cache了?好吧.我把ioremap换成了ioremap_nocache,但依旧不行.
    后来我使用kernel的GPIO接口测试,发现能正常点亮LED,也通过方法排除了GPIO没被设置的可能性,最后去根踪TI BSP里的代码,发现他们都是通过void __iomem *base来进行操作.于是乎google:void __iomem *base,发现描述它的页面并不多.很多都是鸟文的,看起来特累.后来在睡前决定我也试试.于是下面的代码就产生了:

    12345void __iomem *base = ioremap_nocache(TIA8_GPIO1_PA,0x2048);__raw_writel(LED1,(base+TIA8_GPIO_SETDATAOUT));__raw_writel(LED2,(TIA8_GPIO_SETDATAOUT+base));__raw_writel(LED3,(TIA8_GPIO_CLEARDATAOUT+base));__raw_writel(LED4,(TIA8_GPIO_CLEARDATAOUT+base));

    编译模块,加载运行....成功鸟!!!.
    原来我们从ioremap返回的值最好是赋给void __iomem类型.在LDD3中,只是不建义直接使用指针进行访问ioremap过的地址,但没说具体如何使用.
    但具体为什么使用__iomem就可以,而直接的指针就访问异常就不知道了.但至少以后写驱动就注意一下,对于设备寄存器的操作,最好是不直接映射后就使用指针操作.


    回复

    使用道具 举报

  • TA的每日心情
    开心
    2015-1-1 01:21
  • 签到天数: 354 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2013-3-9 16:11:50 | 显示全部楼层
    排版没排好!你懂的!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2013-12-24 21:33
  • 签到天数: 9 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2013-7-29 22:38:58 | 显示全部楼层
    好贴。求楼主分享更多控制io的资料。谢谢
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2014-7-1 10:15
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-6-18 10:41:23 | 显示全部楼层
    看看,学习一下。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2014-7-24 09:24
  • 签到天数: 38 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2014-6-19 15:30:40 | 显示全部楼层
    支持笔记!mark!!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-12-27 09:25
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2017-12-27 10:47:29 | 显示全部楼层
    谢谢学习了。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2018-3-28 09:41
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2018-3-22 11:39:38 | 显示全部楼层
    很好 不过不够详细
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2021-2-27 22:16
  • 签到天数: 1568 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2019-3-31 15:29:49 | 显示全部楼层
    这是好东西 522.jpg
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 20:34 , Processed in 0.197474 second(s), 29 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.