linux 中的串口驱动
1.流程描述
打开串口设备:首先需要打开串口设备文件,通常是/dev/ttyX(如/dev/ttyUSB0,/dev/ttyS0等)。可以使用open()系统调用打开串口设备文件,获取一个文件描述符。
配置串口属性:打开串口后,需要配置串口的属性,例如波特率、数据位、奇偶校验、停止位等。可以使用termios库来设置串口属性。
读写数据:串口配置完成后,可以使用read()和write()系统调用来进行串口数据的读取和写入。
此外,还可以通过select()或poll()等系统调用进行多路复用,实现同时监听串口和其他文件描述符上的事件
2.open函数标志位的含义
在打开串口设备时,可以使用一些标志位(flags)来设置打开模式和行为。下面是常见的一些标志位及其含义:
-
O_RDWR:以读写模式打开设备。允许读取和写入设备数据。 -
O_NOCTTY:如果设备是终端设备(例如串口),不将它作为进程的控制终端。这通常用于防止串口设备接管终端特性(如终端窗口)。一般在打开串口设备时使用这个标志位。 -
O_NDELAY(也叫O_NONBLOCK):将文件描述符设置为非阻塞模式。在非阻塞模式下,读取和写入文件描述符将立即返回。如果没有数据可读取,读取操作将返回-1,并将errno设置为EAGAIN。如果写入操作无法立即完成,将返回-1,并将errno设置为EAGAIN。不建议在打开串口时使用此标志位,因为在阻塞式读取串口数据时,我们希望等待数据的到达。 -
O_RDONLY:以只读模式打开设备。只允许读取设备数据。 -
O_WRONLY:以只写模式打开设备。只允许写入设备数据。 -
O_CREAT:如果设备不存在,创建设备。在使用此标志位时,需要提供另外的参数,如文件权限。 -
O_EXCL:与O_CREAT一起使用,确保创建新设备而不是打开现有设备。 -
O_APPEND:以追加模式打开设备。每次写入操作都将数据追加到文件末尾。 -
O_TRUNC:打开设备之前,先将其内容截断为零长度。
3.实现
/********************************************************************************* @file bsp_uart.c* @author cj* @version V1.0* @date 2019/4* @brief******************************************************************************* @attention*******************************************************************************/#include "bsp_uart.h"
#include "typedef.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>static UartStatus initComm(const char *ttyDir, const int stop, const unsigned speed)
{UartStatus uartStatus;uartStatus.fd = -1;uartStatus.isEnabled = false;int retry = 60;uartStatus.fd = open(ttyDir, O_RDWR | O_NOCTTY /*| O_NDELAY*/);if (uartStatus.fd < 0){CJdebug("can not open this driver\n");return uartStatus;}while (lockf(uartStatus.fd, F_TLOCK, 0) < 0){sleep(1);retry--;if (retry <= 0){CJdebug("Devcie %s locked.\n", ttyDir);close(uartStatus.fd);return uartStatus;}}unsigned currentSpeed = B9600;switch (speed){case 9600:currentSpeed = B9600;break;case 38400:currentSpeed = B38400;break;case 57600:currentSpeed = B57600;break;case 115200:currentSpeed = B115200;break;default:CJdebug("speed error\n");return uartStatus;}struct termios Opt;tcgetattr(uartStatus.fd, &Opt);cfsetispeed(&Opt, currentSpeed);cfsetospeed(&Opt, currentSpeed);tcsetattr(uartStatus.fd, TCSANOW, &Opt);tcflush(uartStatus.fd, TCIOFLUSH);tcgetattr(uartStatus.fd, &Opt);/* Set data bit 8bit */Opt.c_cflag &= ~CSIZE;Opt.c_cflag |= CS8;Opt.c_cflag |= IXON | IXOFF | IXANY;/* Set parity bit: None parity bit */Opt.c_cflag &= ~PARENB;/* stop bit */switch (stop){case 1:Opt.c_cflag &= ~CSTOPB;break;case 2:Opt.c_cflag |= CSTOPB;break;default:Opt.c_cflag &= ~CSTOPB;break;}Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);Opt.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);Opt.c_oflag &= ~OPOST;/* set timeout in deciseconds for non-canonical read */Opt.c_cc[VTIME] = 150; //over timeOpt.c_cc[VMIN] = 0; //DATA_LEN;if (tcsetattr(uartStatus.fd, TCSANOW, &Opt) < 0){perror(ttyDir);close(uartStatus.fd);return uartStatus;}tcflush(uartStatus.fd, TCIOFLUSH);uartStatus.isEnabled = true;return uartStatus;
}/*** @brief Uart_init* @param speed* @param stop* @param name* @return*/
UartStatus uartInit(const unsigned speed, const int stop, const char *name)
{char dev[64] = {0};memset(dev, 0, sizeof(dev));sprintf(dev, "/dev/%s", name);UartStatus status = initComm(dev, stop, speed);return status;
}int uart_readComm(UartStatus *uart, char *data, int dataLen)
{return read(uart->fd, data, dataLen);
}bool uart_writeComm(UartStatus *uart, unsigned char *data, int dataLen)
{if(write(uart->fd, data, dataLen) < dataLen){CJdebug("uartComm write error !\n");return false;}return true;
}
#ifndef BSP_UART_H
#define BSP_UART_H#ifdef __cplusplus
extern "C" {
#endif#include "typedef.h"typedef struct _UartStatus
{int fd;bool isEnabled;
} UartStatus;UartStatus uartInit(const unsigned speed, const int stop, const char *name);
bool uart_writeComm(UartStatus *uart, unsigned char *data, int dataLen);
int uart_readComm(UartStatus *uart, char *data, int dataLen);#ifdef __cplusplus
}
#endif#endif
相关文章:
linux 中的串口驱动
1.流程描述 打开串口设备:首先需要打开串口设备文件,通常是/dev/ttyX(如/dev/ttyUSB0,/dev/ttyS0等)。可以使用open()系统调用打开串口设备文件,获取一个文件描述符。 配置串口属性:打开…...
棱镜七彩正式加入龙蜥社区安全联盟(OASA)
近日,龙蜥社区安全联盟(OASA)正式成立,棱镜七彩成为该联盟成员单位。 龙蜥社区安全联盟是促进产业合作的非营利组织,致力于打造中立开放、聚焦操作系统信息安全的交流平台,推进龙蜥社区乃至整个产业安全生态…...
STM32——STM32F401x系列标准库的下载+环境搭建+建工程步骤(更完整)
文章目录 标准库的下载环境搭建建工程最后的话 标准库的下载 1.STM32标准库的官网下载网站https://www.st.com/content/st_com/en.html 2. 3. 4. 5. 6. 7.点击之后下滑 8.选择自己需要的版本下载 环境搭建建工程 大致步骤同之前我写的一篇STM32——建工程差不多࿰…...
基于ArcGIS土地利用量化人类活动的分析及模型构建
ArcGIS产品线为用户提供一个可伸缩的,全面的GIS平台。ArcObjects包含了许多的可编程组件,从细粒度的对象(例如单个的几何对象)到粗粒度的对象(例如与现有ArcMap文档交互的地图对象)涉及面极广,这…...
特性Attribute
本文只提及常用的特性,更多特性请查看官方文档。 AddComponentMenu - Unity 脚本 API 常用特性 AddComponentMenu 添加组件菜单 使用 AddComponentMenu 属性可在“Component”菜单中的任意位置放置脚本,而不仅是“Component > Scripts”菜单。 使用…...
pyqt5, 如何在窗口上显示10个点地循环进度条。
要在PyQt5窗口上显示从1个点逐渐增加到10个点,然后周而复始地循环,可以使用PyQt5的图形绘制功能和定时器来实现。以下是一个简单的例子: import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QPainter, …...
VM里ubuntu虚拟无法启动
开始认为是VM的设置问题,按照这个链接关闭的3d加速图像显示,以及那个cmd命令,但是没什么用。 后来看到一篇博文和我的错误一模一样,都是只有一个光标在闪。于是按照这个操作进行了一遍,发现是home文件满了,…...
信息学奥赛一本通——1156:求π的值
文章目录 题目【题目描述】【输入】【输出】【输入样例】【输出样例】 AC代码 题目 【题目描述】 根据公式: a r c t a n x ( x ) x − x 3 3 x 5 5 − x 7 7 ⋯ arctanx\left ( x \right ) x- \frac{x^3}{3} \frac{x^5}{5}-\frac{x^7}{7} \cdots arctanx(x…...
BI报表工具有哪些作用?奥威BI全面剖析数据
BI报表工具有哪些作用?主要的作用是通过整合多业务来源数据,全面分析挖掘数据,来帮助企业实现数据化运营、支持智能决策、实现数据资产沉淀和增值、进行数据挖掘和预测分析、提高数据可读性和数据可视化程度等,从而提高企业的竞争…...
【云原生K8s】初识Kubernetes的理论基础
K8S由google的Borg系统(博格系统,google内部使用的大规模容器编排工具)作为原型,后经GO语言延用Borg的思路重写并捐献给CNCF基金会开源。 云原生基金会(CNCF)于2015年12月成立,隶属于Linux基金会。CNCF孵化的第一个项目…...
javaAPI(三):jdk8之前的日期API
jdk 8之前的日期时间API 1、System类中currentTimeMillis()。 2、 java.util.Date和子类java.sql.Date。 3、SimpleDateFormat 4、Calendar System返回时间戳 long time System.currentTimeMillis();System.out.println(time);Date类 java.util.Date类 实例化 构造器一&a…...
驱动开发(中断)
头文件: #ifndef __LED_H__ #define __LED_H__#define PHY_LED1_MODER 0X50006000 #define PHY_LED1_ODR 0X50006014 #define PHY_LED1_RCC 0X50000A28#define PHY_LED2_MODER 0X50007000 #define PHY_LED2_ODR 0X50007014 #define PHY_LED2_RCC 0X50000A28#def…...
TypeScript最新语法总结
注意注意!!!本文介绍的是最新的TypeScript4的重要语法 第一部分:TypeScript的简介 TypeScript 是由微软开发的一款开源的编程语言,TypeScript 是 Javascript 的超集,遵循最新的 ES6、ES5 规范,…...
sentinel组件
目录 定义 4.加SentinelResource,blockHander是超过阈值之后执行的函数 5.设置阈值 6.springboot集成sentinel 定义 1.sentinel知道当前流量大小,在浏览器和后端之间加sentinel控制流量,避免大批量的瞬时请求都达到服务上,将服务压垮 2.…...
26 MFC序列化函数
文章目录 Serialize对于存储文件的序列化 Serialize Serialize 是一个在 MFC (Microsoft Foundation Classes) 中常用的函数或概念。它用于将对象的数据进行序列化和反序列化,便于在不同的场景中保存、传输和恢复对象的状态。 在 MFC 中,Serialize 函数…...
GC 深入(小白,对gc有一个进一步的了解)
垃圾回收器的搭配 一般固定 一般这年轻代垃圾回收器,老年代垃圾回收器,如上图搭配着使用 1.8呢默认就是最后边那哥俩 jvm调优 一个就是增加吞吐量 一个就是减少STW的时间。 三色标记算法(理解根可达算法) 并发的可达性分析 有…...
CSS前端面试
文章目录 rem、em、vh、px各自代表的含义?盒模型poison 定位属性flex属性让元素水平垂直居中页面适配的方法有哪些 rem、em、vh、px各自代表的含义? px:绝对单位,页面按精确像素展示 em:相对单位,基准点为…...
VB+SQL餐饮管理系统设计与实现
第一章 前言 1.1 绪论 当今世界已进入了在计算机信息管理领域中激烈竞争的时代,应用计算机已经变得十分普遍了,如同我们离不开的自行车、汽车一样。我们应该承认,谁掌握的知识多,信息量大,信息处理速度快,批量大,谁的效率就高,谁就能够在各种竞争中立于不败之地。随着…...
React入门学习笔记2
jsx语法规则 定义虚拟DOM时,不要写引号。标签中混入JS表达式时要用{ }。样式的类名指定不要用class,要用className。内联样式,要用style{{key:value}}的形式去写。只有一个根标签标签必须闭合标签首字母 )若小写字母开头…...
Palo Alto Networks® PA-220R 下一代防火墙 确保恶劣工况下的网络安全
一、主要安全功能 1、每时每刻在各端口对全部应用进行分类 • 将 App-ID 用于工业协议和应用,例如 Modbus、 DNP3、IEC 60870-5-104、Siemens S7、OSIsoft PI 等。 • 不论采用何种端口、SSL/SSH 加密或者其他规避技术,都会识别应用。 • 使用…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
网页端 js 读取发票里的二维码信息(图片和PDF格式)
起因 为了实现在报销流程中,发票不能重用的限制,发票上传后,希望能读出发票号,并记录发票号已用,下次不再可用于报销。 基于上面的需求,研究了OCR 的方式和读PDF的方式,实际是可行的ÿ…...
使用python进行图像处理—图像变换(6)
图像变换是指改变图像的几何形状或空间位置的操作。常见的几何变换包括平移、旋转、缩放、剪切(shear)以及更复杂的仿射变换和透视变换。这些变换在图像配准、图像校正、创建特效等场景中非常有用。 6.1仿射变换(Affine Transformation) 仿射变换是一种…...
SpringCloud——Nacos
1、核心功能: 服务注册与发现: 服务实例可动态注入到Nacos中,消费者通过服务名发现可用实例。 // 启用EnableDiscoveryClient注解启用Nacos SpringBootApplication EnableDiscoveryClient public class UserServiceApplication {public st…...
