OrangePi Zero 3学习笔记(Android篇)3 - 串口
目录
1. 找到串口号
2. 修改串口权限
3. 串口类
3.1 serialport.hpp
3.2 serialport.cpp
3.2.1 构造函数
3.2.2 Open函数
3.2.3 Close函数
3.2.4 Write函数
3.2.5 Read函数
3.2.6 SetFlowCtrl函数
4. 测试程序
5. 编译
6. 运行验证
除了默认的UART用于shell,Zero 3的24pin接口还有一路UART5:
将这个脚用线短路起来测试,即红色排针(2个5V接口)那排排针往下数4-5脚短路。
1. 找到串口号
可以在shell中运行命令:
1|apollo-p2:/ $ ls -l /dev/tty*
查看系统本身的串口信息:
crw-rw-rw- 1 root root 5, 0 1970-01-01 08:00 /dev/tty
crw------- 1 root root 247, 0 1970-01-01 08:00 /dev/ttyAS0
crw-rw---- 1 bluetooth net_bt_admin 247, 1 1970-01-01 08:00 /dev/ttyAS1
crw------- 1 root root 247, 5 1970-01-01 08:00 /dev/ttyAS5
crw-rw---- 1 bluetooth net_bt_admin 236, 0 2023-08-10 23:01 /dev/ttyBT0
crw------- 1 root root 236, 1 1970-01-01 08:00 /dev/ttyBT1
crw------- 1 root root 4, 64 1970-01-01 08:00 /dev/ttyS0
crw------- 1 root root 4, 65 1970-01-01 08:00 /dev/ttyS1
crw------- 1 root root 4, 66 1970-01-01 08:00 /dev/ttyS2
crw------- 1 root root 4, 67 1970-01-01 08:00 /dev/ttyS3
从原理图上看,AS1对应UART1,标识也是bluetooth
猜测ttyAS5对应UART5,不过尝试读写ttyAS5提示权限不够。
apollo-p2:/ $ whoami
shell
apollo-p2:/ $ echo hello >/dev/ttyAS5
/system/bin/sh: can't create /dev/ttyAS5: Permission denied
1|apollo-p2:/ $ echo hello >/dev/tty
hello
修改权限也不行
127|apollo-p2:/ $ chmod 666 /dev/ttyAS5
chmod: chmod '/dev/ttyAS5' to 0666: Operation not permitted
2. 修改串口权限
找到文件longan/kernel/linux-5.4/scripts/dtc/include-prefixes/arm64/sunxi/sun50iw9.dtsi
serial0 = &uart0;serial1 = &uart1;serial2 = &uart2;serial3 = &uart3;serial4 = &uart4;serial5 = &uart5;
可以看到实际配置了6个Uart。说明不是这里配置。
进入Ubuntu文件系统,进入longan/kernel/linux-5.4文件夹,执行
make menuconfig
在Device Drivers找一圈也没有找到配置。
尝试SELinux方式修改权限。
在device/softwinner/apollo/common/sepolicy/public/file_contexts添加:
/dev/ttyAS5 u:object_r:ttyAS5_device:s0
这样改也不行。
在device/softwinner/apollo/common/system/init.sun50iw9p1.rc中添加修改权限命令:
on post-fs-data# create file for audio dump datamkdir /data/vendor/hardware/audio_d 0777 audio audiomkdir /data/audio_d 0777 media mediachown system system /dev/nsichmod 0660 /dev/nsichmod 0755 /product/bin/HelloWorldchmod 0666 /dev/ttyAS5
apollo-p2:/ $ ls -l /dev/tty*
crw-rw-rw- 1 root root 5, 0 1970-01-01 08:00 /dev/tty
crw------- 1 root root 247, 0 1970-01-01 08:00 /dev/ttyAS0
crw-rw---- 1 bluetooth net_bt_admin 247, 1 1970-01-01 08:00 /dev/ttyAS1
crw-rw-rw- 1 root root 247, 5 1970-01-01 08:00 /dev/ttyAS5
crw-rw---- 1 bluetooth net_bt_admin 236, 0 2023-08-10 23:01 /dev/ttyBT0
crw------- 1 root root 236, 1 1970-01-01 08:00 /dev/ttyBT1
crw------- 1 root root 4, 64 1970-01-01 08:00 /dev/ttyS0
crw------- 1 root root 4, 65 1970-01-01 08:00 /dev/ttyS1
crw------- 1 root root 4, 66 1970-01-01 08:00 /dev/ttyS2
crw------- 1 root root 4, 67 1970-01-01 08:00 /dev/ttyS3
可以看到已经改动了。
apollo-p2:/ $ echo hello </dev/ttyAS5
hello
3. 串口类
参考上一节helloworld的方式(device/softwinner/apollo/apollo-p2)添加SerialPort的文件夹,在这个文件夹里面新增2个文件:serialport.cpp和serialport.hpp。
3.1 serialport.hpp
需要包含的头文件:
#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /*文件控制定义*/
#include <errno.h> /*错误号定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <string.h>
增加类:
using namespace std;
class CSerialport
{private:int fd;const int baudrateSetting[14] = { B1000000, B576000, B500000, B460800, B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,};const int baudrate[14] = {1000000, 576000, 500000, 460800, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300, };public:CSerialport();bool Open(const char *dev); bool Open(const char *dev, int baud);bool Open(const char *dev, int baud, int databits, int stopbits, char parity);void Close(void);int Write(unsigned char *buf, int len); int Read(unsigned char *buf, int len); bool SetFlowCtrl(bool enable);
};
- fd:串口的句柄。
- baudrateSetting :底层设置波特率的值,这些参数是底层驱动固定的值。
- baudrate:app层设置波特率的范围,和实际值一致。
- Open:打开串口设备,重载了3个函数,返回值都是true或false,参数的含义分别是
- dev:设备名,例如打开"/dev/ttyAS1", Open("/dev/ttyAS1")即可。
- baud:波特率,有效值看数组baudrate
- databits:数据位长度,有效值7或8,默认8。
- stopbits:停止位长度,有效值1或2,默认1。
- parity:校验方式,有效值'O'(奇校验)、'E'(偶校验)、'N'(无校验),默认'N'。
- Close:关闭串口设备
- Write:写数据到串口,buf表示缓冲,写出的数据,len表示数据长度,返回值为实际写出的数据长度,为-1时表示写错误发生。
- Read:从串口读数据,buf表示缓冲,读入的数据,len表示缓冲长度,返回值为实际读入的数据长度,为0则表示无数据。
- SetFlowCtrl:设置流控功能是否使能,参数enable为true时打开流控功能。返回true或false。
3.2 serialport.cpp
在cpp中实现类的成员函数。
需要包含的头文件:
#include "serialport.hpp"
添加命名空间:
using namespace std;
3.2.1 构造函数
CSerialport::CSerialport()
{fd = -1;
}
初始化串口句柄为-1。
3.2.2 Open函数
这里重载了3个Open函数。
第一个只是打开,没有设置串口的其他关键参数。
bool CSerialport::Open(const char *dev)
{char* _dev=new char[256];strcpy(_dev, dev);fd = open(_dev, O_RDWR | O_NOCTTY | O_NDELAY);if (-1 == fd) { perror("Can't Open Serial Port\n");return false; }return true;
}
第二个是设置了波特率。
bool CSerialport::Open(const char *dev, int baud)
{struct termios options;int i;if(Open(dev) == false)return false; if (tcgetattr(fd, &options) != 0){perror("SetupSerial fail\n");return false;}//设置串口输入波特率和输出波特率 for (i = 0; i < (int)(sizeof(baudrate) / sizeof(int)); i++) {if (baud == baudrate[i]) {cfsetispeed(&options, baudrateSetting[i]); cfsetospeed(&options, baudrateSetting[i]); tcflush(fd, TCIFLUSH);if ((tcsetattr(fd, TCSANOW, &options)) != 0){perror("Serialport set error\n");return false;} return true; }}perror("Open Serial fail: baudrate is invalid\n");return false;
}
第三个函数包括设置串口的常用参数。
bool CSerialport::Open(const char *dev, int baud, int databits, int stopbits, char parity)
{struct termios options;int i;if (Open(dev) == false)return false; if (tcgetattr(fd, &options) != 0){perror("SetupSerial fail\n");return false;}bzero(&options, sizeof(options));for (i = 0; i < (int)(sizeof(baudrate) / sizeof(int)); i++) {if (baud == baudrate[i]) {cfsetispeed(&options, baudrateSetting[i]);cfsetospeed(&options, baudrateSetting[i]);break;}}options.c_cflag |= CLOCAL | CREAD;options.c_cflag &= ~CSIZE;switch (databits){case 7:options.c_cflag |= CS7;break;case 8:default:options.c_cflag |= CS8;break;}switch (parity){case 'O': //奇校验options.c_cflag |= PARENB;options.c_cflag |= PARODD;options.c_iflag |= (INPCK | ISTRIP);//printf("parity is Odd\n");break;case 'E': //偶校验options.c_iflag |= (INPCK | ISTRIP);options.c_cflag |= PARENB;options.c_cflag &= ~PARODD;//printf("parity is Even\n");break;case 'N': //无校验default:options.c_cflag &= ~PARENB;//printf("parity is None\n");break;}if (stopbits == 2){options.c_cflag |= CSTOPB;}else{options.c_cflag &= ~CSTOPB;}options.c_cc[VTIME] = 0;options.c_cc[VMIN] = 0;tcflush(fd, TCIFLUSH);if ((tcsetattr(fd, TCSANOW, &options)) != 0){perror("Serialport set error\n");return false;}return true;
}
3.2.3 Close函数
void CSerialport::Close(void)
{if (-1 == fd){return;}close(fd);
}
3.2.4 Write函数
int CSerialport::Write(unsigned char *buf, int len)
{ssize_t ret;ret = write(fd, buf, len);if(ret == -1)perror("Serialport send fail\n");return ret;
}
3.2.5 Read函数
int CSerialport::Read(unsigned char *buf, int len)
{#define TimeOut 10 //if no data in 10ms, returnint retval;fd_set rfds;struct timeval tv;int ret, pos;tv.tv_sec = TimeOut / 1000; //set the rcv wait time tv.tv_usec = TimeOut % 1000 * 1000; //100000us = 0.1spos = 0;while (1){FD_ZERO(&rfds);FD_SET(fd, &rfds);retval = select(fd + 1, &rfds, NULL, NULL, &tv);if (retval == -1){perror("Serialport no data\n");break;}else if (retval){ret = read(fd, buf + pos, 1);if (-1 == ret){printf("Serialport read no data\n");break;}pos++;if (len <= pos){break;}}else{//printf("retval:%d\n", retval);break;}}return pos;
}
读函数是在10ms内判断设备是否有数据,如果没数据就返回,如果有就继续读。宏定义TimeOut就是定义时间间隔,需要自己根据实际情况设定,一般情况10ms应该就够了。
3.2.6 SetFlowCtrl函数
bool CSerialport::SetFlowCtrl(bool enable)
{struct termios options;if (tcgetattr(fd, &options) != 0){perror("SetupSerial fail\n");return false;}if(enable == true){options.c_cflag |= CRTSCTS;}else{options.c_cflag &= ~CRTSCTS;}tcflush(fd, TCIFLUSH);if ((tcsetattr(fd, TCSANOW, &options)) != 0){perror("Serialport set error\n");return false;}return true;
}
4. 测试程序
新建文件main.cpp
包含的头文件
#include "serialport.hpp"
添加main函数
int main(int argc, char **argv)
{}
定义一个串口类实体
CSerialport sp1;
把main参数打印出来
int i = 0;
unsigned char buf[256];
int len = 0;
printf("The num of parameter:%d\n", argc);
for (i = 0; i < argc; i++)
{printf("%s\n", argv[i]);
}
根据不同的参数个数调用Open函数
if(argc == 1)
{printf("Open default serial port: tty\n");sp1.Open("/dev/tty");
}
else if(argc == 2)
{printf("Open serial port:%s\n", argv[1]);sp1.Open(argv[1]);
}
else if(argc == 3)
{printf("Open serial port:%s, baudrate:%d\n", argv[1], atoi(argv[2]));sp1.Open(argv[1], atoi(argv[2]));
}
else if(argc == 6)
{printf("Open serial port:%s, baudrate:%d, data bits:%d, stop bits:%d, parity:%s\n", argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), argv[5]);sp1.Open(argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), argv[5]);
}
写字符串
const char *wrData = "Serial Port Write String\n";
sp1.Write((unsigned char *)(wrData), strlen(wrData));
因为此时串口的TxD和RxD是短路的, 此时可以读到写出去的字符串
usleep(50000);
len = sp1.Read(buf, 256);
if(len > 0)
{//buf[len] = 0;printf("Serial Read String:%s", buf);
}
elseprintf("Serial Read String Fail\n");
注意需要delay一段时间再去读。
最后关闭设备
sp1.Close();
return 0;
5. 编译
新建一个Android.bp文件。
cc_binary {name: "SerialPort",srcs: ["main.cpp","serialport.cpp"],product_specific: true
}
在apollo_p2.mk里面添加SerialPort:
PRODUCT_PACKAGES += SerialPort
在Ubuntun中运行lunch后执行:
mmm device/softwinner/apollo/apollo-p2/serialport/
6. 运行验证
通过adb把生成的执行文件push到目标板中。
首先连接目标板:
adb connect 192.168.3.81:5555
IP地址根据自己的板子地址修改。
将文件push到目标板:
adb root
adb remount
adb push out/target/product/apollo-p2/product/bin/SerialPort /product/bin
然后adb shell,进入目标板的product/bin下运行:
apollo-p2:/product/bin # ./SerialPort /dev/ttyAS5 115200
The num of parameter:3
./SerialPort
/dev/ttyAS5
115200
Open serial port:/dev/ttyAS5, baudrate:115200
Serial Read String:Serial Port Write StringSerial Port Write String
将RxD和TxD断开短路,接到一个USB转串口板子上验证。
apollo-p2:/ # ./product/bin/SerialPort /dev/ttyAS5 115200 8 1 N
The num of parameter:6
./product/bin/SerialPort
/dev/ttyAS5
115200
8
1
N
Open serial port:/dev/ttyAS5, baudrate:115200, data bits:8, stop bits:1, parity:N
Serial Read String Fail
电脑上接收到字符串,由于没有发送数据到串口,所以显示Serial Read String Fail。
相关文章:
OrangePi Zero 3学习笔记(Android篇)3 - 串口
目录 1. 找到串口号 2. 修改串口权限 3. 串口类 3.1 serialport.hpp 3.2 serialport.cpp 3.2.1 构造函数 3.2.2 Open函数 3.2.3 Close函数 3.2.4 Write函数 3.2.5 Read函数 3.2.6 SetFlowCtrl函数 4. 测试程序 5. 编译 6. 运行验证 除了默认的UART用于shell&…...
Node.js 技术原理分析系列9——Node.js addon一文通
Node.js 是一个开源的、跨平台的JavaScript运行时环境,它允许开发者在服务器端运行JavaScript代码。Node.js 是基于Chrome V8引擎构建的,专为高性能、高并发的网络应用而设计,广泛应用于构建服务器端应用程序、网络应用、命令行工具等。 本系…...
HBuilderX安卓真机运行安装失败解决汇总
前置方案 1. 确认USB调试和连接模式 (1)开启USB调试:进入手机设置 > 开发者选项 > 确保USB调试已开启(如无开发者选项,连续点击“版本号”激活)。 (2)连接模式:将…...
TensorFlow 2.x入门实战:从零基础到图像分类项目
TensorFlow 2.x入门实战:从零基础到图像分类项目 前言 TensorFlow是Google开发的开源机器学习框架,已成为深度学习领域的重要工具。TensorFlow 2.x版本相比1.x有了重大改进,更加易用且功能强大。本文将带你从零开始学习TensorFlow 2.x&…...
SpringBoot+Dubbo+Zookeeper实现分布式系统步骤
SpringBootDubboZookeeper实现分布式系统 一、分布式系统通俗解释二、环境准备(详细版)1. 软件版本2. 安装Zookeeper(单机模式) 三、完整项目结构(带详细注释)四、手把手代码实现步骤1:创建父工…...
数据中台-常用工具组件:DataX、Flink、Dolphin Scheduler、TensorFlow和PyTorch等
数据实施服务工具组件概览 数据中台的数据实施服务涵盖 数据采集、处理、调度、分析与应用 全流程,以下为关键工具组件及其作用: 工具类型核心功能典型应用场景DataX离线数据采集多源异构数据批量同步数据仓库ODS层数据导入Apache Flink实时计算引擎流…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】电商数据分析案例-9.2 流量转化漏斗分析
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 9.2 流量转化漏斗分析:从数据清洗到可视化全流程实战一、背景与目标二、数据准备与清洗2.1 数据来源与字段说明2.2 数据清洗步骤2.2.1 去除无效数据2.2.2 处理时…...
结合Splash与Scrapy:高效爬取动态JavaScript网站
在当今的Web开发中,JavaScript的广泛应用使得许多网站的内容无法通过传统的请求-响应模式直接获取。为了解决这个问题,Scrapy开发者经常需要集成像Splash这样的JavaScript渲染引擎。本文将详细介绍Splash JS引擎的工作原理,并探讨如何将其与S…...
[计算机科学#10]:早期的计算机编程方式
【核知坊】:释放青春想象,码动全新视野。 我们希望使用精简的信息传达知识的骨架,启发创造者开启创造之路!!! 内容摘要:1804年,为了在织布机上编织出丰富多彩的…...
JAVA:Spring Boot 集成 Lua 的技术博客
1、简述 在现代开发中,Lua 以其轻量级、高性能以及易嵌入的特点广泛用于脚本扩展、游戏开发以及配置处理场景。将 Lua 与 Spring Boot 集成,可以在 Java 项目中实现动态脚本功能,增强项目的灵活性和动态配置能力。 样例代码: https://gitee.com/lhdxhl/springboot-example…...
代码随想录算法训练营 Day40 动态规划Ⅷ 股票问题
动态规划 题目 121. 买卖股票的最佳时机 - 力扣(LeetCode) 使用二维 dp 数组表示 1. dp[i][0] 表示持有股票的最大金额,dp[i][1] 表示不持有股票的最大金额,表示盈利结果 2. 递推公式由前一天持有金额和是否买股票决定 决定是否…...
【已解决】WORD域相关问题;错误 未找到引用源;复制域出错;交叉引用域到底是个啥
(微软赶紧倒闭 所有交叉引用域,有两个状态:1.锁定。2.手动。可通过编辑->链接查看。 “锁定”状态域的能力: 1. 导出PDF格式稳定(【已解决】WORD导出PDF时,参考文献上标自动被取消/变为正常文本_word…...
小米 MiMo 开源:7B 参数凭什么 “叫板” AI行业巨头?
目录 一、技术革命的起点:小米AI战略的“破局者” 1.1 战略背景:从硬件厂商到AI基础设施提供商 1.2 团队揭秘:“天才少女”罗福莉与小米AI梦之队 二、技术架构解析:7B参数如何实现“推理跃迁” 2.1 核心技术原理 2.2 技术指…...
构建高可用性的LVS-DR群集:实现无缝的负载均衡与故障转移
目录 一、LVS-DR集群 1.LVS-DR工作原理 2.数据包流向分析 3.LVS-DR模式特点 二、直接路由模式(LVS-DR) 1.资源清单 2.配置负载调度器(lvs) 3.配置节点服务器(web1、web2) 4.测试LVS群集 5.使用NFS发布共享资源(nfs上) …...
低光图像增强新色彩空间HVI:技术突破与创新解析(HVI: ANewColor Space for Low-light Image Enhancement)
摘要 低光图像增强(LLIE)是计算机视觉领域的关键任务,旨在从受损的低光图像中恢复细节信息。针对现有方法在标准RGB(sRGB)空间易产生色偏与亮度伪影的问题,以及HSV色彩空间转换引发的红/黑噪声问题…...
Abaqus学习笔记
目录 Abaqus介绍 学习资源 编辑Abaqus/CAE abaqus下载安装 abaqus基本操作 Abaqus启动 新建模型 编辑 编辑修改界面背景 编辑编辑结果信息的显示与否 编辑计算结果信息字体设置 编辑允许多绘图状态 单位量纲 视图操作 事前说明 ODB文件 本构关系…...
AquaCrop 模型新视角:多技术助力农业精准水管理
技术点目录 模型原理介绍与数据要求及模型分析数据制备、模型运行与案例实践(界面GUI版本)模型优化与敏感性分析(基于R语言实践)源代码分析(基于FORTRAN)未来气候变化影响分析与案例实践(基于Py…...
从知识图谱到精准决策:基于MCP的招投标货物比对溯源系统实践
前言 从最初对人工智能的懵懂认知,到逐渐踏入Prompt工程的世界,我们一路探索,从私有化部署的实际场景,到对DeepSeek技术的全面解读,再逐步深入到NL2SQL、知识图谱构建、RAG知识库设计,以及ChatBI这些高阶应用。一路走来,我们在AI的领域里一步一个脚印,不断拓展视野和能…...
【平面波导外腔激光器专题系列】1064nm单纵模平面波导外腔激光器
摘要:我们介绍了平面波导外腔二极管激光器 (PW-ECL) 的特性。据我们所知,这是第一款蝶形封装的 1064nm半导体激光器,其可以稳定锁定到外部参考频率。我们从精密实验的角度评估了它的性能,特别是使用碘的超精细吸收线,在…...
C++ 算法学习之旅:从入门到精通的秘籍
在编程的浩瀚宇宙中,C 算法宛如璀璨的星辰,照亮我们前行的道路。作为一名 C 算法小白,或许你和我一样,怀揣着对算法的好奇与憧憬,却又在学习的道路上感到迷茫。别担心,今天我就和大家分享一下如何学习各种基…...
按摩椅上的气囊系统 是现代按摩椅中非常关键的组成部分,它与机芯系统相辅相成,为用户提供全方位、更接近真人按摩的体验
按摩椅上的气囊系统是现代按摩椅中非常关键的组成部分,它与机芯系统相辅相成,为用户提供全方位、更接近真人按摩的体验。 一、按摩椅气囊的产生背景 1. 传统按摩方式的局限 早期的按摩椅主要依赖机械式的“凸轮电机”或简单的机芯滚轮结构,…...
配置Hadoop集群环境-使用脚本命令实现集群文件同步
(一)Hadoop的运行模式 hadoop一共有如下三种运行方式: 1. 本地运行。数据存储在linux本地,测试偶尔用一下。我们上一节课使用的就是本地运行模式hadoop100。 2. 伪分布式。在一台机器上模拟出 Hadoop 分布式系统的各个组件&…...
Linux系统(OpenEuler22.03-LTS)部署FastGPT
在 openEuler 22.03 LTS 系统上通过 Docker Compose 安装 FastGPT 的步骤如下: 官方参考文档:https://doc.fastgpt.cn/docs/development/docker/ 1. 安装 Docker 和 Docker Compose 可以参考我之前离线安装Docker的文章:openEuler 22.03 LT…...
FastExcel 本地开发和Linux上上传Resource文件的差异性
不能直接通过路径来获取 这个是一个下载导出文件的操作 GetMapping(value "/export/all") public void exportAll(HttpServletResponse response, LaylineListReq req) throws IOException {// 从类路径下获取 Excel 文件资源ClassPathResource classPathResource…...
Excel学习笔记
在excel表格中,某列的数据最大,则整行都红色底色标出,怎么实现? 更改x值,excel图表上动态显示 该值的Y值且动态显示十字交叉线 为了实现如下图所示的效果,需要做出几个辅助列就行。 step1:先写…...
数据中台-数仓分层结构【Doris】
数据仓库采用Doris进行搭建,并分为ODS/DWD/DWM/DWS/ADS等层级结构进行分层数据存储。Doris是百度开源的MPP数据库,可有效支撑大数据量的数据计算和分布式扩展存储。 数据仓库分层架构设计目标 解耦与复用性:通过分层隔离原始数据与业务逻辑&a…...
使用Jmeter对AI模型服务进行压力测试
一、JMeter介绍 Apache JMeter 是一款开源的性能测试工具,主要用于评估Web应用程序的负载和性能。它支持多种类型的测试,包括但不限于: 负载测试:模拟大量用户访问系统以检测其在高负载下的表现。性能测试:评估系统在…...
测试用例管理平台哪些好用?9款主流测试平台对比
在当今软件开发领域,测试用例管理平台已成为提升产品质量和团队协同效率的关键工具。本文将围绕“测试用例管理平台”这一核心关键词,全面解析市面上9款主流产品,帮助企业管理者和测试团队快速了解各平台的核心优势和适用场景,从而…...
C++函数传值与传引用对比分析
在C编程中,函数参数传递的方式直接影响程序的性能、内存管理以及代码逻辑的正确性。传值(Pass by Value)和传引用(Pass by Reference)是两种最常用的参数传递方式,它们各有优缺点,适用于不同的场…...
【se-res模块学习】结合CIFAR-10分类任务学习
继CIFAR-10图像分类:【Res残差连接学习】结合CIFAR-10任务学习-CSDN博客 再优化 本次训练结果在测试集上的准确率表现可达到90%以上 1.训练模型(MyModel.py) import torch import torch.nn as nnclass SENet(nn.Module): # SE-Net模块def…...
二元随机响应(Binary Randomized Response, RR)的翻转概率
随机响应(Randomized Response)机制 ✅ 回答核心: p 1 1 e ε 才是「翻转概率」 \boxed{p \frac{1}{1 e^{\varepsilon}}} \quad \text{才是「翻转概率」} p1eε1才是「翻转概率」 而: q e ε 1 e ε 是「保留真实值」…...
湖北理元理律师事务所:债务优化中的“生活保障”方法论
债务危机往往伴随生活质量骤降,如何在还款与生存间找到平衡点,成为债务优化的核心挑战。湖北理元理律师事务所基于多年实务经验,提出“双轨并行”策略:法律减负与生活保障同步推进。 债务优化的“温度法则” 1.生存资金预留机制…...
RFID智能书柜:精准定位,找书告别 “大海捞针”
在传统图书馆的浩瀚书海,找书无异于在错综复杂的迷宫里徘徊。读者在书架间来回奔波,耗费大量时间精力,还常一无所获。RFID智能书柜的出现,彻底改写了这一局面。它搭载的RFID读写器与天线协同工作,能实时精准定位贴有RF…...
视觉图像处理及多模态融合初探
(一)指标汇总 1. 图像采集与质量提升 指标描述可能的量化值图像清晰度反映图像中物体的边缘和细节的清晰程度例如:1-10 分(1 为极不清晰,10 为非常清晰)噪声水平表示图像中随机噪声的多少例如:噪声强度百分比(0%-100%)畸变程度描述图像中物体形状的变形程度例如:畸变…...
射频前端模组芯片(PA)三伍微电子GSR2337 兼容替代SKY85337, RTC7646, KCT8247HE
射频前端模组芯片(PA)三伍微电子GSR2337 兼容替代SKY85337, RTC7646, KCT8247HE 型号GSR2337 频率: 2.4 GHz 类型: FEM (PALNASW) WIFI: 11n/ac/ax 功率: 21dBmEVM-43dB5V 封装: 3*3 mm 电压: 3.3V & 5V P2P: SKY85…...
python 接收c++的.so传的jsoncpp字符串
叮!快来看看我和文心一言的奇妙对话~点击链接 https://yiyan.baidu.com/share/57o6vGa3GY -- 文心一言,既能写文案、读文档,又能绘画聊天、写诗做表,你的全能伙伴! 要从 C 动态链接库 (.so 文件) 中接收 JS…...
EasyRTC嵌入式音视频通话SDK驱动智能硬件音视频应用新发展
一、引言 在数字化浪潮下,智能硬件蓬勃发展,从智能家居到工业物联网,深刻改变人们的生活与工作。音视频通讯作为智能硬件交互与协同的核心,重要性不言而喻。但嵌入式设备硬件资源受限,传统音视频方案集成困难。EasyRT…...
Day19 常见的特征筛选算法
常见的特征筛选算法 1. 方差筛选 原理 :方差衡量的是数据的离散程度。在特征筛选中,如果某个特征的方差很小,说明该特征在不同样本上的值差异不大,那么它对模型的区分能力可能很弱。方差筛选就是通过设定一个方差阈值࿰…...
如何使用极狐GitLab 软件包仓库功能托管 terraform?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 Terraform 模块库 (BASIC ALL) 基础设施仓库和 Terraform 模块仓库合并到单个 Terraform 模块仓库功能引入于极狐GitLab 15.1…...
15前端项目----用户信息/导航守卫
登录/注册 持久存储用户信息问题 退出登录导航守卫解决问题 持久存储用户信息 本地存储:(在actions中请求成功时) 添加localStorage.setItem(token,result.data.token);获取存储:(在user仓库中,state中tok…...
重定向及基础实验
1.if指令 if (判断条件){ 执行语句; } if的正则表达式 #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false ! #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false ~ #区分大小写字符&…...
CBO和HBO区别及介绍
CBO(Cost-Based Optimizer)和 HBO(Heuristic-Based Optimizer)是两种数据库查询优化器的类型,它们在优化策略和实现方式上有显著的区别。以下是详细的解释和对比: 1. CBO(Cost-Based Optimizer…...
华为HCIP-AI认证考试版本更新通知
华为HCIP-AI认证考试版本更新通知 HCIP-AI-EI Developer V2.5认证发布 华为官方宣布,HCIP-AI-EI Developer V2.5认证考试将于2025年3月31日正式上线。新版认证聚焦AI工程化开发与行业实践,新增大模型部署优化、AI边缘计算等前沿技术内容&…...
【算法-链表】链表操作技巧:常见算法
算法相关知识点可以通过点击以下链接进行学习一起加油!双指针滑动窗口二分查找前缀和位运算模拟 链表是一种灵活的数据结构,广泛用于需要频繁插入和删除的场景。掌握链表的常见操作技巧,如插入、删除、翻转和合并等,能帮助开发者更…...
【探寻C++之旅】第十三章:红黑树
请君浏览 前言1. 红黑树的概念1.2 红黑树的规则1.3 红黑树如何确保最长路径不超过最短路径的两倍?1.4 红黑树的效率 2. 红黑树的实现2.1 红黑树的结构2.2 红黑树的插入情况1:变色情况2:单旋变色情况2:双旋变色代码演示 2.3 红黑树…...
JavaScript 性能优化全攻略:从基础到实战
引言 在现代 Web 开发中,JavaScript 作为核心语言,其性能直接影响用户体验。无论是单页应用(SPA)还是复杂交互页面,性能优化始终是开发者关注的核心。 本文将从基础策略、最新技巧、常见误区和实战案例四个维度,系统性地解析 JavaScript 性能优化的关键方法,并提供可复…...
Kafka消息队列之 【消费者分组】 详解
消费者分组(Consumer Group)是 Kafka 提供的一种强大的消息消费机制,它允许多个消费者协同工作,共同消费一个或多个主题的消息,从而实现高吞吐量、可扩展性和容错性。 基本概念 消费者分组:一组消费者实例的集合,这些消费者实例共同订阅一个或多个主题,并通过分组来协调…...
HuggingFace与自然语言处理(从框架学习到经典项目实践)[ 01 API操作 ]
本教程适用与第一次接触huggingface与相应框架和对nlp任务感兴趣的朋友,该栏目目前更新总结如下: Tokenizer: 支持单句/双句编码,自动处理特殊符号和填充。 批量编码提升效率,适合训练数据预处理。Datasets…...
uniapp-文件查找失败:‘@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue‘
uniapp-文件查找失败:‘dcloudio/uni-ui/lib/uni-icons/uni-icons.vue’ 今天在HBuilderX中使用uniapp开发微信小程序时遇到了这个问题,就是找不到uni-ui组件 当时创建项目,选择了一个中间带的底部带选项卡模板,并没有选择内置u…...
springboot+vue实现在线网盘(云盘)系统
今天教大家如何设计一个网盘(云盘)系统系统 , 基于目前主流的技术:前端vue,后端springboot。 同时还带来的项目的部署教程。 视频演示 springbootvue实现在线网盘(云盘)系统 图片演示 一. 系统概述 用过百…...