0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

米尔电子MYD-YA15XC-T开发板试用测评---dql2016

米尔电子 2022-01-04 15:01 次阅读
近期,米尔电子重磅发布新品“MYD-YA15XC-T”开发板,并在电子工程世界、电子发烧友、电路城等各大论坛发布试用通知,受到了众多工程师、广大电子爱好者围观,米尔选取了电子发烧友平台一篇优秀试用报告,在此同步给各位小伙伴们。

01

【米尔MYD-YA15XC-T评测】+开箱上电测

7e428d98-6b1f-11ec-ad3b-dac502259ad0.gif

STM32MP1 是意法半导体推出的首款 MPU,其内部集成了 1-2 颗主频 650MHz 的 Arm Cortex-A7 应用处理器内核和 1 颗运行频率 209MHz 的高性能 Arm Cortex-M4 微 控制器内核。两种内核之间分工明确、配合默契,Cortex-A7 内核专用于开源操作系统, Cortex-M4 内核则专用于实时及低功耗任务处理。这一灵活的异构计算架构在单一芯片 上执行快速数据处理和实时任务,可以实现最高的能效。MYC-YA15XC-T 核心板基于 STM32MP1 系列处理器研制,完美继承了该处理器高 性能、低功耗的优点,且拥有良好的软件开发环境,Cortex-A7 内核支持开源操作系统 Linux,Cortex-M4 内核完美沿用现有的 STM32 MCU 生态系统,有助于开发者轻松实 现各类开发应用。

这次的板卡包装比米尔以往的板卡包装大得多。

7e4e1adc-6b1f-11ec-ad3b-dac502259ad0.jpg

7e6965b2-6b1f-11ec-ad3b-dac502259ad0.jpg

包装很用心:含有指导手册

7e8da940-6b1f-11ec-ad3b-dac502259ad0.jpg

电源适配器赠送了不同国家的插口适配器:

7e97a404-6b1f-11ec-ad3b-dac502259ad0.jpg

一如既往的黑色沉金

7ea417e8-6b1f-11ec-ad3b-dac502259ad0.jpg

板卡背面

7eb169c0-6b1f-11ec-ad3b-dac502259ad0.jpg

赠送了塑料螺柱

7ebe9212-6b1f-11ec-ad3b-dac502259ad0.jpg

上电效果

7ec9f436-6b1f-11ec-ad3b-dac502259ad0.jpg

接下来就需要下载资料进行交叉编译器和SDK环境的安装了。

02

【米尔MYD-YA15XC-T评测】+ USB UVC摄像头测试

7e428d98-6b1f-11ec-ad3b-dac502259ad0.gif

UVC全称为USB Video Class,即:USB视频类,是一种为USB视频捕获设备定义的协议标准。是Microsoft与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标准,已成为USB org标准之一。米尔MYD-YA15XC-T开发板内核已经开启了UVC驱动,因此插入USB UVC摄像头后可以看到识别信息7ee22970-6b1f-11ec-ad3b-dac502259ad0.png

V4L2是Video for linux2的简称,为linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video*下,如果只有一个视频设备,通常为/dev/video0。v4l2-ctl是用户空间一组用于测试,配置和使用整个相机子系统的工具,包括外部相机传感器和相机接口。v4l2-ctl 是最有用的实用工具。

v4l2-ctl基本常用的命令如下:

  • 使用--list-devices选项列出所有可用的视频设备


  • v4l2-ctl --list-devices

7ef0f41e-6b1f-11ec-ad3b-dac502259ad0.png

  • 获得有关特定设备的信息,加上-D 选项:


  • v4l2-ctl -d /dev/video1 -D

7eff3790-6b1f-11ec-ad3b-dac502259ad0.png

7f0ad7b2-6b1f-11ec-ad3b-dac502259ad0.png


  • v4l2-ctl -L -d /dev/video1

7f1d6116-6b1f-11ec-ad3b-dac502259ad0.png

其中可以通过 --set-ctrl 选项更改控制值,如:


  • v4l2-ctl --set-ctrl test_pattern=1

控制值可以动态更改。

  • 设置像素格式,分辨率和帧率,使用 --list-formats-ext 选项可获取受支持的像素格式、分辨率和帧速率:


  • v4l2-ctl --list-formats-ext -d /dev/video1

7f294ec2-6b1f-11ec-ad3b-dac502259ad0.png

  • 查看当前摄像头支持的视频压缩格式


  • v4l2-ctl -d /dev/video1 --list-formats

7f3a0e06-6b1f-11ec-ad3b-dac502259ad0.png

  • 查看摄像头所有参数


  • v4l2-ctl -d /dev/video1 --all

7f49c7e2-6b1f-11ec-ad3b-dac502259ad0.png

7f5a33c0-6b1f-11ec-ad3b-dac502259ad0.png

  • 查看摄像头所支持的分辨率


  • v4l2-ctl --list-framesizes=MJPG -d /dev/video1

7f6bc0fe-6b1f-11ec-ad3b-dac502259ad0.png

GStreamer是用于创建流媒体应用程序的框架,开发板集成了gstreamer系列命令。

  • 单次拍照


  • gst-launch-1.0 v4l2src device=/dev/video1 num-buffers=1 ! image/jpeg,width=1920,height=1080 ! filesink location=/tmp/capture.jpg

7f7f2c5c-6b1f-11ec-ad3b-dac502259ad0.png

使用 gst-typefind 命令检查图片分辨率


  • gst-typefind-1.0 /tmp/capture.jpg

7f8b07d4-6b1f-11ec-ad3b-dac502259ad0.png

初步完成了usb摄像头图像的采集,后续将研究简单的图像处理,视频采集,体验米尔MYD-YA15XC-T开发板的多媒体处理性能。

03

【米尔MYD-YA15XC-T评测】+使用mjpg-streamer搭建网络摄像头

7e428d98-6b1f-11ec-ad3b-dac502259ad0.gif

0、mjpg-streamer介绍

mjpg-streamer是一款免费基于IP地址的视频流服务器,它的输入插件从摄像头读取视频数据,这个输入插件产生视频数据并将视频数据复制到内存中,它有多个输出插件将这些视频数据经过处理,其中最重要的输出插件是网站服务器插件,它将视频数据传送到用户浏览器中,mjpg-streamer的工作就是将其中的一个输入插件和多个输出插件绑定在一起,所有的工作都是通过它的各个插件完成的。mjpg-streamer各个文件如下:

(1)input_testpicture.so。这是一个图像测试插件,它将预设好的图像编译成一个头文件,可以在没有摄像头的情况下传输图像,从而方便调试程序。

(2)input_uvc.so。此文件调用USB摄像头驱动程序V4L2,从摄像头读取视频数据。

(3)input_control.so。这个文件实现对摄像头转动的控制接口。

(4)output_http.so。这是一个功能齐全的网站服务器,它不仅可以从单一文件夹中处理文件,还可以执行一定的命令,它可以从输入插件中处理一幅图像,也可以将输入插件的视频文件根据现有M-JPEG标准以HTTP视频数据服务流形式输出。

(5)output_file.so。这个插件的功能是将输入插件的JPEG图像存储到特定的文件夹下,它可以用来抓取图像。

mjpg-streamer优点是对RAMCPU的消耗比较少,可以快速的传输jpeg流。

一、米尔SDK安装

7fda7f26-6b1f-11ec-ad3b-dac502259ad0.png

在终端执行命令:


  • . /opt/st/myir/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

将设置好交叉编译工具链,常用的环境变量如CC。

二、libjpeg交叉编译

有些UVC摄像头只支持输出YUV原始图像,此时mjpg-streamer会将其转码为mjpeg,然后进行传输,此时会对CPU的消耗以及实时流的流畅度有影响,特别是分辨率比较大的时候。

因此mjpg-streamer 依赖 libjpeg, libjpeg下载地址:
http://www.ijg.org/

7fe620ce-6b1f-11ec-ad3b-dac502259ad0.png

目前最新版本是v9d。libjpeg交叉编译命令:


  • make clean

  • . /opt/st/myir/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

  • ./configure --host=arm-ostl-linux-musl --prefix=$HOME/stm32mp1/build_jpegsrc.v9d

  • make -j6

  • make install

写成编译脚本:

7ff3e4d4-6b1f-11ec-ad3b-dac502259ad0.png

编译成功后得到动态库:

80044e3c-6b1f-11ec-ad3b-dac502259ad0.png

米尔MYD-YA15XC-T内核已经配置好了UVC和USB 驱动,因此无需重新配置编译内核。

三、mjpg-streamer交叉编译

mjpeg-streamer下载

https://sourceforge.net/p/mjpg-streamer/code/HEAD/tree/

80113cc8-6b1f-11ec-ad3b-dac502259ad0.png

目前最新版本为r182,本次测试使用版本r63。

在ubuntu可通过2种命令下载代码:


  • svn checkout svn://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code

或者


  • svn checkout https://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code

在编译前需要对源码的Makefile做以下修改:
将源码的所有Makefile(包含其子目录)中的编译工具链修改为米尔开发板的编译工具链,由于在终端执行命令. /opt/st/myir/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi会设置好交叉编译相关的环境变量,因此去掉Makefile文件中的CC 即可。

本次测试只需要 input_uvc.so 和 output_http.so,在主目录中的Makefile里面只选择这两个,其它的去掉。

插件input_uvc依赖jpeg,因此修改plugins/input_uvc/Makefile文件,指定jpeg库头文件路径:


  • CFLAGS += -I$HOME/stm32mp1/build_jpegsrc.v9d/include

指定链接jpeg动态库路径:


  • -ljpeg -L$HOME/stm32mp1/build_jpegsrc.v9d/lib

804a9e1e-6b1f-11ec-ad3b-dac502259ad0.png

编译成功之后,在lib目录会生成如下输入、输出动态库文件:

8078c992-6b1f-11ec-ad3b-dac502259ad0.png

在mjpg-streamer-r63目录生成mjpg-streamer可执行文件:

80862042-6b1f-11ec-ad3b-dac502259ad0.png

查看一下mjpg-streamer文件信息,ARM 32位可执行程序:

80902150-6b1f-11ec-ad3b-dac502259ad0.png

将上面生成的动态库文件都复制到lib目录:

80a06010-6b1f-11ec-ad3b-dac502259ad0.png

然后将lib目录里面的文件和mjpg-streamer可执行文件一起打包为app_and_lib.tar.xz,使用SCP命令将它复制到开发板home目录:

80bc53c4-6b1f-11ec-ad3b-dac502259ad0.png

解压:

80c677b4-6b1f-11ec-ad3b-dac502259ad0.png

得到如下文件,使用chmod +x mjpg-streamer命令为mjpg-streamer添加可执行权限:

80d75278-6b1f-11ec-ad3b-dac502259ad0.png

四、测试

插入USB UVC摄像头,正确识别到了视频设备:

80e73062-6b1f-11ec-ad3b-dac502259ad0.png

手动指定一下库路径:


  • export LD_LIBRARY_PATH=./

执行下列命令启动mjpg-streamer:


  • ./mjpg_streamer -i "input_uvc.so -r 1920x1080" -o "output_http.so -w ./www"

80f48fe6-6b1f-11ec-ad3b-dac502259ad0.png


如果是输出YUV格式的UVC摄像头,则执行命令:


  • ./mjpg_streamer -i "input_uvc.so -y -r 1920x1080" -o "output_http.so -w ./www

查看图片,在浏览器输入:
http://192.168.1.136:8080/?action=snapshot
查看视频,在浏览器输入:
http://192.168.1.136:8080/?action=stream
其中192.168.1.136为开发板IP地址。

附录:

MJPG简介:MJPEG全名为 "Motion Joint Photographic Experts Group",是一种视频编码格式,Motion JPEG技术常用闭合电路的电视摄像机的模拟视频信号“翻译”成视频流,并存储在硬盘上。典型的应用如数字视频记录器等。MJPEG不像MPEG,不使用帧间编码,因此用一个非线性编辑器就很容易编辑。MJPEG的压缩算法与MPEG一脉相承,功能很强大,能发送高质图片,生成完全动画视频等;从另一个角度说,在某些条件下,MJPEG也许是效率最低的编码/解码器之一。MJPEG与MJPG的区别:mjpeg视频,就是由系列jpg图片组成的视频。

还有一款MJPG视频流服务开源软件uStreamer:

µStreamer is a lightweight and very quick server to streamMJPGvideo from any V4L2 device to the net.

https://github.com/pikvm/ustreamer

8126277c-6b1f-11ec-ad3b-dac502259ad0.png

04

【米尔MYD-YA15XC-T评测】+ 使用ffmpeg音视频处理软件处理多媒体文件(上)

7e428d98-6b1f-11ec-ad3b-dac502259ad0.gif

在多媒体音视频处理应用中一个常见的需求就是给视频或者图像叠加水印文字、图片logo等。以下是ffmpeg的介绍:

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。[1] FFmpeg编码库可以使用GPU加速。

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了领先的音/视频编码库libavcodec等。
libavformat:用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构
和读取音视频帧等功能;
libavcodec:用于各种类型声音/图像编解码;
libavutil:包含一些公共的工具函数;
libswscale:用于视频场景比例缩放、色彩映射转换;
libpostproc:用于后期效果处理;
ffmpeg:该项目提供的一个工具,可用于格式转换、解码或电视卡即时编码等;
ffsever:一个 HTTP 多媒体即时广播串流服务器;
ffplay:是一个简单的播放器,使用ffmpeg 库解析和解码,通过SDL显示;

本次就打算使用ffmpeg进行中英文特殊字符水印、图片水印的叠加测试,首先在电脑端实现功能,然后交叉编译移植到米尔MYD-YA15XC-T平台,顺便定性对比下电脑和米尔MYD-YA15XC-T的多媒体处理性能。

在编译ffmpeg前需要先编译字体处理软件freetype,这里使用了freetype-2.10.2版本。

编译命令如下:


  • make clean

  • ./configure --prefix=/opt/nrjd/nrjd-olms-0201/apps/aaa/comm/pc/freetype --with-zlib=no --with-png=no --enable-static=no

  • make -j12

  • make install

  • make clean

81453806-6b1f-11ec-ad3b-dac502259ad0.png

然后编译ffmpeg,指定freetype库和头文件路径:


  • make clean

  • ./configure --enable-shared --disable-static --target-os=linux --enable-libx264 --enable-gpl --enable-libfreetype --enable-filter=drawtext --extra-cflags="-I/home/qldeng/ffmpeg_watermark_test/ffmpeg_test_pc/comm/pc/freetype/include/freetype2" --extra-ldflags="-L/home/qldeng/ffmpeg_watermark_test/ffmpeg_test_pc/comm/pc/freetype/lib" --prefix=/home/qldeng/ffmpeg_watermark_test/ffmpeg_test_pc/comm/pc/ffmpeg

  • make -j12

  • make install

  • make clean

8173b744-6b1f-11ec-ad3b-dac502259ad0.png

项目文件夹内容如下:


  • qldeng@ubuntu:~/ffmpeg_watermark_test/ffmpeg_test_pc$ tree -L 2

  • .

  • ├── build

  • ├── CMakeLists.txt

  • ├── comm

  • │ ├── ffmpeg-4.4

  • │ ├── freetype-2.10.2

  • │ └── pc

  • ├── in.jpg

  • ├── logo.png

  • ├── main.cpp

  • ├── out.jpg

  • ├── readme.txt

  • ├── SourceHanSansCN-Bold.ttf

  • ├── toolchain.cmake

  • └── 捕获.PNG

  • 5 directories, 9 files

8180139a-6b1f-11ec-ad3b-dac502259ad0.png

测试项目使用CMake构建,CMakeLists.txt内容如下:


  • cmake_minimum_required(VERSION 3.17)

  • #输出可执行文件的文件名

  • set(ARTIFACT_NAME myapp)

  • project(${ARTIFACT_NAME})

  • set(CMAKE_CXX_STANDARD 11)

  • set(CMAKE_C_STANDARD 99)

  • set(MYLIBS_PATH /opt/nrjd/nrjd-olms-0201/apps/ffmpeg_test_pc/comm/pc)

  • set(INC_DIR

  • ${PROJECT_SOURCE_DIR}

  • ${MYLIBS_PATH}/freetype/include/freetype2

  • ${MYLIBS_PATH}/ffmpeg/include

  • )

  • set(LINK_DIR

  • ${MYLIBS_PATH}/freetype/lib

  • ${MYLIBS_PATH}/ffmpeg/lib

  • )

  • include_directories(${INC_DIR})

  • link_directories(${LINK_DIR})

  • aux_source_directory(${PROJECT_SOURCE_DIR} SOURCE_FILES)

  • set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})

  • link_libraries(

  • freetype

  • avcodec

  • avdevice

  • avfilter

  • avformat

  • avutil

  • postproc

  • swresample

  • swscale

  • )

  • add_executable(${ARTIFACT_NAME} ${SOURCE_FILES})

  • target_link_libraries(${ARTIFACT_NAME}

  • freetype

  • avcodec

  • avdevice

  • avfilter

  • avformat

  • avutil

  • postproc

  • swresample

  • swscale

  • pthread)

main.cpp是测试代码,直接使用system函数调用ffmpeg即可,需要注意的是特殊符号需要转义:


  • cmd = "ffmpeg -loglevel quiet -i " + string(dest_path) + " -vf drawtext="fontcolor=white:fontfile=SourceHanSansCN-Bold.ttf:fontsize=40:x=w-tw-th/2:y=h-th-th::alpha=0.65:box=1:boxcolor=0x000000:text='" + string(s5) + "" -y " + string(dest_path);

  • system(cmd.c_str());


  • float battery_voltage = 12.345;

  • float battery_current = 0.678;

  • float device_temperature = 37.2;

  • s1 = "日期\\:" + string(str) + """;

  • memset(str, 0, sizeof(str));

  • sprintf(str, "处理器\\:%0.1f\℃ 电源\\:%0.1fV %0.2fA CSQ\\:%d%%", device_temperature, battery_voltage,battery_current,64);

  • s2 = string(str);

toolchain.cmake内容:


  • set(CMAKE_CXX_COMPILER g++)

  • set(CMAKE_C_COMPILER gcc)

进入build目录,打开终端执行以下命令进行编译:


  • cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ..

  • make

可以看到图片上叠加了预期的水印内容,处理时间183毫秒:
818d88ea-6b1f-11ec-ad3b-dac502259ad0.png

下一步就是眼睛就如何正确交叉编译ffmpeg到米尔MYD-YA15XC-T平台了,周六晚上折腾了半天,虽然编译出了命令行工具个库,但是放到米尔MYD-YA15XC-T里面无法运行,总是提示命令找不到,还得仔细研究下。

05

【米尔MYD-YA15XC-T评测】+ 使用STM32CubeProgrammer软件更新系统固件

7e428d98-6b1f-11ec-ad3b-dac502259ad0.gif

米尔提供的资料01_Documents\User_Manual\Chinese\软件手册\MYD-YA15XC-T_Linux软件开发指南V1.0.0.pdf第四节描述了如何更新系统固件。

MYC-YA15XC-T 开发板采用的是 ST 公司的 STM32MP1 系列微处理器,原生支持使用ST推出的STM32CubeProgrammer软件更新系统固件,只需要连接一根USB线通信即可完成烧录固件,快速方便。按照米尔提供的资料,实际使用中遇到些小问题

首先选择启动模式,将拨码开关拨到 Download 模式(B2/B1/B0 : 0/0/0)。将开发板的 J5 USB接口与电脑连接,插入电源适配器。如下图所示:

81e609e8-6b1f-11ec-ad3b-dac502259ad0.jpg

这时候可以在电脑发现USB DFU设备了:

81f1d80e-6b1f-11ec-ad3b-dac502259ad0.png

打开 STM32CubeProgrammer 软件,选择 USB烧录方式:

8226d6bc-6b1f-11ec-ad3b-dac502259ad0.png

点击 connect按钮连接,连接正常就会显示处理器的信息,如下图:

82362040-6b1f-11ec-ad3b-dac502259ad0.png

根据本开发板的处理器选择的烧录包位于目录myir-image-core\256N256D。然后点击Open File,选择nand的 TSV 文件myir-image-core\256N256D\myir-image-core\flashlayout_myir-image-core\trusted\FlashLayout_nand-2-256_stm32mp15xc-ya151c-256d-t-trusted.tsv,如下图所示:

824366d8-6b1f-11ec-ad3b-dac502259ad0.png

但是按照这个步骤烧录出错了:

8286e4bc-6b1f-11ec-ad3b-dac502259ad0.png

根据错误原因提示,将目录myir-image-core\256N256D\myir-image-core下的arm-trusted-firmware、bootloader、myir-image-core-openstlinux-eglfs-myir-ya151c-t_nand_2_256_multivolume.ubi复制到目录myir-image-core\256N256D\myir-image-core\flashlayout_myir-image-core\trusted下即可:

82c505c6-6b1f-11ec-ad3b-dac502259ad0.png

82d3746c-6b1f-11ec-ad3b-dac502259ad0.png

然后就可以烧录成功了:

82fc58dc-6b1f-11ec-ad3b-dac502259ad0.png

831072b8-6b1f-11ec-ad3b-dac502259ad0.png

06

【米尔MYD-YA15XC-T评测】+ epoll串口通信

7e428d98-6b1f-11ec-ad3b-dac502259ad0.gif

串口是嵌入式系统中最常用的接口之一,系统终端通常都是串口。除了终端功能之外,实际应用中,Linux系统也经常通过串口与其它设备进行通信和数据传递,如232、485等接口传感器通常底层都是串口。在Linux下的串口编程不像微控制器上那么简单。本帖以米尔MYD-YA15XC-T为例,实现串口基本操作、串口属性设置、如串口数据读写。米尔MYD-YA15XC-T开发板扩展排针接口引出了串口3供我们使用。位置如下图所示:

834e9ee4-6b1f-11ec-ad3b-dac502259ad0.png

终端使用ls /dev/tty*命令查看设备文件:

835e28fa-6b1f-11ec-ad3b-dac502259ad0.png

Linux的串口表现为设备文件,Linux的串口设备文件命名一般为/dev/tty*,米尔MYD-YA15XC-T开发板串口设备命名为/dev/ttySTM*

可以看到串口3对应的设备文件是/dev/ttySTM3,使用一个TTL串口调试助手连接到串口3:
836aa60c-6b1f-11ec-ad3b-dac502259ad0.jpg

首先使用echo命令测试发送数据,可以看到串口3收到了数据:
8377cbe8-6b1f-11ec-ad3b-dac502259ad0.png

接下来通过编写代码的方式实现串口的数据收发。

首先配置网络,因为后面拷贝文件到开发板需要用到。
8387cf84-6b1f-11ec-ad3b-dac502259ad0.png

在编写Linux串口的C程序代码时,需要包含termios.h头文件。主要流程为:

打开串口:用open()函数打开它所对应的设备文件。

关闭串口:用close()函数关闭串口。

发送数据:使用write()函数可以发送数据。

读取数据:使用read()函数可以读取接收到的数据。

此外,如果对串口属性进行设置需要包含头文件,该文件包含了POSIX终端属性描述结构struct termios。

完整的代码如下所示:


  • #include

  • using namespace std;

  • #include

  • #include

  • #include

  • #include

  • #include

  • #include

  • #include

  • #include

  • #include

  • class MySerial

  • {

  • private:

  • int fd = -1;

  • string serial_dev;

  • int serial_baudrate;

  • string serial_parity;

  • int serial_databits;

  • int serial_stopbits;

  • void* (*rx_cb_fun)(void*);

  • int epfd;

  • struct epoll_event event;// 告诉内核要监听什么事件

  • struct epoll_event wait_event;

  • public:

  • MySerial(string serial_dev, int serial_baudrate, string serial_parity, int serial_databits, int serial_stopbits,void* (*rx_cb_fun)(void*))

  • {

  • this-> serial_dev= serial_dev;

  • this-> serial_baudrate= serial_baudrate;

  • this-> serial_parity= serial_parity;

  • this-> serial_databits= serial_databits;

  • this-> serial_stopbits= serial_stopbits;

  • this->rx_cb_fun = rx_cb_fun;

  • epfd = epoll_create(10); // 创建一个 epoll 的句柄,参数要大于 0, 没有太大意义

  • if( -1 == epfd )

  • {

  • perror ("epoll_create");

  • }

  • };

  • int OpenSerial()

  • {

  • struct termios tios;

  • int speed;

  • fd = open(serial_dev.c_str(), O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL);

  • if (fd < 0)

  • {

  • perror("open");

  • }

  • memset(&tios, 0, sizeof(struct termios));

  • switch (serial_baudrate)

  • {

  • case 50:

  • speed = B50;

  • break;

  • case 75:

  • speed = B75;

  • break;

  • case 110:

  • speed = B110;

  • break;

  • case 134:

  • speed = B134;

  • break;

  • case 150:

  • speed = B150;

  • break;

  • case 200:

  • speed = B200;

  • break;

  • case 300:

  • speed = B300;

  • break;

  • case 600:

  • speed = B600;

  • break;

  • case 1200:

  • speed = B1200;

  • break;

  • case 1800:

  • speed = B1800;

  • break;

  • case 2400:

  • speed = B2400;

  • break;

  • case 4800:

  • speed = B4800;

  • break;

  • case 9600:

  • speed = B9600;

  • break;

  • case 19200:

  • speed = B19200;

  • break;

  • case 38400:

  • speed = B38400;

  • break;

  • case 57600:

  • speed = B57600;

  • break;

  • case 115200:

  • speed = B115200;

  • break;

  • case 230400:

  • speed = B230400;

  • break;

  • case 460800:

  • speed = B460800;

  • break;

  • case 500000:

  • speed = B500000;

  • break;

  • case 576000:

  • speed = B576000;

  • break;

  • case 921600:

  • speed = B921600;

  • break;

  • case 1000000:

  • speed = B1000000;

  • break;

  • case 1152000:

  • speed = B1152000;

  • break;

  • case 1500000:

  • speed = B1500000;

  • break;

  • case 2000000:

  • speed = B2000000;

  • break;

  • case 2500000:

  • speed = B2500000;

  • break;

  • case 3000000:

  • speed = B3000000;

  • break;

  • case 3500000:

  • speed = B3500000;

  • break;

  • case 4000000:

  • speed = B4000000;

  • break;

  • default:

  • speed = B9600;

  • break;

  • }

  • if ((cfsetispeed(&tios, speed) < 0) || (cfsetospeed(&tios, speed) < 0))

  • {

  • close(fd);

  • fd = -1;

  • perror("cfsetispeed or cfsetospeed");

  • }

  • tios.c_cflag |= (CREAD | CLOCAL);

  • tios.c_cflag &= ~CSIZE;

  • switch (serial_databits)

  • {

  • case 5:

  • tios.c_cflag |= CS5;

  • break;

  • case 6:

  • tios.c_cflag |= CS6;

  • break;

  • case 7:

  • tios.c_cflag |= CS7;

  • break;

  • case 8:

  • default:

  • tios.c_cflag |= CS8;

  • break;

  • }

  • if (serial_stopbits == 1)

  • {

  • tios.c_cflag &= ~CSTOPB;

  • }

  • else

  • {

  • tios.c_cflag |= CSTOPB;

  • }

  • if (serial_parity == "none")

  • {

  • tios.c_cflag &= ~PARENB;

  • }

  • else if (serial_parity == "even")

  • {

  • tios.c_cflag |= PARENB;

  • tios.c_cflag &= ~PARODD;

  • }

  • else if (serial_parity == "odd")

  • {

  • tios.c_cflag |= PARENB;

  • tios.c_cflag |= PARODD;

  • }

  • tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

  • if (serial_parity == "none")

  • {

  • tios.c_iflag &= ~INPCK;

  • }

  • else

  • {

  • tios.c_iflag |= INPCK;

  • }

  • tios.c_iflag &= ~(IXON | IXOFF | IXANY);

  • tios.c_oflag &= ~OPOST;

  • tios.c_cc[VMIN] = 0;

  • tios.c_cc[VTIME] = 0;

  • if (tcsetattr(fd, TCSANOW, &tios) < 0)

  • {

  • close(fd);

  • fd = -1;

  • perror("tcsetattr");

  • }

  • event.data.fd = fd; // 串口描述符

  • event.events = EPOLLIN; // 表示对应的文件描述符可以读

  • // 事件注册函数,将描述符fd加入监听事件

  • int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);

  • if(-1 == ret)

  • {

  • perror("epoll_ctl");

  • }

  • return fd;

  • }

  • void loop()

  • {

  • int ret;

  • // 监视并等待多文件(串口)描述符的属性变化(是否可读)

  • // 没有属性变化,这个函数会阻塞,直到有变化才往下执行,这里没有设置超时

  • ret = epoll_wait(epfd, &wait_event, 2, -1);

  • if(ret == -1) // 出错

  • {

  • close(epfd);

  • perror("epoll");

  • }

  • else if(ret > 0) // 准备就绪的文件描述符

  • {

  • //char buf[100] = {0};

  • if((fd == wait_event.data.fd) && (EPOLLIN == wait_event.events & EPOLLIN))

  • {

  • rx_cb_fun(&fd);

  • }

  • }

  • else if(0 == ret)

  • {

  • printf("time out\n");

  • }

  • }

  • ~MySerial()

  • {

  • close(fd);

  • close(epfd);

  • }

  • };

  • void *SerialRxCB(void* arg)

  • {

  • int fd = *(int*)arg;

  • char buf;

  • read(fd, &buf, 1);

  • printf("%c\n", buf);

  • return NULL;

  • }

  • void thread_task(void* arg)

  • {

  • int fd = *(int*)arg;

  • while(1)

  • {

  • char tx_buf[]="hello eeworld & mier";

  • this_thread::seconds(1));

  • write (fd, tx_buf, sizeof(tx_buf));

  • }

  • }

  • int main(int argc,char* argv[])

  • {

  • MySerial *ps = new MySerial("/dev/ttySTM3",9600,"none",8,1,SerialRxCB);

  • int ret = ps->OpenSerial();

  • if(ret < 0)

  • {

  • perror("open serial");

  • return -1;

  • }

  • thread t(thread_task,&ret);

  • t.detach();

  • while(1)

  • {

  • ps->loop();

  • }

  • return 0;

  • }

程序中使用到了epoll,类似单片机里面的中断,可以实现异步数据的接收,程序中还使用到了c++11的线程库,米尔提供的交叉编译器版本很新,完全支持c++11的各种特性。首先在虚拟机终端执行命令,这样交叉编译环境变量就在该终端生效了:


  • . /opt/st/myir/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

可以看到CXX环境变量:

8395d188-6b1f-11ec-ad3b-dac502259ad0.png

然后执行命令进行程序的编译:


  • $CXX stm32mp1_uart_test.cpp -o uart_test -lpthread

c++11的线程库底层使用了pthread实现,因此需要加链接参数-lpthread

83a41c02-6b1f-11ec-ad3b-dac502259ad0.png

交叉编译完成后,使用scp命令将程序拷贝到开发板上执行:


  • scp qldeng@192.168.1.131:/home/qldeng/stm32mp1_uart_test/uart_test ./

复制到板子上的效果:
83add71a-6b1f-11ec-ad3b-dac502259ad0.png

最后看看实际效果吧:

83d14ce0-6b1f-11ec-ad3b-dac502259ad0.gif

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 开发板
    +关注

    关注

    25

    文章

    4429

    浏览量

    93993
收藏 人收藏

    评论

    相关推荐

    ROS系统的智能车开发-基于米尔芯驰MYD-JD9X开发板

    本篇测评电子工程世界的优秀测评者“mameng”提供。本文将介绍基于米尔电子MYD-JD9X
    的头像 发表于 01-26 08:01 347次阅读
    ROS系统的智能车<b class='flag-5'>开发</b>-基于<b class='flag-5'>米尔</b>芯驰<b class='flag-5'>MYD</b>-JD9X<b class='flag-5'>开发板</b>

    国产开发板上打造开源ThingsBoard工业网关--基于米尔芯驰MYD-JD9X开发板

    本篇测评由面包板论坛的优秀测评者“JerryZhen”提供。本文将介绍基于米尔电子MYD-JD9X开发板
    的头像 发表于 10-13 08:01 481次阅读
    国产<b class='flag-5'>开发板</b>上打造开源ThingsBoard工业网关--基于<b class='flag-5'>米尔</b>芯驰<b class='flag-5'>MYD</b>-JD9X<b class='flag-5'>开发板</b>

    如何选择米尔基于STM32MP1系列核心开发板

    适合应用在工业物联网和汽车通信领域。 而作为ST的年度官方合作伙伴,米尔电子从2019年就紧随ST的脚步,同步发行STM32MP151,157和今年首发的STM32MP135系列核心开发
    发表于 09-28 16:54

    米尔-STM32MP135开发板-入门级MPU试用】初识功能强大的米尔-STM32MP135开发板及培训课程

    157C-V3核心标注图 米尔MYD-YA157C-V3开发板标注图 [# ST官方基于米尔STM32MP135
    发表于 09-04 22:16

    米尔-STM32MP135开发板-入门级MPU试用】让米尔-STM32MP135开发板轻松跑Linux

    : STM32CubeProg、STM32CubeMX 安装米尔定制的 SDK 2、构建开发板镜像 第1步:获取源码 可以从米尔提供链接获取源码。http://down.myir-tech.com/
    发表于 09-04 21:46

    米尔基于瑞萨RZ/G2L开发板在工控领域的应用-基于SOEM的EtherCAT主站

    本文介绍【米尔MYD-YG2LX开发板】在工控领域的应用,实现基于SOEM的EtherCAT主站。开发环境基于WSL2。
    的头像 发表于 08-24 18:57 536次阅读
    <b class='flag-5'>米尔</b>基于瑞萨RZ/G2L<b class='flag-5'>开发板</b>在工控领域的应用-基于SOEM的EtherCAT主站

    米尔-STM32MP135开发板-入门级MPU试用米尔-STM32MP135开发板开发环境搭建

    UART功能接口。 米尔-STM32MP135开发板的核心简介 米尔电子,专注嵌入式处理器模块设计和研发的高新技术企业,是领先的嵌入式处
    发表于 08-17 00:07

    在多媒体应用场景下ffmpeg网络视频播放器的体验--基于米尔MYD-YG2LX开发板

    本篇测评由优秀测评者“qinyunti”提供。前言前面进行了ffmpeg的开发环境搭建以及性能测试,现在就可以进行具体的应用开发了。这一篇就以一个网络视频播放的Demo来演示基于
    的头像 发表于 08-14 09:43 458次阅读
    在多媒体应用场景下ffmpeg网络视频播放器的体验--基于<b class='flag-5'>米尔</b><b class='flag-5'>MYD</b>-YG2LX<b class='flag-5'>开发板</b>

    米尔-STM32MP135开发板-入门级MPU试用MYD-YF135开发板测评(一)

    MYD-YF135开发板米尔电子基于 STM32MP135 处理器推出的嵌入式开发板,套件由核心
    发表于 08-03 22:39

    0元试用!车规级国产芯驰D9开发板

    米尔与合作芯驰推出的新品基于D9系列应用处理器的MYC-JD9X核心板及开发板现已开放免费试用名额!!米尔准备了3块价值1199元的开发板
    的头像 发表于 07-06 10:07 549次阅读
    0元<b class='flag-5'>试用</b>!车规级国产芯驰D9<b class='flag-5'>开发板</b>

    基于iMX6ULL处理器的监控平台体验--米尔MYD-Y6ULX-V2开发板

    本篇测评电子发烧友的优秀测评者“HonestQiao”提供。点击观看视频01.评测规划米尔MYD-Y6ULX-V2
    的头像 发表于 05-25 10:49 1830次阅读
    基于iMX6ULL处理器的监控平台体验--<b class='flag-5'>米尔</b><b class='flag-5'>MYD</b>-Y6ULX-V2<b class='flag-5'>开发板</b>

    米尔MYD-YG2开发板触摸屏测试

    米尔MYD-YG2开发板测试米尔触摸屏
    的头像 发表于 05-24 13:12 29.4w次阅读

    米尔MYD-JX8MMA7开发板-ARM+FPGA架构试用体验】九、QTDome大全

    ,并查看编译结果是否成功和编译后的输出路径。 最后将编译后的文件,复制到IMX8MMA7开发板上,然后运行其代码操作方法如下: 实际运行效果: 二、米尔开发板内例程 米尔科技
    发表于 05-23 09:21

    米尔瑞萨RZ/G2L开发板-试用体验】开箱 + 开机

    感谢 感谢电子发烧友论坛、感谢米尔电子,把米尔瑞萨RZ/G2L开发板试用话动的机会给了我。最近事
    发表于 05-18 19:33

    有奖,免费开发板又双叒叕来了!米尔基于全志T113-S3开发板试用招募

    米尔再次与全志推出新品基于全志T113-S3应用处理器的MYC-YT113X核心板及开发板现已开放免费试用名额!!米尔准备了4块价值348元的开发板
    的头像 发表于 05-18 10:25 700次阅读
    有奖,免费<b class='flag-5'>开发板</b>又双叒叕来了!<b class='flag-5'>米尔</b>基于全志T113-S3<b class='flag-5'>开发板</b><b class='flag-5'>试用</b>招募