找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5125|回复: 2
打印 上一主题 下一主题
收起左侧

MCU驱动GEC6818程序开发记录

[复制链接]
跳转到指定楼层
楼主
ID:442604 发表于 2019-5-24 19:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在GEC6818开发平台上可以显示JPG格式的图片

一. 任务:显示RGB颜色LCD液晶屏幕中   --> 例如: 填充紫色到LCD上。
1. 分析技术点
1)了解LCD液晶屏幕组成架构?
2)在嵌入式平台如何处理LCD屏幕?
3)如何在工程访问LCD液晶屏?
4)如何写入数据到LCD屏幕中?数据是什么?该如何表示颜色?

二. 研究LCD液晶屏幕参数
1. 什么是分辨率?GEC6818平台LCD屏幕分辨率是多少?
分辨率指的是设备总像素点数是多少,例如:电视机1080*720 -> 一共有1080*720这么多个像素点
GEC6818平台分辨率->800*480

2. 什么是像素点?
像素,就是图像元素,指的是由RGB颜色组成一个点。

3. 究竟每个像素点如何组成?
像素点占多少个字节数?  --> 通过在GEC6818平台输入命令知道
[root@GEC6818 /]#cat /sys/class/graphics/fb0/bits_per_pixel
32

---> 1个像素点  -->  32位
已知:1个字节 = 8位
---> 1个像素点  --> 4个字节

结论: 每一个像素点  --> 透明度,红色,绿色,蓝色

三. 在嵌入式平台如何处理LCD屏幕?
原理:在linux下,一切都是文件。  --->在linux下,LCD液晶屏是被看作是一个文件。
LCD液晶屏幕对应的文件名是什么?
--->规律:嵌入式平台硬件设备文件名存放dev目录  dev->device

1. 切换到/dev目录下
[root@GEC6818 /]#cd /dev/
[root@GEC6818 /dev]#

2. 查看当前目录下所有的文件名是什么?
[root@GEC6818 /dev]#ls
fb0  --> 就是LCD液晶屏幕的文件名

四. 如何在工程访问/关闭LCD液晶屏?  --> 新的函数:open
1. 在Ubuntu中,输入命令查看open函数用法
gec@ubuntu:~$ man 2 open   --> 结束查询->按‘q’

头文件是什么?
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

函数原型是什么?
int open(const char *pathname, int flags);

参数填什么?
pathname:需要打开的文件的路径名  -> 文件在哪里?
flags:操作文件的权限
O_RDONLY  --> read only   -> 只读
O_WRONLY  --> write only  -> 只写
O_RDWR    --> read write  -> 可读可写

返回值是什么?
成功:new file descriptor  -> 新的文件描述符  --> 其实是大于等于0  >=0
失败:-1

2. 如何关闭?
在Ubuntu中,输入命令查看close函数使用方法:
头文件是什么?
#include <unistd.h>

函数原型是什么?
int close(int fd);

参数填什么?
fd: -> file descriptor  -> 文件描述符

返回值是什么?
成功:0
失败:-1

  练习: 写一个程序   --> LCD设备名字: /dev/fb0
     1. 首先访问LCD屏幕
            如果访问成功,则在终端打印open lcd ok!
        如果访问失败,则在终端打印open lcd error!
         2. 然后关闭LCD屏幕
        如果关闭成功,则在终端打印close lcd ok!
        如果关闭失败,则在终端打印close lcd error!

参考代码:
------------------------------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()  //->函数头
{      
    //->函数体,写一些可执行的内容
    //->使用了printf才需要包含头文件
    printf("this is first program!\n");

    int lcd_fd;//关于LCD液晶屏幕的文件描述符
    lcd_fd = open("/dev/fb0",O_RDWR);
    if(lcd_fd >= 0)
    {
        printf("open lcd ok!\n");
    }
    else{
        printf("open lcd error!\n");
    }
   
    int ret;
    ret = close(lcd_fd);
    if(ret == 0)
    {
        printf("close lcd ok!\n");
    }
    else{
        printf("close lcd error!\n");
    }
   
    return 0; //->返回值  成功:0  失败:非0
}
---------------------------------------

五. 如何写入数据到LCD屏幕中?数据是什么?该如何表示颜色?
1. 如何写入? --> 新函数:write()
在Ubuntu中输入查询命令:
gec@ubuntu:/mnt/hgfs/zdnf/02$ man 2 write

头文件是什么?
#include <unistd.h>

函数原型是什么?
ssize_t write(int fd, const void *buf, size_t count);

参数填什么?
fd: -> file descriptor  -> 文件描述符
buf:-> buffer  --> 写入的数据的缓冲区  --> RGB颜色
count: --> 写入的总字节数

返回值是什么?
成功:已经写入的字节数
失败:-1

2. 数据是什么?
既然任务是填充RGB颜色到LCD屏幕,数据就应该RGB颜色。

      write()
    颜色 --------> LCD液晶

3. 该如何表示颜色?
结论: 每一个像素点  --> 透明度,红色,绿色,蓝色

例子:红色如何表示?
一个像素点=32位
00000000111111110000000000000000  --> 红色
0x00FF0000   --> 红色
0x00FF00FF   --> 紫色
0x00FFFF00   --> 黄色

---------------------填充红色示例代码-------------------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()  //->函数头
{      
    //->函数体,写一些可执行的内容
    //->使用了printf才需要包含头文件
    printf("this is first program!\n");

    int lcd_fd;//关于LCD液晶屏幕的文件描述符
    lcd_fd = open("/dev/fb0",O_RDWR);
    if(lcd_fd >= 0)
    {
        printf("open lcd ok!\n");
    }
    else{
        printf("open lcd error!\n");
    }
   
    int color = 0x00FF0000;

    int i;
    for(i=0;i<800*480;i++)
    {
        write(lcd_fd,&color,4);
    }
   
    int ret;
    ret = close(lcd_fd);
    if(ret == 0)
    {
        printf("close lcd ok!\n");
    }
    else{
        printf("close lcd error!\n");
    }
   
    return 0; //->返回值  成功:0  失败:非0
}
-----------------------------------------------

  练习:填充紫色到LCD屏幕。


一. 项目: 基于网络远程控制多媒体系统
          socket通信
   客户端   <------------>   服务器
   UI界面            播放视频
   触摸屏           控制视频状态

二. UI界面如何设计?JPG格式图形特点?JPG图片如何显示LCD液晶屏幕?
1. UI界面如何设计?
已知GEC6818平台LCD液晶屏幕分辨率->800*480  -->横:800个像素点  竖:480个像素点
想在LCD液晶上全屏显示JPG格式图片-> UI界面->分辨率:800*480

2. 根据项目要求设计UI界面
1)按钮内容
控制视频状态:快进、快退、音量+、音量-、暂停/继续、静音/恢复、退出。

2)按钮大小 -> 由于在客户端中触摸屏控制按钮,所以必须清楚知道按钮的范围!
画图软件:
重新调整大小->像素->把"保持纵横比"选项去掉
水平:800
垂直:480

3. 为什么选择使用jpg格式图片?
由于jpg格式文件经过压缩的,所以文件大小相对其它格式图片较小,方便开发时进行数据传输。
而且显示jpg图片编译移植jpg库,然后jpg源码调用库里面的接口就可以。

三. JPG图片如何显示LCD液晶屏幕?
任务: UI.jpg  --> 显示在GEC6818平台
首先拿到两个文件:
jpeg_show.c  --> 显示jpg图片的源码
jpegsrc.v9a.tar.gz  --> jpg库

1. 在Ubuntu中,切换到源码所在的路径
gec@ubuntu:~$ cd /mnt/hgfs/zdnf/02/

2. 尝试在Ubuntu Linux系统编译源码:
gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show
编译出错:
error: jpeglib.h: No such file or directory  -> 找不到jpeglib.h这个头文件。

jpeglib.h->其实是存在于jpg库中,所以编译之前,首先要编译移植jpg库。

四. 编译移植jpg库?
1. 什么是编译移植?
其实就是安装jpg库的文件到Ubuntu linux系统中。

2. 如何编译移植?
jpegsrc.v9a.tar.gz  --> jpg库: 开源免费

1)先把jpg库放置在共享目录下
2)在linux中,切换到jpg库所在的路径下
gec@ubuntu:~$ cd /mnt/hgfs/zdnf/02/

3)在linux中解压jpg库,一般地解压到家目录下  --> 因为在家目录下,拥有一切权限。
gec@ubuntu:/mnt/hgfs/zdnf/02$ tar zxvf jpegsrc.v9a.tar.gz -C ~

  tar: 解压/压缩的linux命令
  z: 处理以.gz结尾的压缩包
  x: 解压   c:压缩
  v: 以可见的方式进行解压,这个参数不是必须。
  f: 文件
  -C: 指定解压之后的路径
  ~: 家目录

如果有v选项,则会打印解压的过程
jpeg-9a/
jpeg-9a/wrppm.c
jpeg-9a/wrrle.c
jpeg-9a/maketdsp.vc6
jpeg-9a/jdinput.c

4)回到家目录下,看看有没有一个新的目录叫jpeg-9a/
gec@ubuntu:/mnt/hgfs/zdnf/02$ cd ~
gec@ubuntu:~$ ls   --> 看到jpeg-9a/目录

5)在家目录下创建一个新的目录,作为安装之后的目录,并给予权限
创建目录linux命令:mkdir  --> make diretcory

gec@ubuntu:~$ mkdir jpgbuf   --> 创建目录
gec@ubuntu:~$ chmod 777 jpgbuf  --> 修改目录权限

为什么要修改目录权限?
因为在windows中,创建了一个新的文件夹,我们可以直接把文件丢进去。
但是在linux下,创建一个新的目录,是默认没有写的权限,我们不能丢文件进去,所以就没办法安装到目录中

--> 结论: 创建完目录后,通过chmod命令给予权限。

6)切换到解压之后的目录下
gec@ubuntu:~$ cd ~/jpeg-9a/
gec@ubuntu:~/jpeg-9a$ ls   --> 看到一个文件,叫configure  -> 配置文件。

7)配置
gec@ubuntu:~/jpeg-9a$ ./configure --host=arm-linux --prefix=/home/gec/jpgbuf

其中:
./configure  --> 执行当前目录下的configure文件
--host=arm-linux  --> 指定是交叉编译
--prefix=/home/gec/jpgbuf   -->指定安装路径

8)编译
gec@ubuntu:~/jpeg-9a$ make
make  all-am
make[1]: Entering directory `/home/gec/jpeg-9a'
make[1]: Leaving directory `/home/gec/jpeg-9a'  --> 则需要清除链接文件

gec@ubuntu:~/jpeg-9a$ make clean  -> 清除链接文件
rm -f cjpeg djpeg jpegtran rdjpgcom wrjpgcom
test -z "testout.ppm testout.bmp testout.jpg testoutp.ppm testoutp.jpg testoutt.jpg" || rm -f testout.ppm testout.bmp testout.jpg testoutp.ppm testoutp.jpg testoutt.jpg
test -z "libjpeg.la" || rm -f libjpeg.la
rm -f ./so_locations
rm -rf .libs _libs
rm -f *.o
rm -f *.lo

gec@ubuntu:~/jpeg-9a$ make   --> 重新编译
  CC       jaricom.lo
  CC       jcapimin.lo
  CC       jcapistd.lo   --> 正在编译

9)安装
gec@ubuntu:~/jpeg-9a$ make install

安装结果:切换到jpgbuf路径看看
gec@ubuntu:~/jpeg-9a$ cd ~/jpgbuf
gec@ubuntu:~/jpgbuf$ ls
bin  include  lib  share   --> 如果看到有4个目录,则编译移植jpg库成功!

五. 分析jpg库编译移植之后文件有哪些?
bin:  
cjpeg  djpeg  jpegtran  rdjpgcom  wrjpgcom  --> 二进制文件

include:
jconfig.h  jerror.h  jmorecfg.h  jpeglib.h   --> jpg库头文件

lib:
libjpeg.a  libjpeg.la  libjpeg.so  libjpeg.so.9  libjpeg.so.9.1.0  --> 库文件

share:
man  --> 帮助文档

六. 已经编译移植完,接下来让源码调用库里面的内容。
1. 切换到源码的位置
gec@ubuntu:~/jpgbuf/share$ cd /mnt/hgfs/zdnf/02/

2. 重新编译
gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show
编译出错:error: jpeglib.h: No such file or directory

为什么编译移植之后,还是找不到?
因为用户编译移植完jpg库之后,编译器是不知道已经编译完成了,所以我们需要告诉编译器,头文件在哪里。

如何告诉编译器,头文件在哪里? --> 使用编译器选项: -I 头文件的路径

gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show -I /home/gec/jpgbuf/include
编译出错:
/tmp/cc2O0oBN.o: In function `main':
jpeg_show.c:(.text+0x440): undefined reference to `jpeg_std_error'
jpeg_show.c:(.text+0x45c): undefined reference to `jpeg_CreateDecompress'
jpeg_show.c:(.text+0x474): undefined reference to `jpeg_mem_src'

原因:找不到对应的函数的定义,函数的定义其实在库文件中,找不到函数的定义,其实就是找不到库文件,库文件就是lib中。

如何告诉编译器,库文件在哪里? --> 使用编译器选项: -L 库文件的路径 -l库的名字

gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show -I /home/gec/jpgbuf/include -L /home/gec/jpgbuf/lib
编译出错:
/tmp/cc2O0oBN.o: In function `main':
jpeg_show.c:(.text+0x440): undefined reference to `jpeg_std_error'
jpeg_show.c:(.text+0x45c): undefined reference to `jpeg_CreateDecompress'
jpeg_show.c:(.text+0x474): undefined reference to `jpeg_mem_src'

-l库的名字  --> -l后面是没有空格的
libjpeg.so.9.1.0  --> 库的名字是lib与.so中间的名字
--> -ljpeg

gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show -I /home/gec/jpgbuf/include -L /home/gec/jpgbuf/lib -ljpeg
编译通过,生成一个新的文件:jpeg_show
  
七. 烧写程序到开发板中
1. 烧写可执行程序,输入烧写命令
[root@GEC6818 /]#cd /
[root@GEC6818 /]#rx jpeg_show
C

2. 传输->发送Xmodom->选择jpeg_show文件->发送
3. 修改权限
[root@GEC6818 /]#chmod 777 jpeg_show

4. 执行
[root@GEC6818 /]#./jpeg_show
./jpeg_show: error while loading shared libraries: libjpeg.so.9: cannot open shared object file: No such file or directory

解决方案:将缺少的库libjpeg.so.9下载到开发板的/lib中

5. 下载libjpeg.so.9到开发板中
[root@GEC6818 /]#cd /lib
[root@GEC6818 /lib]#rx libjpeg.so.9
C

传输->发送Xmodom->选择libjpeg.so.9文件->发送

6. 回到根目录,再下载图片到开发板中
[root@GEC6818 /]#cd /
[root@GEC6818 /]#rx UI.jpg
C

传输->发送Xmodom->选择UI.jpg文件->发送

7. 最后一步
[root@GEC6818 /]#./jpeg_show UI.jpg

全部资料51hei下载地址:
02.zip (1.38 MB, 下载次数: 38)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:245437 发表于 2019-6-5 14:42 | 只看该作者
很全,真的很谢谢,但是请问我用了新的乌班图,出现没有arm-linux-gcc指令和make没有相应指令怎么搞呢,刚学习linux感觉很复杂,不是缺这个文件就是那个文件,而且网上搜的教程也没有你说的这么详细,因为你会解释语句的作用,那些教程没有往往因为不明白意思而出现出现一些教程上没有出现的问题
回复

使用道具 举报

板凳
ID:564887 发表于 2019-6-21 15:08 | 只看该作者
寻鱼寻渔 发表于 2019-6-5 14:42
很全,真的很谢谢,但是请问我用了新的乌班图,出现没有arm-linux-gcc指令和make没有相应指令怎么搞呢,刚 ...

下载啊
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表