##使用环境
Ubuntu 16.04
googletest-release-1.8.0.tar.gz
##安装jenkins的xUnit插件
##编写测试程序
###自己使用的demo
https://github.com/QUSIR/googletest_demo
###运行测试程序输出xml
./Demo –gtest_output=xml:gtestreport.xml
##设置插件
##测试结果输出
##使用环境
Ubuntu 16.04
googletest-release-1.8.0.tar.gz
##安装jenkins的xUnit插件
##编写测试程序
###自己使用的demo
https://github.com/QUSIR/googletest_demo
###运行测试程序输出xml
./Demo –gtest_output=xml:gtestreport.xml
##设置插件
##测试结果输出
##设置git源码管理
内网搭建GitLab源码托管平台,如下设置,使用的是http方式,点击Add添加gitlab用户名和密码。
立即执行构建会出现以下信息
表示从gitlab拉取代码成功,clone路径是 /root/.jenkins/workspace/uart
##cppcheck静态代码分析
###在构建服务器上安装cppcheck
sudo apt install cppcheck
###在构建输入以下指令
cppcheck –enable=all –xml-version=2 ./ 2> cppcheck.xml
以上./是指当前目录,将检查以xml形式输出到cppcheck.xml文件
###安装cppcheck插件
####添加构建后cppcheck插件
####设置cppcheck插件
####输出结果
##gcovr代码覆盖率分析
###安装gcovr
sudo apt install gcovr
###安装Cobertura插件
###修改Makefile文件
在Makefile文件添加 -fprofile-arcs -ftest-coverage -fPIC 编译选项
Target=epoll_key
HomeDir = .
Objects=$(HomeDir)/Epoller.o $(HomeDir)/HotKeyService.o $(HomeDir)/main.o
CC=g++
Compile=$(CC) -fprofile-arcs -ftest-coverage -fPIC
Link=$(CC) -lstdc++
INCLUDE = -O3 -D_LINUX -DLINUX -DDEBUG
INCLUDE += -I./
INCLUDE += -I$(ServiceDir)/
LIB=-Wall -lz -lrt -ldl -lpthread -fprofile-arcs -ftest-coverage -fPIC
main : $(Objects)
$(Link) $(Objects) $(LIB) -o $(Target)
.cpp.o :
$(Compile) -c -o $@ $< $(INCLUDE)
.c.o :
$(Compile) -c -o $@ $< $(INCLUDE)
clean:
rm $(Objects)
###添加构建指令
chmod +x epoll_key
./epoll_key
gcovr -x -r “./“ –output “./coverage.xml”
###配置Cobertura插件
###构建输出
##安装
sudo pip install conan
##参考官网的demo
git clone https://github.com/memsharded/example-poco-timer.git mytimer
##命令
查看本地库
conan search
安装库
conan install zlib/1.2.8@lasote/stable
删除库
conan remove zlib/1.2.11@conan/stable
##编写conanfile.txt文件
[requires]
Poco/1.8.0.1@pocoproject/stable
[generators]
gcc
##编写main.cpp源文件
// $Id: //poco/1.4/Foundation/samples/Timer/src/Timer.cpp#1 $
// This sample demonstrates the Timer and Stopwatch classes.
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
// SPDX-License-Identifier: BSL-1.0
#include "Poco/Timer.h"
#include "Poco/Thread.h"
#include "Poco/Stopwatch.h"
#include <iostream>
using Poco::Timer;
using Poco::TimerCallback;
using Poco::Thread;
using Poco::Stopwatch;
class TimerExample{
public:
TimerExample(){ _sw.start();}
void onTimer(Timer& timer){
std::cout << "Callback called after " << _sw.elapsed()/1000 << " milliseconds." << std::endl;
}
private:
Stopwatch _sw;
};
int main(int argc, char** argv){
TimerExample example;
Timer timer(250, 500);
timer.start(TimerCallback<TimerExample>(example, &TimerExample::onTimer));
Thread::sleep(5000);
timer.stop();
return 0;
}
##根据conanfile.txt文件生成conanbuildinfo.gcc conanbuildinfo.txt conaninfo.txt文件
conan install .
##使用conanbuildinfo.gcc文件
gcc main.cpp -o main -DBOOST_USE_STATIC_LIBS -DPOCO_STATIC=ON -DPOCO_NO_AUTOMATIC_LIBS -I/home/qusir/.conan/data/Poco/1.8.0.1/pocoproject/stable/package/8a67b44a092c0074e3cb946a9ddada338054b11e/include -I/home/qusir/.conan/data/boost/1.66.0/conan/stable/package/eacfdb5f448bfd89f0b2950fb6b7a79e44c7ea08/include -I/home/qusir/.conan/data/OpenSSL/1.0.2l/conan/stable/package/0abbb2ea17cdc92f4a2ac8a9e55de717e3b5a9d1/include -I/home/qusir/.conan/data/bzip2/1.0.6/conan/stable/package/76f87539fc90ff313e0b3182641a9bb558a717d2/include -I/home/qusir/.conan/data/zlib/1.2.11/conan/stable/package/d358fec34c04bcd89832a09158783c750a3304dc/include -m64 -s -DNDEBUG -Wl,-rpath=”/home/qusir/.conan/data/Poco/1.8.0.1/pocoproject/stable/package/8a67b44a092c0074e3cb946a9ddada338054b11e/lib” -Wl,-rpath=”/home/qusir/.conan/data/boost/1.66.0/conan/stable/package/eacfdb5f448bfd89f0b2950fb6b7a79e44c7ea08/lib” -Wl,-rpath=”/home/qusir/.conan/data/OpenSSL/1.0.2l/conan/stable/package/0abbb2ea17cdc92f4a2ac8a9e55de717e3b5a9d1/lib” -Wl,-rpath=”/home/qusir/.conan/data/bzip2/1.0.6/conan/stable/package/76f87539fc90ff313e0b3182641a9bb558a717d2/lib” -Wl,-rpath=”/home/qusir/.conan/data/zlib/1.2.11/conan/stable/package/d358fec34c04bcd89832a09158783c750a3304dc/lib” -L/home/qusir/.conan/data/Poco/1.8.0.1/pocoproject/stable/package/8a67b44a092c0074e3cb946a9ddada338054b11e/lib -L/home/qusir/.conan/data/boost/1.66.0/conan/stable/package/eacfdb5f448bfd89f0b2950fb6b7a79e44c7ea08/lib -L/home/qusir/.conan/data/OpenSSL/1.0.2l/conan/stable/package/0abbb2ea17cdc92f4a2ac8a9e55de717e3b5a9d1/lib -L/home/qusir/.conan/data/bzip2/1.0.6/conan/stable/package/76f87539fc90ff313e0b3182641a9bb558a717d2/lib -L/home/qusir/.conan/data/zlib/1.2.11/conan/stable/package/d358fec34c04bcd89832a09158783c750a3304dc/lib -lPocoUtil -lPocoMongoDB -lPocoNet -lPocoNetSSL -lPocoCrypto -lPocoData -lPocoDataSQLite -lPocoZip -lPocoXML -lPocoJSON -lPocoFoundation -lpthread -lrt -lboost_wave -lboost_container -lboost_exception -lboost_graph -lboost_iostreams -lboost_locale -lboost_log -lboost_program_options -lboost_random -lboost_regex -lboost_wserialization -lboost_serialization -lboost_signals -lboost_coroutine -lboost_context -lboost_timer -lboost_thread -lboost_chrono -lboost_date_time -lboost_atomic -lboost_filesystem -lboost_system -lboost_type_erasure -lboost_log_setup -lboost_stacktrace_backtrace -lboost_math_tr1l -lboost_math_tr1f -lboost_stacktrace_basic -lboost_stacktrace_addr2line -lboost_math_c99f -lboost_math_tr1 -lboost_stacktrace_noop -lboost_math_c99l -lboost_math_c99 -lboost_unit_test_framework -lssl -lcrypto -ldl -lbz2 -lz -D_GLIBCXX_USE_CXX11_ABI=0 -lstdc++
其实就是将conanbuildinfo.gcc内容添加到gcc编译选项中
##查找远程库
conan remote add conan-transit https://conan-transit.bintray.com
conan search –remote conan-transit
conan remote add conan-center https://conan.bintray.com
conan search --remote conan-center
#说明
由于项目需要,使用通用的usb摄像头进行拍照,这样成本低且比较通用,市面上一大堆支持yuv的usb摄像头。而且linux内核自带yuv的usb驱动,不用移植驱动之类的。由于有些摄像头不支持抓拍jpg格式图片,是因为里面没有哈夫曼编码器对yuv数据进行编码成jpg格式图片。移植了libjpeg库,可以将yuy2格式转为jpg格式,还压缩了一遍。
#环境
Android 4.4,普通的yuv摄像头,不自带哈夫曼编码。
#查看android系统是否识别了usb摄像头
adb shll
ls /dev/video*
说明:如果显示有/dev/video
的控制句柄,那说明识别成功。
#使用
说明:建议先查看下托管代码下面的README文件。
libjpeg8d
为libjpeg
库得源码,进入该目录使用ndk-build
生成.a
静态库文件文件。
##模块使用说明
只要include encode_jpeg.h文件就可以了。
#define FILE_VIDEO "/dev/video1" //摄像头路径
#define PHOTO_FOLDER "/sdcard/androidDoor" // 图片存放路径
int get_photo(int size,int filename); //调用接口 第一个参数为设置
//图片大小,第二个参数为图片名称
#模块托管地址
https://github.com/QUSIR/yuy2_to_jpeg.git
#注
由于没有空,没有将该模块整合为一个Andoid Studio工程,但是可使用的的,从整个项目拆下来的子模块。详细请看代码,遇到问题请联系我。
#说明
由于需要用到全志的芯片的orangepi_zero的开源板子做项目,需要定制linux系统,对系统添加内置程序,修改镜像大小和ubuntu系统版本。需要对源码编译生成ubuntu系统镜像。
#使用编译环境
编译内核使用的是docke容器,比较方便。封装打包内核生成镜像使用实体机ubuntu16.04 64位。因为打包镜像在docker内运行会出错。
##docker地址
docker pull registry.cn-shenzhen.aliyuncs.com/qusir/orangepi_zero:0.2
#源码地址
https://github.com/QUSIR/orangepi_h2_linux
#依赖项安装
##设置dtc编译uboot
运行容器
docker run -it -v /home/orangepi_h2_linux:/data registry.cn-shenzhen.aliyuncs.com/qusir/orangepi_zero:0.2 bash
说明:将orangepi_h2_linux源码目录映射到容器的data文件夹
##编译dtc
dtc下载地址 链接:https://pan.baidu.com/s/1sndX30T 密码:c2mw
7z x dtc.7z
cd dtc
make
##设置dtc环境变量
export PATH=/data/dtc/:$PATH
##设置交叉编译器环境变量
export PATH=”$PWD/brandy/gcc-linaro/bin”:”$PATH”
#编译过程
##编译uboot
make CROSS_COMPILE=arm-linux-gnueabi- orangepi_zero_defconfig
##编译内核
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- sun8iw7p1smp_linux_defconfig
make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage modules
#编译文件生成文件拷贝
cp -rf ./linux-3.4/output/lib/ ./build/lib
cp -rf ./linux-3.4/arch/arm/boot/uImage ./build/uImage
cp -rf ./u-boot-2016.7/u-boot-sunxi-with-spl.bin ./build/uboot
cp -rf ./build/lib/ ../OrangePi-BuildLinux/orange/lib/
cp -rf ./build/uImage ../OrangePi-BuildLinux/orange/
cp -rf ./build/uboot/u-boot-sunxi-with-spl.bin ../OrangePi-BuildLinux/orange/
cp -rf ./build/uboot/boot.scr ../OrangePi-BuildLinux/orange/
#依赖项安装
实体机上
apt-get install debootstrap qemu-user-static chroot
#生成镜像
./create_image
./image_from_dir linux-trusty orangepi ext4 zero
说明:linux-trust为执行create_imge所生成系统目录,orangepi为生成镜像名称。
#镜像定制说明
修改 params.sh文件
# =====================================================
# ==== P A R A M E T E R S ============================
# =====================================================
# *****************************************************
# Set to "yes" to create realy minimal image *
# *****************************************************
ONLY_BASE="no"
# *****************************************************
# Set hostname, user to be created *
# and root and user passwords *
# *****************************************************
HOSTNAME="OrangePizero" #主机名称
USER="orangepi" #用户名
ROOTPASS="orangepi" #root密码
USERPASS="orangepi" #orangepi密码
# *****************************************************
# Set timezone, for default (HOST'S) set _timezone="" *
# *****************************************************
_timezone="Etc/UTC"
#_timezone=""
# *****************************************************
# SET IF YOU WANT TO INSTALL SPECIFIC LANGUAGE, *
# COMMENT FOR DEFAULT (HOST) settings *
# *****************************************************
LANGUAGE="en"
LANG="en_US.UTF-8"
# *****************************************************
# Set the base name of your image. *
# Distro name is automaticaty appended, and the image *
# will be "image_name-distro.img" *
# --------------------------------------------------- *
# IF image_name="", image file won't be created, *
# instalation will be created in local directories *
# linux-$distro & boot-$distro *
# YOU CAN CREATE THE IMAGE LATER RUNNING: *
# sudo ./image_from_dir <directory> <DEVICE|IMAGE> *
# === IT IS THE RECOMMENDED WAY OF IMAGE CREATION === *
# --------------------------------------------------- *
# IF image_name is BLOCK DEVICE (/dev/sdXn) *
# LINUX filesystem will be created directly on it *
# Partition must exist ! *
# IF _format="" partition will NOT be formated *
# otherwyse it will be formated with specified format *
# *****************************************************
image_name=""
#image_name="minimal"
#image_name="/dev/sdg"
# *****************************************************
# Filesystem type for linux partition *
# If btrfs is selectet, partition will be mounted *
# "compressed" option, you can save some sdcard space *
# --------------------------------------------------- *
# Used when creating the system directly on SDCard or *
# SDCard image file and in "image_from_dir" script *
# *****************************************************
_format="ext4" #文件系统
#_format="btrfs"
# *****************************************************
# SD Card partitions sizes in MB (1024 * 1024 bytes) *
# --------------------------------------------------- *
# If creating on physical sdcard (not image) you can *
# set "linuxsize=0" to use maximum sdcard size *
# --------------------------------------------------- *
# When creating the image with "image_from_dir" script*
# "linuxsize" is calculated from directory size *
# *****************************************************
fatsize=64
linuxsize=800 #生成镜像大小
# *****************************************************
# Select ubuntu/debian distribution and repository *
# === SELECT ONLY ONE distro AND ONE repo === *
# *****************************************************
# === Ubuntu ===
#distro="precise"
#distro="xenial"
distro="trusty" #ubuntu版本
#distro="utopic"
#distro="vivid"
#distro="wily"
#repo="http://ports.ubuntu.com/ubuntu-ports"
repo="http://mirrors.ustc.edu.cn/ubuntu-ports" #ubuntu镜像源
# === Debian ===
#distro="wheezy"
#distro="jessie"
#repo="http://ftp.hr.debian.org/debian"
#raspbian="no"
# === Raspbian ===
#distro="wheezy"
#distro="jessie"
#repo="http://archive.raspbian.org/raspbian"
#raspbian="yes"
# ******************************************************
# If creating the image, you can xz compress the image *
# after creation and make the md5sum file *
# to do that automatically, set _compress="yes" *
# ******************************************************
_compress="no"
# =====================================================
# IF YOU WANT TO HAVE BOOT FILES ON EXT4 PARTITION =
# AND NOT ON SEPARATE FAT16 PARTITION =
# set _boot_on_ext4="yes" and =
# FAT partitin won't be created =
# --------------------------------------------------- =
# DO NOT CHANGE FOR NOW ! =
# =====================================================
_boot_on_ext4="no"
# ^^^^ P A R A M E T E R S ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
##说明
由于需要读取键盘和串口输入,之前都是用循环读取的方式进行读取数据的,采用主动方式而不是等有数据过来的时候通知读取。前一种方式很耗资源也不方便管理,于是就想到epoll,这种一般使用在socket网络编程上的的。对于epoll的说明可以参考以下文章。
http://www.cnblogs.com/Anker/archive/2013/08/17/3263780.html
##原理
epoll方式是应用在数据流方面的,比如在socket网络数据传输时候,数据传递就是流,当有数据过来的时候会触发。以同样的方式对于键盘和串口数据输入也是一种流,所以也可以检测数据输入。方便管理,不用使用一直读的方式去读取数据,改为被动式方式读取。
##自己写的demo
https://github.com/QUSIR/key_epoll
说明:
#define DEV_PATH1 "/dev/input/event4"
#define UART_DEVICE_NAME "/dev/ttyUSB1"
以上为键盘和串口控制句柄
#orangepi zero接口图
#编译安装WiringOP
源码
WiringOP-zero.zip
解压
unzip WingOP-zero.zip
编译安装
cd WingOP-zero
./build
#测试是否安装成功
gpio -v
gpio readall
#例子程序,控制gpio0闪烁
vim test_gpio.c
##demo code
#include <wiringPi.h>
int main(void)
{
wiringPiSetup() ;
pinMode (0, OUTPUT) ;
for(;;)
{
digitalWrite(0, HIGH) ; delay (500) ;
digitalWrite(0, LOW) ; delay (500) ;
}
}
##编译demo
gcc -Wall -o test_gpio test_gpio.c -lwiringPi -lpthread
##执行程序
sudo ./test_gpio
##说明
由于每次插入刷卡器之后,控制句柄会发生改变。
例如这次是/dev/input/event1
,下次是/dev/input/event0
。面对会有多个event
,必须写个查找程序。
##解决方法
linux系统里面的/proc/bus/input/devices
文件存储了输入设备的信息,可以通过读取该文件判断输入设备。该文件信息如下:
qusir@qusir-HP-dx2818-MT:~$ cat /proc/bus/input/devices
I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=PNP0C0C/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
U: Uniq=
H: Handlers=kbd event0
B: PROP=0
B: EV=3
B: KEY=10000000000000 0
I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=LNXPWRBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXPWRBN:00/input/input1
U: Uniq=
H: Handlers=kbd event1
B: PROP=0
B: EV=3
B: KEY=10000000000000 0
I: Bus=0003 Vendor=413c Product=2106 Version=0110
N: Name="DELL Dell QuietKey Keyboard"
P: Phys=usb-0000:00:1d.1-1/input0
S: Sysfs=/devices/pci0000:00/0000:00:1d.1/usb7/7-1/7-1:1.0/0003:413C:2106.0001/input/input5
U: Uniq=
H: Handlers=sysrq kbd event2 leds
B: PROP=0
B: EV=120013
B: KEY=1000000000007 ff9f207ac14057ff febeffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7
I: Bus=0003 Vendor=093a Product=2510 Version=0111
N: Name="PixArt USB Optical Mouse"
P: Phys=usb-0000:00:1d.1-2/input0
S: Sysfs=/devices/pci0000:00/0000:00:1d.1/usb7/7-2/7-2:1.0/0003:093A:2510.0002/input/input6
U: Uniq=
H: Handlers=mouse0 event3
B: PROP=0
B: EV=17
B: KEY=70000 0 0 0 0
B: REL=103
B: MSC=10
I: Bus=0003 Vendor=ffff Product=0035 Version=0110
N: Name="Sycreader RFID Technology Co., Ltd SYC ID&IC USB Reader"
P: Phys=usb-0000:00:1d.2-1/input0
S: Sysfs=/devices/pci0000:00/0000:00:1d.2/usb8/8-1/8-1:1.0/0003:FFFF:0035.0003/input/input7
U: Uniq=08FF20140315
H: Handlers=sysrq kbd event4 leds
B: PROP=0
B: EV=120013
B: KEY=e080ffdf01cfffff fffffffffffffffe
B: MSC=10
B: LED=1f
I: Bus=0003 Vendor=e806 Product=6001 Version=0040
N: Name="USB 2.0 Camera"
P: Phys=usb-0000:00:1d.7-6/button
S: Sysfs=/devices/pci0000:00/0000:00:1d.7/usb2/2-6/2-6:1.0/input/input8
U: Uniq=
H: Handlers=kbd event5
B: PROP=0
B: EV=3
B: KEY=100000 0 0 0
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HDA Intel Front Mic"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:1b.0/sound/card0/input9
U: Uniq=
H: Handlers=event6
B: PROP=0
B: EV=21
B: SW=10
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HDA Intel Rear Mic"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:1b.0/sound/card0/input10
U: Uniq=
H: Handlers=event7
B: PROP=0
B: EV=21
B: SW=10
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HDA Intel Line"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:1b.0/sound/card0/input11
U: Uniq=
H: Handlers=event8
B: PROP=0
B: EV=21
B: SW=2000
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HDA Intel Line Out"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:1b.0/sound/card0/input12
U: Uniq=
H: Handlers=event9
B: PROP=0
B: EV=21
B: SW=40
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HDA Intel Front Headphone"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:1b.0/sound/card0/input13
U: Uniq=
H: Handlers=event10
B: PROP=0
B: EV=21
B: SW=4
可以看到以上信息中有"Sycreader RFID Technology Co., Ltd SYC ID&IC USB Reader"
关键字,通过该关键字可以判断刷卡器的控制句柄为event4
##程序说明
##说明
由于防止linux系统下程序突然意外终止或是陷入死循环等情况,启用看门狗机制,出现问题的时候机器重启。
##初始化看门狗
查看liux系统下是否有 /dev/watchdog
控制句柄
ls /dev/watchdog
代码段
int fd = open("/dev/watchdog", O_WRONLY);
if(fd == -1){
printf("open watchdog error \n\n\n");
return false;
}
int timeout;
timeout = 15;
ioctl(fd, WDIOC_SETTIMEOUT, &timeout); //设置超时
printf("The timeout was set to %d seconds\n", timeout);
##喂狗
ioctl(this->fd, WDIOC_KEEPALIVE);
使用定时的方式运行以上语句,延时时间必须小于超时时间。
##说明
使用orangepi外接USB摄像头进行拍照,发现没有/dev/video0
,可能没哟将yuv驱动编译进内核,需要外部加载进去。
##添加驱动
一开始没有发现/lib/modules/3.4.39/
目录下uvcvideo.ko
,害得自己找来orangepi内核重新编译了一遍。
1.插入驱动模块
sudo insmod /lib/modules/3.4.39/uvcvideo.ko
2.查看是否识别了驱动
ls /dev/video0
3.添加系统启动时候加载驱动
sudo vim /etc/rc.local
添加以下语句
sudo insmod /lib/modules/3.4.39/uvcvideo.ko