嵌入式应用开发第四阶段

一、需求分析

伴随着嵌入式技术、图像处理技术和无线网络传输技术的发展,传统模拟视频监控系统和基于PC的远程视频监控系统由于自身的不足,已经无法满足现代社会应用中不断涌现出来的新需求,于是基于嵌入式技术的无线网络数字视频监控系统就应因而生了。例如远程监控、远程教学、远程医疗诊断、远程购物、远程探视、电视电话会议等应用都迫切需要高质量的网络视频传输的支持。考虑到了所用的硬件设备大部分都已经具备和我们所学到的知识及本身的能力有限,选择基于rk3399的视频监控系统作为我们本次的课程设计题目是比较实际而且比较容易掌握嵌入式开发的基本方法

设计实现功能要求

1)   利用USB摄像头进行采集图像数据的采集;

2)   利用rk3399对所采集到图像数据进行解码

3)   将解码后的图像显示在LCD屏上。

设计用到的设备

1)   PC机

2)   RK3399开发板

3)   USB摄像头

4)   type-c usb线

5)   CH340串口线

一、产品的系统构成

系统的工作原理

系统可以分为4 个模块:图像采集模块、图像存储模块、图像处理模块、图像显示模块。系统在RK3399 的控制下从USB 摄像头采集图像数据,然后经过DMA 方式将图像数据传输到内存缓冲区中,由软件将图像数据读出并对图像数据进行压缩和打包处理后存入Flash 中, 最后图像在LCD屏上。本系统的设计难点是如何保证内存中图像数据的读取与USB 摄像头的同步以及图像数据的实时处理。系统采用RK339作为嵌入式处理器,完全可以完成图像数据的实时处理需求,比一般采用添加图像硬件处理模块减少了系统的成本.

二、软硬件协同设计与程序建模

在开始应用编程之前,需要先准备好驱动,在LCD上显示摄像头图像,至少需要三个驱动:LCD驱动、背光驱动、UVC驱动。

以前都是使用的insmod xx.ko进行动态加载驱动,每次开发板上电后,都需要手动/脚本里加载驱动,有点麻烦。

反观内核自带的驱动,使用make menuconfig进入图形配置界面里,找到对应的驱动,可以设置为Y(编译到内核)、M(编译成模块)、N(不编译)。当设置为Y后,进入系统后,就自带了该驱动,不再需要手动加载。

四,嵌入式产品的设计与开发

1.1 LCD 显示原理

液晶显示的原理基于液晶的透光率随其所施电压大小而变化的特性。当光通过上偏振片后,变成线性偏振光,偏振方向与偏振片振动方向一致,与上下玻璃基板上面液晶分子排列顺序一致。当光通过液晶层时,由于受液晶折射,线性偏振光被分解为两束光。又由于这两束光传播速度不同(相位相同),因而当两束光合成后,必然使振光的振动方向发生变化。通过液晶层的光,则被逐渐扭曲。当光达到下偏振片时,其光轴振动方向被扭曲了90度,且与下偏振片的振动方向保持一致。这样,光线通过下偏振片形成亮场。加上电压以后,液晶在电场作用下取向,扭曲消失。这时,通过上偏振片的线性偏振光,在液晶层不再旋转,无法通过下偏振片而形成暗场。可见液晶本身不发光,在外光源的调制下,才能显示,在整个显示过程中,液晶起到一个电压控制的光阀作用。TFT-LCD的工作原理则可简述为:当栅极正向电压大于施加电压时,漏源电极导通,当栅极正向电压等于0或负电压时,漏源电极断开。漏电极与ITO象素电极连结,源电极与源线(列电极)连结,栅极与栅线(行电极)连结。这就是TFT-LCD的简单工作原理

1.2 lcd示例

1)打开lcd设备:

linux系统所有lcd设备名称是统一是 /dev/fbX ,X是0~31 .

RK3399 开发平台lcd设备情况:

[[email protected] ~]# ls /dev/fb*

/dev/fb0

2)操作lcd设备

a.获得lcd屏的工作参数:可变参数和固定参数

b.使用 mmap 函数把lcd的显存映射到进程空间中 -- 得到一个显存首地址

c.通过映射得到的地址往显存写颜色数据。

第一步:

第二步:显存首地址偏移+目标点偏移量 ---> 目标点在内存中的绝对地址

第三步:根据 BPP 合成颜色写入到目标点内存中

3)关闭 lcd设备,取消映射(munmap)

2 Linux系统下摄像图像采集

172.16.14.208

1. Linux系统下标准的摄像头框架V4L2

2. V4L2框架不局限应用在摄像头,还有其他类设备

3. 摄像头设备文件:

/dev/videoX   X是一个整数从0开始。

4. 摄像头编程流程

Linux下一切都是文件!

1)打开摄像头设备对应文件

int  video_device_open(const char*dev)

{

fd_vd = open(dev, O_RDWR);  //阻塞方式打开

if (-1 == fd_vd) {

fprintf(stderr, "Cannot open ‘%s‘: %d, %s\n", dev_name, errno, strerror(errno));

return -1;

}

return fd_vd;

}

2)各种操作

a. 查询设备功能:

因为打开的设备不一定就是摄像头设备,不一定支持捕获功能。

b. 根据上一步查询结果来判断是否支持捕获功能

c. 查询摄像头支持的数据格式:

因为不同型号的摄像头支持不一样格式,格式数量也不一样。

d. 从支持格式选择一种可以处理的数据格式 设置到硬件中。

e. 申请缓冲

f. 查询缓冲信息:得到内存偏移量和长度

g. 使用 mmap 进行映射到进程空间中

h. 添加到采集队列中

i. 启动图像采集

j. 取出一帧数据进行处理:实际把最早一帧数据从采集队列取下来,需要自己去复制数据。

k. 把缓冲区重新添加到采集队列

循环:j, k 两步

l. 停止采集

m. 取消映射,关闭设备

3)关闭

2. 示例代码

04-lcd-v4l2

3. 测试

1)编译

编译前根据自己的文件系统路径修改 Makefile

DEST := /home/edu118/work/nanopc-t4/rootfs/home

查看当前路径

[email protected]:code$ pwd

/mnt/hgfs/OceanUniversity/2.示例代码/04-lcd-v4l2/code

清上次编译信息

[email protected]:code$ make clean

重新编译

[email protected]:code$ make

‘./app-lcd-v4l2‘ -> ‘/home/edu118/work/nanopc-t4/rootfs/home/app-lcd-v4l2‘

自动复制 生成的  app-lcd-v4l2 到根文件系统的 /home/ 目录中

2)开发板测试

a. 插上摄像头

b. 启动测试

3.LCD显示框架

①:首先从摄像头获取数据放入video_buf,数据的格式(YUV、MJPEG、RGB)和分辨率可能有多种;

②:RK3399的LCD仅支持RGB格式,因此需要数据格式转换;

③:RK3399的LCD分辨率是800X480,因此可能需要大小缩放;

④:根据LCD显示流程,必须要将显示数据写入显存(FrameBuffer);

⑤:最后LCD控制器会将显存数据自动搬运到LCD/VGA等显示设备上;

在应用编程中,要习惯面向对象编程(Object Oriented Programming),也就是把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数,在C语言中常常用结构体(struct)来实现。

关于Linux内核C语言中的面向对象的实现,可以参考这篇博客,介绍了如何C语言实现面向对象,也通过这个能稍微理解Linux驱动中的操作函数的原理。

这里,模仿内核的编程框架,为每个模块实现一个管理链表,模块对应加入链表,再调用对应的操作函数,框架如下:

简单说明下这个框架,主要有四个模块:

video用于摄像头数据采集,convert用于格式转换、process用于缩放等操作、dispaly用于显示。

以convert为例,有一个manager管理每个子模块,将每个子模块放入链表,向上提供统一的操作接口,调用对应文件的操作函数。

五.嵌入式系统移植

建立交叉编译环境

搭建交叉编译环境是嵌入式开发的第一步,也是必备的一步。搭建交叉环境的方法很多,不同的体系结构、不同的操作内容甚至是不同版本的内核,都会用到不用的交叉编译器,选择合适的交叉编译器对于嵌入式开发是非常重要的。由于我们本次用到的是linux 2.6.32.2内核,故我们选择了编译器arm-linux-gcc-4.3.2[3]。以下安装交叉编译器的步骤:

1、下载交叉编译器arm-linux-gcc-4.3.2,下载地址:http://www.handhelds.org/download/projects/toolchain/arm-linux-gcc-4.3.2.tar.bz2

2、复制arm-linux-gcc-4.3.2.tar.bz2到目录 tmp/下并解压:

# cd /tmp

# tar xvzf arm-linux-gcc-4.3.2.tar.bz2

3、把编译器路径加入系统环境变量,运行命令

#gedit /root/.bashrc

编辑/root/.bashrc 文件,在最后一行设置:

export PATH=$PATH:/usr/local/arm/4.3.2/bin

3.2.3解压安装源代码和工具

1、下载linux 2.6.32.2内核源代码

下载地址:http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.2.tar.gz

2、复制内核代码至目录/tmp/linux 并解压

# tar –xvzf linux-2.6.32.2.tar.gz

3、解压目标文件系统

这里我们使用现有的根文件系统资源root_qtopia-20100108.tgz,将它复制至目录/usr/src 并解压

# tar –xvzf root_qtopia-20100108.tgz

4、安装目标文件系统映象制作工具mkyaffs2image

要把上一步中的root_qtopia 目录烧写入目标板中使用, 就需要使用相应的mkyaffs2image 工具,它是一个命令行的程序,使用它可以把主机上的目标文件系统目录制作成一个映象文件,以烧写到开发板中[4]

#tar xvzf /tmp/linux/mkyaffs2image.tgz –C /

3.2.4配置网络文件系统NFS服务

1、设置共享目录

运行命令 #gedit /etc/exports

编辑 nfs 服务的配置文件,添加以下内容:

/opt/FriendlyARM/mini2440/root_qtopia *(rw,sync,no_root_squash)

其中:/opt/FriendlyARM/mini2440/root_qtopia 表示nfs 共享目录,它可以作为开发板的根文件系统通过nfs 挂接;* 表示所有的客户机都可以挂接此目录rw 表示挂接此目录的客户机对该目录有读写的权力;no_root_squash 表示允许挂接此目录的客户机享有该主机的root 身份[5]

2、启动NFS 服务

在命令行下运行:

#/etc/init.d/nfs start

3.3 定制Linux内核

Linux 内核是一个社区共同开发的作品,具备一个现代操作系统的所有功能,并能对绝大多数硬件提供支持。然而,我们本次设计有很多功能都没有用到的,为了尽可能减少编译出来的内核体积,在配置内核时,只需要配置需要用到的模块。常用的配置内核的方法有make config ,make menuconfig和make xconfig这里我们使用最广泛的make menuconfig[6]。执行“make menuconfig”,可进入配置内核界面:

配置万能驱动USB摄像头

在Device Drivers 菜单里面,选择 Multimedia devices,回车进入,选择如图“*”号选项,并选择Video capture adapters 进入

出现如图菜单,找到如图选项并进入

出现如图菜单,选择如图“*”号选项,再选GSPCA based webcams 进入

这里我们选择所有类型USB 摄像头的支持

1)   配置网卡驱动

要配置网卡驱动,首先要配置网络协议支持.在主菜单中,选择 Netwoking support,回车进入子菜单, 选择 Networking options 并进入下一级菜单,如图配置选项

选择完毕,一直退回到主菜单,并选择进入 Device Drivers 菜单。找到 Network device support,选择进入下一级菜单, 找到并进入 Ethernet (10 or 100Mbit) 选项[8], 选中:

<*> Generic Media Independent Interface device support

<*> DM9000 support

2)   配置串口驱动

在 Character devices 菜单中,选择进入Serial drivers - - ->,选择如图选项,来配置串口驱动

3)   配置yaff2s文件系统的支持

要使用 yaffs2 文件系统,需要先配置nand flash 驱动支持,在Device drivers 菜单中选择MTD 选项,按回车进入,找到 NAND Device Support 选项并进入,如图选择 Nand Flash 驱动支持

返回到内核配置主菜单,找到 File systems 选项进入,然后找到选项 Miscellaneous filesystems 并进入,再找到 YAFFS2 支持选项,如图选择

4)   配置NFS文件系统

在 File System 菜单中,选择Network File Systems 文件系统的支持且进入, 选择如图选项,这样配置编译出的内核就可以通过 NFS 启动系统了。

完成内核的配置并保存好,接着执行命令:

#make dep       ;生成依赖文件

#make zImage    ;生成压缩的内核影象文件

3.4 制作目标文件系统映象

3.5 移植bootloader

(1) 打开DNW 程序,接上USB 电缆,根据菜单选择功能号[v]开始下载supervivi

(2)点击“USB Port->Transmit/Restore”选项,并选择打开文件supervivi开始下载。

(3)下载完毕,BIOS 会自动烧写supervivi 到Nand Flash 分区中,并返回到主菜单。

3.6 移植Linux内核

(1)在BIOS 主菜单中选择功能号[k],开始下载linux 内核zImage

(2) 点击“USB Port->Transmit”选项,并选择打开相应的内核文件zImage开始下载.

(3) 下载完毕,BIOS 会自动烧写内核到Nand Flash 分区中,并返回到主菜单

3.7移植根文件系统

(1)在BIOS 主菜单中选择功能号[y],开始下载yaffs 根文件系统映象文件

(2) 点击“ USB Port->Transmit/Restore ” 选项, 并选择打开相应的文件系统映象文件

(3)下载完毕,BIOS 会自动烧写内核到Nand Flash 分区中,并返回到主菜单

六.设计心得

本次设计参考了众多书籍及网络上的理论知识,在理解的基础上结合思考及老师给我们做的项目演示,根据现有的硬件设备,对完整的内核代码进行了相应的裁减,配置出适合我们所设计的系统的内核。整个过程看似有点按部就班,但真正操作起来并没有那么简单,很多时候都会出现一些莫名其妙的错误,以致无法进行下一步的操作。这时就需要回归到理论方面的知识中去,经过多次尝试才能得以解决。

 

原文地址:https://www.cnblogs.com/cyyz-le/p/11150538.html

时间: 2024-10-12 02:05:15

嵌入式应用开发第四阶段的相关文章

嵌入式应用开发第三阶段

今天来设计一个项目:嵌入式智能娱乐影音系统 软件:vmwave虚拟机  ubuntu18.0系统  SecureCRT串口终端  tftpd64 硬件:基于ARM Cortex-A53芯片的6818开发板,4寸电容屏  rs232串口线  usb转串口线  电源线 网线 一.搭建项目框架 建一个文件夹project,存放多个.c文件负责各个模块功能的实现,创建一个.h文件,把所有用到的库函数放进去.创建一个project_set.c文件,存放lcd.触摸屏等各个模块都需用到的函数 本系统包含5个

嵌入式应用开发第一阶段

奋斗中的linux开发初学者!转自陈佳乐! 本文主要讲如何搭建嵌入式开发环境以及文件传输到开发板的两种方式 一.准备开发环境 软件 SecureCRT  串口工具.tftpd64   tftp文件传输工具.vmware虚拟机+Ubuntu系统 硬件 rk3399开发板.7寸lcd屏.rs232串口线.usb转串口线.网线 1.1虚拟机安装ubuntu系统 虚拟机和ubuntu系统,微信关注软件安装管家  发送ubuntu即可获取文件和安装教程 1.2 设置虚拟机的共享文件夹 ==========

从零开始学ios开发(四):IOS控件(1),Image View、Text Field、Keyboard

长话短说,谢谢大家的关注,这篇写了好长时间,下面继续学习ios.我将用2到3篇的篇幅来学习iphone上的一些常用控件,包括Image View.Text Field.Keyboard.Slider等等,这篇的内容包括ImageView和Keyboard的使用.完成后的效果图如下: 1)创建一个新的project,选择“Single View Application”,命名为“Control Fun”,然后保存.一些和前几章相似的步骤在从这篇起就开始一笔待过了,也不再做截图了,例如这里的创建一个

嵌入式Linux裸机开发(四)——重定位relocate

嵌入式Linux裸机开发(四)--重定位relocate 一.位置有关编码 汇编源文件被编译成二进制可执行程序时编码方式可能与内存地址有关,也可能与内存地址无关.与内存地址有关的为位置有关编码,与内存地址无关的为位置无关编码. 程序在设计时需要规划一个程序运行时的地址(链接地址),编译连接器在链接时必须指定这个链接地址,得到的二进制程序的程序理论规划的运行时地址和编译连接器指定的链接地址才相同,程序才能正常运行.位置无关编码程序则无需设计程序时规划运行时地址,编译链接器链接时同样无需指定链接地址

第四阶段 (七)MySQL REPLICATION(主从复制、半同步复制、复制过滤)

Linux运维 第四阶段 (七)MySQL REPLICATION(主从复制.半同步复制.复制过滤) 一.MySQL Replication相关概念: 1.复制的作用:辅助实现备份:高可用HA:异地容灾:分摊负载(scaleout):rw-spliting(mysql proxy工作在应用层). 2.master有多个CPU允许事务并行执行,但往二进制日志文件只能一条条写:slave比master要慢:master-slave默认异步方式传送. 3.半同步:仅负责最近一台slave同步成功,其它

Go语言开发(四)、Go语言面向对象

Go语言开发(四).Go语言面向对象 一.结构体和方法 1.结构体的定义 在结构体中可以为不同项定义不同的数据类型.结构体是由一系列具有相同类型或不同类型的数据构成的数据集合.结构体定义需要使用type和struct语句.struct语句定义一个新的数据类型,结构体有中有一个或多个成员.type语句设定了结构体的名称.结构体的格式如下: type struct_variable_type struct { member definition; member definition; ... mem

HyperLeger Fabric开发(四)——HyperLeger Fabric共识机制

HyperLeger Fabric开发(四)--HyperLeger Fabric共识机制 一.Fabric共识过程 1.Fabric共识过程 Fabric区块链的网络节点本质上是互相复制的状态机,节点之间需要保持相同的账本状态.为了实现分布式节点的一致性,各个节点需要通过共识过程,对账本状态的变化达成一致性的认同.Fabric区块链的共识过程包括3个阶段:背书.排序和校验. 2.背书 在背书(endorsement)阶段中,背书节点对客户端发来的交易提案进行合法性校验,然后模拟执行链码得到交易

嵌入式linux QT开发(四)——QT Creator工程管理

嵌入式linux QT开发(四)--QT Creator工程管理 一.QT Creator工程管理 QT Creator以工程项目的方式对源码进行管理,一个QT工程中包含不同类型的文件如下: A..pro项目描述文件 B..pro.user用户描述文件 C..h头文件 D..cpp源文件 E..ui界面描述文件 F.资源文件(图片.音频等) 二..pro项目描述文件 1..pro项目描述文件基本构成如下: A.#注释起始符 B.QT模块声明 C.TARGET可执行文件名 D.TEMPLATE程序

Android深度探索HAL与驱动开发 第四章

Android深度探索HAL与驱动开发 第四章 源代码的下载和编译 读书笔记 一.下载编译和测试Android源代码 1.配置Android源代码下载环境 创建一个用于存放下载脚本文件的目录(可将该文件放到任何一个目录在这里使用-/bin) # mkdir ~/bin # PATH=~/bin:$PATH 2.下载repo脚本文件(用于下载Android源代码) # curl htttps://dl-ssl.google.com/dl/googlesource/git-repo/repo> ~/