Chinaunix首页 | 论坛 | 博客
  • 博客访问: 242680
  • 博文数量: 36
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 730
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-30 14:04
文章分类

全部博文(36)

文章存档

2014年(36)

我的朋友

分类: 嵌入式

2014-08-12 11:43:28

ZedBoard上有一个128x32的OLED,默认情况下启动Digilent OOB Design的镜像之后显示的是“Digilent”的logo,不过既然能显示logo,那么也就是说其实在Digilent Linux中已经提供了Linux的驱动,那么这就是一个很好的学习资料。在ZedBoard自带的SD卡镜像中,oled的驱动是作为模块驱动在启动时加载的,脚本如下:
	


zynq> cat /usr/bin/load_oled                                                       
#!/bin/sh                                                                          
insmod /lib/modules/`uname -r`/pmodoled-gpio.ko;                                   
                                                                                   
if [ -c /dev/zed_oled ]; then                                                      
        cat /root/logo.bin > /dev/zed_oled;                                        
fi; 


可以看到,加载驱动也就是简单地insmod ko文件,此时会在/dev目录下自动生成zed_oled设备节点(这是由于zedboard的ramdisk移植了mdev,可以理解为嵌入式版的udev,解释到此为止,有兴趣的可以去搜搜udev),同时还提供了一个脚本来卸载该模块,此时oled上就会全屏清空,脚本如下:
	


zynq> cat /usr/bin/unload_oled                                                     
#!/bin/sh                                                                          
rmmod pmodoled-gpio /lib/modules/`uname -r`/pmodoled-gpio.ko;   


所以在zedboard的getting started文档中就有这样一个demo,不过在新版的digilent内核中(我的是3.6)oled驱动已经被编译到内核中去了,所以load/unload操作没有效果,不过既然cat /root/logo.bin > /dev/zed_oled有效,那么我们也可以试试其他bin文件是否有效,经过一番摸索,最终明白了zedboard上的oled是从右往左扫描,从上往下扫描,一共四行。由于从图片转bin文件的软件linux下实在难找,所以最终我只能使用了Img2Lcd(还好电脑里面装了wine :-) ),具体的配置如下图中Img2Lcd所示(注意图片大小是128x32):
ZedBoard开发----OLED - 小辉辉 - 小辉辉的博客
注意左下角两个打勾的选项,一个是从右往左扫描,另一个是字节内像素数据反序,最后保存成.bin格式的即可。下面我们启动ZedBoard Linux之后,将.bin二进制文件通过nfs拷贝过来,再用cat xxx.bin > /dev/zed_oled,那么就可以看到oled上面的图像发生了变化:
ZedBoard开发----OLED - 小辉辉 - 小辉辉的博客
接下来的事情,大家依葫芦画瓢就好:-) 
        这里简要介绍内核中的驱动,驱动的源码位于linux-digilent/drivers/pmods/pmodoled-gpio.c,首先注册pmodoled-gpio平台设备驱动,通过设备树中展开的平台设备进行匹配从而跳转到.probe函数,在该函数中再注册spi驱动以及添加spi设备,通过spi总线匹配之后调用spi驱动的.probe函数,最终在该函数中我们可以找到熟悉的cdev_init,cdev_add,alloc_chrdev_region,class_create以及device_create等函数,那么到这里基本上驱动就可以分析完毕了,有兴趣的可以写一个C程序进行操作,以加深对驱动程序的理解,下面我给出一个最简单的demo来结束本篇博客:


		


#include
#include
#include
#include
#include
unsigned char dis_buf[128*4]={0};
const unsigned char gImage_logo_aa[512] = { /* 0X82,0X01,0X80,0X00,0X20,0X00, */
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X80,0X80,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X80,0X80,0X80,0X80,0X80,0X80,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X80,0X80,0X80,0X80,0X80,0X80,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0XC0,0XC0,0X00,0X00,0X00,0X00,0XE0,
0XE0,0X00,0X00,0X00,0X00,0X80,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0XC0,0XC0,0XC0,0XC0,0XC0,0XC0,0XC0,0XC0,0XC0,0XC0,0XC0,0X00,0X00,0XC0,0XC0,0XC0,
0XC0,0XC0,0XC0,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0XE0,0XE0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0X00,0X00,0X00,
0X00,0X06,0X07,0X03,0X01,0X01,0X01,0X01,0X01,0X03,0X03,0X07,0X1E,0XFC,0XF8,0XE0,
0X00,0X00,0X00,0X00,0X07,0X03,0X83,0X81,0X81,0XC1,0XC1,0XC3,0XE3,0XFF,0XFE,0X7C,
0X00,0X00,0X00,0X00,0X00,0X18,0X18,0X1B,0X1B,0X19,0X18,0X18,0X18,0X18,0X18,0X19,
0X1F,0XFE,0XF8,0X98,0X18,0X18,0X1F,0X1F,0X1C,0X00,0X00,0X00,0X00,0X00,0X00,0X80,
0X8F,0X8C,0X88,0X88,0XF8,0XF8,0XC8,0X88,0X8C,0X8F,0X8F,0X00,0X00,0X3F,0X3F,0X30,
0X30,0X30,0XF0,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0XF0,0X7C,0X0C,0X00,0X00,
0X00,0X00,0XFF,0XFF,0X00,0X00,0X00,0X00,0X3C,0XFC,0XE0,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0X00,0X00,0X00,
0X00,0XC0,0XC0,0X80,0X00,0X00,0X00,0X00,0X00,0X80,0X80,0XC0,0XF0,0X7F,0X3F,0X0F,
0X00,0X00,0X00,0X7C,0XFF,0XFF,0XC7,0X83,0X03,0X03,0X01,0X01,0X01,0X80,0X80,0XC0,
0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X0F,0X1F,0X3B,0XF3,0XE3,0XC3,0XC3,0XE3,0X73,
0X3B,0X1F,0X07,0X0F,0X1E,0X38,0X70,0XE0,0XC0,0X80,0X00,0X00,0X00,0X00,0X00,0X3F,
0XBF,0XB0,0X30,0X30,0XFF,0XFF,0X30,0X30,0X30,0X3F,0X3F,0X00,0X00,0XFC,0XFC,0X04,
0X04,0X04,0X07,0X07,0X00,0X00,0X00,0X00,0X78,0X7F,0X0F,0X01,0X00,0X00,0X00,0X00,
0X00,0X00,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X01,0X0F,0X3F,0X78,0X60,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X03,0X03,0X00,0X00,0X00,
0X00,0X00,0X01,0X01,0X03,0X03,0X03,0X03,0X03,0X03,0X01,0X01,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X01,0X01,0X03,0X03,0X03,0X03,0X03,0X03,0X03,0X01,0X01,
0X00,0X00,0X00,0X00,0X04,0X0C,0X0C,0X06,0X06,0X07,0X03,0X03,0X01,0X01,0X03,0X03,
0X06,0X06,0X0E,0X0C,0X0C,0X0C,0X00,0X00,0X01,0X03,0X01,0X00,0X00,0X00,0X0E,0X0F,
0X07,0X06,0X06,0X06,0X07,0X0F,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X00,0X03,0X0F,0X0E,
0X0C,0X0C,0X0C,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X0F,0X0F,0X0C,0X0C,0X0C,0X0C,0X0C,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
};
int main()
{
  int fd = open("/dev/zed_oled",O_RDWR);
  int i=0;
  if( fd == -1){
    printf("Can't open zed_oled device!\n");
    return 0;
  }
  else{
    printf("/dev/zed_oled open success!\n");
  }
    for(i=0;i<128*4;i++){
      dis_buf[i]=0;
    }
    
    for(i=0; i<128*4 ; i++){
      dis_buf[i]=gImage_logo_aa[i];
    }
    write(fd,dis_buf,128*4);
  return 0;
}
阅读(1812) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~