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

这篇具有很好参考价值的文章主要介绍了嵌入式Linux应用开发笔记:串口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目的

串口(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

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

应用程序

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;
}

演示

上面代码的作用是接收数据并回传,演示如下:
嵌入式Linux应用开发笔记:串口

总结

串口操作总体来说并不复杂。另外虽然串口有很多可以设置的属性,但是目前很多属性已经不怎使用了,最常见需要修改的也就波特率了。文章来源地址https://www.toymoban.com/news/detail-491323.html

设备树文件

/*
 * 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>;
	};
};

到了这里,关于嵌入式Linux应用开发笔记:串口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Azure RTOS & 嵌入式无线网络框架简化物联网应用开发

    一、Azure RTOS概述 Azure RTOS 是一个实时操作系统 (RTOS),适用于由微控制器 (MCU) 提供支持的物联网 (IoT) 和边缘设备, Azure RTOS 旨在支持高度受限设备(电池供电,并且闪存容量不到 64 KB)。简而言之,这就是一套完整的针对于物联网应用开发的带有多线程功能,中间件和桌面

    2024年02月08日
    浏览(62)
  • 【STM32嵌入式系统设计与开发】——7有源蜂鸣器应用

    STM32资料包: 百度网盘下载链接:链接:https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd=8888 提取码:8888 观察电路图,核心板PD14连接底板中的P2外接排针,将正负极接上直流电压即可持续发声,频率固定。LED的PA0连接底板的D1灯。 步骤1:复制工程模板“1_Template”重命名为“4_Active

    2024年03月21日
    浏览(68)
  • 【嵌入式系统应用开发】FPGA——HLS入门实践之led灯闪烁

    HLS(High Level Synthesis) :一款高层次综合工具。 能够将 C/C++ 或者 system C 等高级语言转化为 RTL (底层硬件描述语言)电路,降低开发时间。 提供了常见的库(例如图像处理相关的 OpenCv 库和其 它的数学库)。 可以创建IP并通过例化或者使用 BlockDesign 的方式应用到项目中。 转化原

    2024年02月05日
    浏览(63)
  • 阿里P8面试官都说太详细了,嵌入式应用开发和驱动开发的区别

    1、如何进行单元测试,如何保证App稳定 ? 参考回答: 要测试Android应用程序,通常会创建以下类型自动单元测试 本地测试 :只在本地机器JVM上运行,以最小化执行时间,这种单元测试不依赖于Android框架,或者即使有依赖,也很方便使用模拟框架来模拟依赖,以达到隔离A

    2024年04月09日
    浏览(40)
  • 使用GUI Guider工具开发嵌入式GUI应用(4)-使用image组件

    在没有使用LVGL和GUI Guider的时候,我想做一个电子相册的小应用,需要在MCU工程中集成一个小型的文件系统和图像解码组件,例如 fatfs (http://elm-chan.org/fsw/ff/00index_e.html)组件和 tjpgdec (http://elm-chan.org/fsw/tjpgd/00index.html)组件。使用GUI Guider显示图片就不需要这么麻烦,可以使

    2024年02月13日
    浏览(58)
  • 使用GUI Guider工具开发嵌入式GUI应用 (3) - 使用label组件

    本节讲述在GUI Guider中,应用各种UI的基本元素,并顺利部署到MCU的过程。在GUI Guider中使用各LVGL的组件时,将会涉及到GUI Guider的操作,以及将某些组件额外生成的源码添加到Keil工程中。至于具体产品中的UI应用,可以是这些基本UI元素的组合使用,以实现更加丰富的显示效果

    2024年02月12日
    浏览(53)
  • 【嵌入式系统应用开发】FPGA——基于HC-SR04超声波测距

    硬件 DE2-115 HC-SR04超声波传感器 软件 Quartus 18.1 使用DE2-115开发板驱动HC-SR04模块,并将所测得数据显示到开发板上的数码管。 HC-SR04 超声波测距模块可提供 2cm-400cm的非接触式距离感测功能,测距精度可达高到 3mm;模块包括超声波发射器、接收器与控制电路。图1为 HC-SR04 外观,

    2024年02月08日
    浏览(58)
  • 全国职业院校技能大赛-嵌入式系统应用开发赛项-竞赛任务书(第5套)

    目录 全国职业院校技能大赛嵌入式系统应用开发赛项 竞赛模块: 模块一 竞赛注意事项 第一模块 嵌入式系统硬件制作与驱动开发 竞赛任务书(第5套) 一、总体要求 二、竞赛任务表 竞赛模块: 模块二 竞赛注意事项 第二模块 嵌入式系统应用程序开发 竞赛任务书(第5套)

    2024年02月04日
    浏览(53)
  • 全国职业院校技能大赛-嵌入式系统应用开发赛项-竞赛任务书(第9套)

    目录 全国职业院校技能大赛嵌入式系统应用开发赛项 竞赛模块: 模块一 竞赛注意事项 第一模块 嵌入式系统硬件制作与驱动开发 竞赛任务书(第9套) 一、总体要求 二、竞赛任务表 竞赛模块: 模块二 竞赛注意事项 第二模块 嵌入式系统应用程序开发 竞赛任务书(第9套)

    2024年02月07日
    浏览(54)
  • 使用GUI Guider工具在MCU上开发嵌入式GUI应用 (1) - GUI Guider简介及安装

    受限于每篇文章最多只能贴9张图的限制,这个教程被拆分成了多篇文章连载发布,完整目录结构如下图x所示。后续会发布完整教程的pdf文件,敬请期待。 图x 完整教程文档的目录 LVGL是一个开源免费(MIT许可)的嵌入式GUI组件(https://lvgl.io/),支持触摸屏操作,移植简单方

    2024年02月13日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包