嵌入式Linux应用开发笔记:串口

2023-10-27

目的

串口(UART)是嵌入式设备中比较常用的功能。这篇文章将记录下应用程序中串口操作相关内容。

这篇文章中内容均在下面的开发板上进行测试:
《新唐NUC980使用记录:自制开发板(基于NUC980DK61YC)》

这篇文章是在下面文章基础上进行的:
《新唐NUC980使用记录(5.10.y内核):在用户应用中使用GPIO》

基础说明

Linux中应用程序对于串口的使用可以参考下面文章: https://digilander.libero.it/robang/rubrica/serial.htm
https://blog.csdn.net/qq_37932504/article/details/121125906

这里简单介绍下相关内容。Linux中应用程序对于串口的使用基本上也就是文件操作,使用 open / write / read 等方法。此外通常使用前需要通过 ioctl 方法来获取与设置串口的波特率、数据位、停止位、流控制等。对于串口而言部分设置在 ioctl 方法之上封装了一些函数,可以方便的进行操作。

串口的设置都集中在下面的结构体中:

struct termio
{
	unsigned short c_iflag; /* 输入模式标志 */
	unsigned short c_oflag; /* 输出模式标志 */
	unsigned short c_cflag; /* 控制模式标志*/
	unsigned short c_lflag; /*本地模式标志 */
	unsigned char c_line; /* 行规程标志 */
	unsigned char c_cc[NCC]; /* 控制字符标志 */
};

结构体中具体内容与设置可以参考上面文章。

开发准备

设备树

首先需要调整设备树来启用串口:

# cd ~/nuc980-sdk/NUC980-linux-5.10.y/
gedit arch/arm/boot/dts/nuc980-dev-v1.0.dts

这里启用了 uart1

uart1: serial@b0071000 {
	status = "okay";
};

根据 nuc980.dtsi 文件的中的定义 uart1 默认使用引脚为 PA0 - RXDPA1 - TXD

# 设置编译工具链
export ARCH=arm; export CROSS_COMPILE=arm-buildroot-linux-gnueabi-
export PATH=$PATH:/home/nx/nuc980-sdk/buildroot-2023.02/output/host/bin

# 编译生成设备树文件
make dtbs

# 编译完成后拷贝到电脑上再拷贝到SD卡中
# sudo cp arch/arm/boot/dts/nuc980-dev-v1.0.dtb /media/sf_common/

# 我这里开发环境和开发板在同一局域网中,所以可以直接通过网络将dtb文件拷贝到开发板上
# 在开发板中挂载boot分区
# mount /dev/mmcblk0p1 /mnt/
# 在ubuntu中使用scp命令拷贝dtb文件到开发板上
# scp arch/arm/boot/dts/nuc980-dev-v1.0.dtb root@192.168.31.142:/mnt/
# 拷贝完成后重启开发板即可测试
# reboot

加载新的设备树之后就可以测试新串口的功能了,使用外部的串口模块连接开发板和电脑:
在这里插入图片描述
可以看到使用默认波特率发送数据其实很简单,但是实际的使用过程中往往还需要修改串口设置以及接收数据等,所以就需要编写应用程序来处理。

应用程序

cd ~

# 创建目应用程序录并进入
mkdir -p ~/nuc980-sdk/apps/uart
cd ~/nuc980-sdk/apps/uart

# 创建应用程序文件
gedit uart_test.c

# 应用程序代码见下面章节

# 设置编译工具链
export ARCH=arm; export CROSS_COMPILE=arm-buildroot-linux-gnueabi-
export PATH=$PATH:/home/nx/nuc980-sdk/buildroot-2023.02/output/host/bin

# 编译生成目标应用程序
arm-linux-gcc -o uart_test uart_test.c

# 编译完成后拷贝到电脑上再拷贝到SD卡中
# sudo cp uart_test /media/sf_common/

# 我这里开发环境和开发板在同一局域网中,所以可以直接通过网络将文件拷贝到开发板上
# 在ubuntu中使用scp命令拷贝文件到开发板上
# scp uart_test root@192.168.31.142:/root/

应用程序与演示

代码

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

int main(int argc, char **argv)
{
    int fd, ret;
    struct termios opt;
    char c;

	if (argc != 2)
	{
		printf("Usage: uart_test </dev/ttyX>\n");
		return -1;
	}

    /* 打开串口 */
    fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1)
    {
        printf("NX applog: can not open %s\n", argv[1]);
        return -1;
    }
    fcntl(fd, F_SETFL, 0); // 读取使用阻塞方式

    /* 设置串口属性 */
    // tcgetattr(fd, &opt); // 获取现有串口属性
    bzero(&opt, sizeof(opt)); // 以0填充结构体

    cfsetspeed(&opt, B115200); // 设置串口波特率

    opt.c_cflag |= CS8; // 8位数据位
    // opt.c_cflag &= ~PARENB; // 没有校验位
    // opt.c_cflag &= ~CSTOPB; // 1位停止位

    opt.c_cflag |= CREAD | CLOCAL;

	opt.c_cc[VMIN] = 1;	// 每次读取至少读到一个字节
	opt.c_cc[VTIME] = 0; // 读取操作不会超时

    tcflush(fd, TCIOFLUSH); // 清空当前输入/输出缓冲区数据

    ret = tcsetattr(fd, TCSANOW, &opt); // 使能串口设置
    if (ret != 0)
	{
		printf("NX applog: port set error\n");
		return -1;
	}

    /* 数据收发测试 */
    while (1) 
    {
        read(fd, &c, 1); // 
        printf("NX applog: read 0x%02x %c\n", c, c);
        write(fd, &c, 1);
    }

    close(fd);

    return 0;
}

演示

上面代码的作用是接收数据并回传,演示如下:
在这里插入图片描述

总结

串口操作总体来说并不复杂。另外虽然串口有很多可以设置的属性,但是目前很多属性已经不怎使用了,最常见需要修改的也就波特率了。

设备树文件

/*
 * Device Tree Source for NUC980 DEV board
 *
 * Copyright (C) 2018 Nuvoton Technology Corp.
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */
/dts-v1/;

#include "nuc980.dtsi"

/ {
	model = "Nuvoton NUC980 DEV V1.0";
	compatible = "nuvoton,nuc980-dev-v1.0", "nuvoton,nuc980";

	chosen {
		bootargs = "console=ttyS0,115200n8 noinitrd rootfstype=ext4 root=/dev/mmcblk0p2 rw rootwait mem=64M";
	};

	apb {
		uart1: serial@b0071000 {
			status = "okay";
		};

		uart2: serial@b0072000 {
			status = "disabled";
		};

		uart3: serial@b0073000 {
			status = "disabled";
		};

		uart4: serial@b0074000 {
			status = "disabled";
		};

		uart5: serial@b0075000 {
			status = "disabled";
		};

		uart6: serial@b0076000 {
			status = "disabled";
		};

		uart7: serial@b0077000 {
			status = "disabled";
		};

		uart8: serial@b0078000 {
			status = "disabled";
		};

		uart9: serial@b0079000 {
			status = "disabled";
		};

		can0: can@b00a0000 {
			status = "disabled";
		};

		can1: can@b00a1000 {
			status = "disabled";
		};

		rtc: rtc@b0041000 {
			status = "disabled";
		};

		gpio: gpio@b0004000 {
			pinctrl-0 = <>;
			eint2-config = <0 0 0>;
			eint3-config = <0 0 0>;
		};

		nadc: nadc@b0043000 {
			status = "disabled";
		};

		pwm0: pwm@b0058000 {
			status = "disabled";
		};

		pwm1: pwm@b0059000 {
			status = "disabled";
		};


		etimer0: etimer0@b0050000 {
			status = "disabled";
		};

		etimer1: etimer1@b0050100 {
			status = "disabled";
		};

		etimer2: etimer2@b0051000 {
			status = "disabled";
		};

		etimer3: etimer3@b0051100 {
			status = "disabled";
		};

		i2c0: i2c0@b0080000 {
			status = "disabled";
		};

		i2c1: i2c1@b0081000 {
			status = "disabled";
			pinctrl-0 = <&pinctrl_i2c1_PB>;
		};


		i2c2: i2c2@b0082000 {
			status = "disabled";
			pinctrl-0 = <&pinctrl_i2c2_PB>;
		};

	};

	ahb {

		usbh_ehci@b0015000 {
			pinctrl-0 = <>; /*disable PWREN and OVC*/
			ov_active = <1>;/*disable PWREN and OVC*/
			status = "okay";
		};
		usbh_ohci@b0017000{
			status = "okay";
		};

		usbdev@b0016000 {
			status = "okay";
		};

		fmi@b0019000 {
			status = "disabled";
		};

		sdh@b0018000 {
			status = "okay";
		};

		emac0@b0012000 {
			status = "okay";
		};
		emac1@b0022000 {
			status = "disabled";
		};
		ccap0@b0024000 {
			status = "disabled";
		};
		i2c_gpio0: i2c-gpio-0 {
			status = "disabled";
		};
		ccap1@b0014000 {
			status = "disabled";
		};
		i2c_gpio1: i2c-gpio-1 {
			status = "disabled";
		};
		dma@b0008000 {
			status = "okay";
		};

		i2s: i2s@b0020000 {
			status = "disabled";
		};

		i2s_pcm: i2s_pcm {
			status = "disabled";
		};

		sound {
			compatible = "nuvoton,nuc980-audio";
			i2s-controller = <&i2s>;
			i2s-platform = <&i2s_pcm>;
			status = "disabled";
		};
		ebi: ebi@b0010000 {
			status = "disabled";
		};
	};

	nx_node@0 {
		compatible = "nx_dts_node";
		str = "Naisu 233!";
		num = <0x00000000 0x00000020>;
	};
	
	nx_node@1 {
		compatible = "nx_dts_node";
		str = "Hello Naisu!";
		num = <0x000000 0x00000040>;
	};
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌入式Linux应用开发笔记:串口 的相关文章

  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • 设置 Apache POI 的路径

    我想创建 Excel 文件并使用 java 程序在该文件中写入数据 That is here http www techbrainwave com p 554我在 java 文件所在的位置提取了 Apache POI 并将该路径包含在路径变
  • 如何使用 sed 仅删除双空行?

    我找到了这个问题和答案 https stackoverflow com questions 4651591 howto use sed to remove only triple empty lines关于如何删除三重空行 但是 我只需要对
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • Godaddy 托管上的 CakePHP 控制台

    我一直在努力让我的 CakePHP 网站在 Godaddy 网格托管 帐户上运行 我的蛋糕应用程序设置是从帐户的子目录托管的 并且可以通过子域访问 我必须调整我的 htaccess 文件才能使其正常工作 现在我需要让 CakePHP 控制台
  • 为什么我收到的数据包数据大小大于mss?

    我在两台 PC 上使用 ifconfig ethX mtu 300 修改了 MTU 并使用 netperf 测试网络 我用 WireShark 嗅探了 SYN 数据包中的 MSS 260 但我得到了一些大于 260 的数据包 为什么 嗅探器
  • Unix 命令列出包含字符串但*不*包含另一个字符串的文件

    如何递归查看包含一个字符串且不包含另一个字符串的文件列表 另外 我的意思是评估文件的文本 而不是文件名 结论 根据评论 我最终使用了 find name html exec grep lR base maps xargs grep L ba
  • awk 子串单个字符

    这是columns txt aaa bbb 3 ccc ddd 2 eee fff 1 3 3 g 3 hhh i jjj 3 kkk ll 3 mm nn oo 3 我可以找到第二列以 b 开头的行 awk if substr 2 1 1
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 创建 jar 文件 - 保留文件权限

    我想知道如何创建一个保留其内容的文件权限的 jar 文件 我将源代码和可执行文件打包在一个 jar 文件中 该文件将在使用前提取 人们应该能够通过运行批处理 shell 脚本文件立即运行示例和演示 然后他们应该能够修改源代码并重新编译所有内
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • 抑制 makefile 中命令调用的回显?

    我为一个作业编写了一个程序 该程序应该将其输出打印到标准输出 分配规范需要创建一个 Makefile 当调用它时make run gt outputFile应该运行该程序并将输出写入一个文件 该文件的 SHA1 指纹与规范中给出的指纹相同
  • 如何通过替换为空页映射来取消映射 mmap 文件

    Linux 用户空间有没有办法用空页面 映射自 dev null 或者可能是一个空页面 重复映射到从文件映射的页面的顶部 对于上下文 我想找到这个 JDK bug 的修复 https bugs openjdk java net browse
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 如何使用 xterm.js 创建基于 Web 的终端以 ssh 进入本地网络上的系统

    我偶然发现了这个很棒的图书馆xterm js https xtermjs org 这也是 Visual Studio Code 终端的基础 我有一个非常普遍的问题 我想通过基于网络的终端 不在网络中 可能位于 aws 服务器上 访问本地网络
  • 应用程序无缘无故地被杀死。怀疑 BSS 高。如何调试呢?

    我已经在CentOs6 6中成功运行我的应用程序 最近 硬件 主板和内存 更新了 我的应用程序现在毫无理由地被杀死 root localhost PktBlaster PktBlaster Killed 文件和 ldd 输出 root lo
  • 如何禁用 GNOME 桌面屏幕锁定? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何阻止 GNOME 桌面在几分钟空闲时间后锁定屏幕 我已经尝试过官方手册了在红帽 https access redhat com doc
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 为什么 Linux perf 使用事件 l1d.replacement 来处理 x86 上的“L1 dcache misses”?

    在英特尔 x86 上 Linux用途 https stackoverflow com a 52172985 149138事件l1d replacements来实施其L1 dcache load misses event 该事件定义如下 计数
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C

随机推荐

  • TDR土壤水分检测传感器方案设计

    1 TDR土壤水分检测传感器方案 TDR 时域反射 法是介电测量中的高速测量技术 以 Feidegg 1969 等人对许多液体介电特性的研究为基础而发展起来的 最初被用来定位通讯电缆的缺陷 TDR 是一个类似于雷达系统的系统 有较强的独立性
  • chatgpt赋能python:如何把Python添加到Path

    如何把Python添加到Path Python是一种流行的编程语言 但是如果您想在命令行或终端中使用它 您需要将它添加到您的环境变量中 这篇文章将向您展示如何将Python添加到PATH中 以便您可以在任何地方使用Python 什么是PAT
  • 青少年编程python一级真题_青少年编程能力等级测评试卷二及答案 Python编程(一级)...

    青少年编程能力等级测评试卷 Python编程 一级 考试时间90分钟 满分100分 一 单项选择题 共20题 每题2 5分 共50分 1 运行下方代码段 输出是6 则输入的可能是 C a eval input print a A 8 2B
  • 《数据库系统概念》11-扩展的E-R特性

    虽然基本的E R特性可以应对大部分数据库建模 但为了使用方便 也提供扩展的E R特性一 特化Specialization有时一个实体集会保护若干子集 这些子集各自具有不同的属性 比如person可以包含employee和student子集
  • vsCode 配置 html 文件警告

    vsCode 配置 html 文件警告 问题描述 IDE vsCode 会默认根据自己的规则来检测 html 文件书写格式 但是在实际项目中模板的格式可能会有与规则有些不同 比如 第一行必须为声明 属性不能为空等 本人有点偏强迫症 要找办法
  • 创新造型,引领未来——探索OLED透明屏造型的创新与应用

    OLED透明屏作为一项颠覆性的显示技术 正在以其卓越的透明度和灵活性在各个行业中崭露头角 而在OLED透明屏的应用中 造型设计的创新成为了吸引消费者和提升用户体验的重要因素 一 OLED透明屏的特点 OLED透明屏采用有机发光二极管技术 其
  • python加载dll_C#初识 *.dll文件及动手编写简单应用

    DLL的概念 DLL Dynamic Link Library 文件为动态链接库文件 又称 应用程序拓展 是软件文件类型 在Windows中 许多应用程序并不是一个完整的可执行文件 它们被分割成一些相对独立的动态链接库 即DLL文件 放置于
  • SGD和Adam(转载)

    https blog csdn net weixin 42398658 article details 84525917 另在一篇文章中 我们介绍了随机梯度下降的细节以及如何解决陷入局部最小值或鞍点等问题 在这篇文章中 我们看看另一个困扰神
  • Unity3D编辑器扩展——EditorWindow交互响应事件

    重点 需要在OnGUI方法里监听事件 Unity的编辑器界面中由这么一些事件 EventType MouseDown 鼠标按下 MouseUp 鼠标抬起 MouseDrag 鼠标拖动 KeyDown 按键按下 KeyUp 按键抬起 Scro
  • js sum函数

    addnum function num1 num2 const num1Digits num1 toString split 1 length const num2Digits num2 toString split 1 length co
  • Qt新建项目No valid kits found解决思路

    第一次用Qt Creator创建Project时 进入Kit Selection窗口后 会提示No Valid kits found Please add a kit in the options
  • web性能测试基本性能指标

    文章出处 https blog csdn net qiguiting article details 11584397 Web性能测试的部分概况一般来说 一个Web请求的处理包括以下步骤 1 客户发送请求 2 web server接受到请求
  • Source Insight 4.0常用设置

    1 删除某一个或多个无用的project 历史project 用十六进制编辑器打开 我的文档 Source Insight 4 0 Projects project list sidb 文件 找到你要删除的项目路径及名称字符串 用0替换相关
  • TortoiseGit实现分支的新增、合并、删除详细教程

    分支的新增 合并 删除 关于git分支的操作 内容较多 所以从上篇博客 Windows下TortoiseGit客户端安装 中单独提取了出来 16 创建分支 Create Branch 关于Git Branch 在实际的项目开发过程中 这个非
  • ROS学习笔记(一)

    一 ROS安装与测试 Ubuntu和ROS版本的对应关系 网上教程很多 本人主要参考以下几篇 官网教程 全英文 ROS安装教程 ROS kinetic 超详细安装教程 安装过程中报错以及参考文章 均能有效解决 安装完ROS后 初始化rosd
  • 总结Pyinstaller的坑及终极解决方法

    一 首先要有个稳定环境 下面是博主经测试的觉得坑比较少的环境搭配 Python3 4 PyQt5 4 Pyinstaller3 2 1 Python3 5 PyQt5 8 Pyinstaller3 2 1 二 Pyinstaller遇到坑没
  • el-table表头无法居中显示(使用了cell-style和header-cell-style属性,也没有效果)----解决办法

    解决办法 cell style和header cell style属性要写在style前面
  • Windows Server 2016组策略限制用户登录到本机

    打开组策略 编辑 设置允许本地登录 拒绝本地登录 刷新组策略
  • 【EI会议征稿】第三届机械自动化与电子信息工程国际学术会议(MAEIE 2023)

    第三届机械自动化与电子信息工程国际学术会议 MAEIE 2023 第三届机械自动化与电子信息工程国际学术会议 MAEIE 2023 将于2023年12月15 17日在江苏南京举行 本会议通过与业内众多平台 社会各团体协力 聚集机械自动化 电
  • 嵌入式Linux应用开发笔记:串口

    文章目录 目的 基础说明 开发准备 设备树 应用程序 应用程序与演示 代码 演示 总结 设备树文件 目的 串口 UART 是嵌入式设备中比较常用的功能 这篇文章将记录下应用程序中串口操作相关内容 这篇文章中内容均在下面的开发板上进行测试 新