全志V85x芯片 Tina Linux RISC-V E907核心开发指南

news2024/11/24 15:58:39

全志V85x芯片 Tina Linux RISC-V E907核心开发指南

1 编写目的

介绍v85X 上E907 的启动环境和AMP 的环境搭建。

2 使用范围

全志V85X 系列芯片

3 环境

A7 SDK:Tina
E907 SDK:melis

4 SDK 快捷命令说明

这里主要介绍几个下文会用到的命令,并不会介绍全部命令,如果想了解全部命令,可以在lunch
方案后使用hmm打印出所有tina提供的快捷命令。

  1. ckernel, m kernel_menuconfig, mkernel:分别对应进入到内核目录,配置内核,单独编译内核
  2. cboot0, mboot0:进入boot0 目录,单独编译boot0
  3. cmelis, mmelis, mmelis menuconfig:分别对应进入melis 根目录,编译melis,配置melis
  4. make:编译整个tina 除了melis 外的所有东西,如boot0,uboot,内核,跟文件系统等
  5. cconfigs:进入板级配置目录,这里主要存放板级的设备树,分区等配置文件
  6. p:打包命令,将编译后的东西打包成固件

5 E907 启动环境

5.1 预先工作

选择方案

cd tina
source build/envsetup.sh
lunch
选择对应的V85x方案

5.2 配置boot0 启动e907

e907 在boot0 阶段启动,需要对boot0 进行一些配置

cboot0
vim board/sun8iw21p1/common.mk
# 如下图取消注释
保存退出
mboot0 #编译

image-20221121115033101

图5-1: 配置1

5.2.1 关闭RISCV 的IOMMU

本步骤只有需要在boot0 阶段启动E907 的需要配置。打开设备树,注释掉下面2 条属性,因为
e907 在boot0 阶段就启动了,不能打开其IOMMU。

cconfigs
vim ../board.dts

image-20221121115124735

图5-2: 关闭IOMMU

5.3 配置打包e907 固件

cconfigs
cd ../../default/
vim boot_package_nor.cfg # 取消melis-elf选项的注释,如下图
vim boot_package.cfg # 取消melis-elf选项的注释,如下图
保存退出

image-20221121115200889

图5-3: 打包配置

5.4 Linux 配置

ckernel
m kernel_menuconfig
# 如下图选中2个驱动
mkernel -j

image-20221121115234331

图5-4: 补丁下载
mmelis menuconfig # 如下图选中standby支持

image-20221121115354868

图5-5: e907-standby 配置

5.5 编译打包

至此关于E907 启动的配置完成,进行编译烧录即可

make -j16 # 编译tina
mmelis # 编译melis
p
烧录

6 AMP 环境搭建

AMP 环境用于Linux 和E907 间通信,Linux 依赖于2 个驱动,melis 依赖于openamp 驱
动。

  1. remoteproc 驱动:主要用来管理E907 固件的加载器的
  2. rpmsg:在virtio 框架上实现的消息传送框架

6.1 Linux 配置

注意:需要前面的启动环境配置好后,再执行以下操作。
需要打开的配置有:

  1. remoteproc 驱动
  2. rpmsg 驱动

6.1.1 remoteproc 驱动

ckernel
m kernel_menuconfig

选中

image-20221121115519043

图6-1: rproc config

6.1.2 rpmsg 驱动

ckernel
m kernel_menuconfig
# 红框必选,蓝色框为sdk提供的rpmsg demo,视情况而选择
# 建议选上sunxi rpmsg ctrl driver 方便后面测试rpmsg通信功能

选中

image-20221121115554767

图6-2: rpmsg config

6.2 melis 配置

主要进行2 个配置:

  1. msgbox 配置
  2. openamp 配置

6.2.1 msgbox 配置

mmelis menuconfig #选择下面2项

选中

image-20221121115636186

图6-3: msgbox-melis config

6.2.2 openamp 配置

mmelis menuconfig

# 红框是必选,蓝框是可选的rpmsg demo

刚刚Linux 端选择了rpmsg hearbeat demo 和ctrl driver,我们这里也选上对应的驱动hearbeatdriver 和client driver。
选中

image-20221121115718036

图6-4: openamp config

为了方便在控制台测试rpmsg 通信,rpmsg client driver 还需开启下面2 个选项

image-20221121115739276

图6-5: rpmsg client config

6.3 打包

make -j16 # 编译tina
mmelis # 编译melis
p
烧录

6.4 测试

本章节介绍一些AMP 提供的控制台命令,用于测试AMP 环境

6.4.1 E907 控制

1.在linux 控制台执行:echo stop > /sys/kernel/debug/remoteproc/remoteproc0/state
(停止e907)

2.在linux 控制台执行:echo start > /sys/kernel/debug/remoteproc/remoteproc0/state
(启动e907)

若控制台出现remoteproc0: remote processor e907_rproc is now up,表明启动e907 成功。
如果使能了rpmsg_heartbeat 和rpmsg_ctrl 驱动,可以在Linux 控制台start 之后会看到如下输出:

image-20221121115904466

图6-6: rproc test

红框里面表示有2 个设备成功创建,代表rpmsg 正常。

6.4.2 rpmsg 通信测试

借助rpmsg_ctrl 驱动帮助我们进行测试

6.4.2.1 名字监听.

平台:melis 控制台
输入如下图命令:
eptdev_bind 命令:监听name=test 的链接,最大连接数5 个

image-20221121115954891

图6-7: rproc test
6.4.2.2 节点创建

平台:Linux 控制台
输入如下图的命令,进行节点创建

image-20221121120018359

图6-8: rpmsg test

image-20221121120038291

图6-9: rpmsg test

根据log 可以看出,创建了一个rpmsg0-4 5 个设备,因为melis 只监听的5 个,故最多只能创建5 个。

6.4.2.3 节点通信

rpmsg 节点支持标准的文件操作,直接读写即可。
Linux 向e907 发数据:

image-20221121120107001

图6-10: rpmsg test

image-20221121120127394

图6-11: rpmsg test

e907 向Linux 发数据:

image-20221121120151355

图6-12: rpmsg test

image-20221121120206688

图6-13: test
6.4.2.4 节点关闭

Linux 主动释放:

image-20221121120236147

图6-14: rpmsg test

image-20221121120250818

图6-15: rpmsg test

e907 主动释放:

image-20221121120354607

图6-16: rpmsg test

image-20221121120410691

图6-17: rpmsg test

e907 端接触监听,会释放所有的链接:

image-20221121120433076

图6-18: rpmsg test

image-20221121120447261

图6-19: rpmsg test

7 开发使用

7.1 rpmsg 内核开发

linux 端请参考driver/rpmsg/rpmsg_client_e907.c 。

melis 端请参考ekernel/subsys/thirdparty/openamp/rpmsg_demo/ 目录下的文件。

7.2 rpmsg 用户层接口

控制台调试命令参考测试章节,这里列举代码使用示例。

Linux 端:

#include <linux/rpmsg.h>
# 创建端点
int fd;
struct rpmsg_ept_info info;
char ept_dev_name[32];
strcpy(info.name, "test");
info.id = 0xfffff; # id由itctl进行更新
fd = open(ctrl_dev, O_RDWR);
ret = ioctl(fd, RPMSG_CREATE_EPT_IOCTL, &info);
# 当ioctl返回值==0时,端点已经创建成功,设备节点会出现在/dev/rpmsg%d(=info.id)下
close(fd);
#读写设备节点
snprintf(ept_dev_name, 32, "/dev/rpmsg%d", info.id);
fd = open(ept_dev_name, O_RDWR);
write,read,poll...
close(fd);
# 关闭节点
fd = open(ctrl_dev, O_RDWR);
ret = ioctl(fd, RPMSG_DESTROY_EPT_IOCTL, &info);
close(fd);

melis 端:

方法1:基于rpmsg_ctrl 驱动,等待主机建立连接

// 头文件
#include <openamp/sunxi_helper/openamp.h>
static int ept_cb(struct rpmsg_endpoint *ept, void *data,
size_t len, uint32_t src, void *priv)
{
// 收到数据
}
int bind_cb(struct rpmsg_ept_client *client)
{
// client绑定,每个client代表一个连接
// client->priv和client->ept->priv 可供用户使用
}
int unbind_cb(struct rpmsg_ept_client *client)
{
// 连接关闭
}
int main()
{
// cnt: 监听的数量,即最多对test创建cnt个连接
// 最后一个参数priv,其实里面设置的是client->priv
rpmsg_client_bind("test", ept_cb, bind_cb, unbind_cb,
cnt, NULL);
// do some things
// 取消绑定会unbind所有与其相关的client
rpmsg_client_unbind("test");
}

具体代码参考ekernel/subsys/thirdparty/openamp/rpmsg_demo/rpmsg_ctrl/test.c;

方法2:基于rpmsg 原生框架,melis 端主动创建连接,触发主机端的rpmsg driver 的probe。

melis 端代码参考:

1.ekernel/subsys/thirdparty/openamp/rpmsg_demo/demo.c

2.ekernel/subsys/thirdparty/openamp/rpmsg_demo/hearbeat.c

Linux 端参考代码:

1.drivers/rpmsg/rpmsg_client_e907.c

2.drivers/rpmsg/rpmsg_client_heart.c

7.3 amp 控制台

SDK 在Linux 端提供了进入E907 控制台的功能,配置步骤如下:

内核配置

ckernel
m kernel_menuconfig # 选择下图配置

image-20221121120738002

图7-1: rpmsg config

Tina 配置

croot
m menuconfig # 选择下图配置

image-20221121175441744

图7-2: amp_shell config

melis 配置

image-20221121175506540

图7-3: amp_shell config

编译& 打包& 下载

mmelis -j32
make -j32
p

使用

在echo start > /sys/kernel/debug/remoteproc/remoteproc0/state 后检查有无rpmsg_ctrl 成功创建的log 或者是否存在/dev/rpmsg_ctrl0 节点。如果正常,直

接在Linux 控制台啊输入amp_shell 即可进入e907 控制台,amp_exit退出控制台。支持执行多次amp_shell,开启多个控制台。

image-20221121175556831

图7-4: amp_shell test

image-20221121175611748

图7-5: amp_shell test

7.4 大数据传输

由于rpmsg 特性,不适合传输大数据量;如需使用大数据传输,请参考本章节。

7.4.1 配置

内核打开rpbuf 驱动:

m kernel_menuconfig
Device Drivers --->
	RPBuf drivers --->
		-*- RPBuf device interface
		<*> RPMsg-based RPBuf service driver
		<*> Allwinner RPBuf controller driver
		<*> Allwinner RPBuf sample driver

Note:Allwinner RPBuf sample driver 是一个简单的rpbuf 内核层使用demo,可以不使能。

e907 配置:

Kernel Setup
	Subsystem support
		Allwinner Components Support
			RPBuf framework
                [*] RPMsg-based RPBuf service component
                [*] RPBuf controller component
                [*] RPMsg-based RPBuf service component demo
            OpenAMP Support
           	  [*]  RPBuf demo

Tina 打开rpbuf_demo 软件包:

m menuconfig
Allwinner --->
    RPBuf --->
        <*> rpbuf_demo
        <*> rpbuf_test

7.4.2 测试

rpmsg_test:会自动生成随机数据并附带MD5 校验值,另一端收到会重新计算MD5 并与收到的进行对比。

(e907) rpbuf_test -c -N "rpbuf_demo" -L 0x100000 # 创建size=0x100000的buffer
(Linux) rpbuf_test -d 1000 -s -L 0x100000 -N "rpbuf_demo" # 发送测试数据
(Linux) rpbuf_test -r -t 1000 -L 0x100000 -N "rpbuf_demo" # 接收数据
(e907) rpbuf_test -s -L 0x100000 -N "rpbuf_demo" #发送测试数据
(e907) rpbuf_test -N "rpbuf_demo" -d # 删除buffer

出现success 表明校验成功。

过程log 如下:

image-20221121182820753

图7-6: Linux 端log

image-20221121182838167

图7-7: e907 端log

rpbuf_demo:用于在控制台简单传输数据

(e907) rpbuf_demo -c -N "rpbuf_demo" -L 0x1000 # 创建size=4k的buffer
(Linux) rpbuf_demo -d 1000 -L 0x1000 -N "rpbuf_demo" -s "hello" # 发送数据,并在1000ms后释放
buffer
(Linux) rpbuf_demo -r -t 1000 -L 0x1000 -N "rpbuf_demo" # 接收数据
(e907) rpbuf_demo -s "hello" -N "rpbuf_demo" # 发送数据
(e907) rpbuf_demo -N "rpbuf_demo" -d # 删除buffer

image-20221121182906578

图7-8: Linux 端log

image-20221121182927251

图7-9: e907 端log

7.4.3 使用

内核层接口,参考drivers/rpbuf/rpbuf_sample_sunxi.c:
Linux 端使用流程:

  1. 在需要用到rpbuf 接口的驱动的设备树节点种添加一条属性:rpbuf = <&rpbuf_controller0>;,
    可以创建多个controller,当面默认只有一个rpbuf_controller0;

  2. 获取controller:调用controller = rpbuf_get_controller_by_of_node(np, 0);

  3. 创建buffer:调用rpbuf_alloc_buffer(controller, name, len, ops, cbs, priv);

  4. 接收数据:收到数据时候会调用cbd->rx_cb 回调

  5. 判断状态:创建出的buffer 不一样马上可用,需要用判断状态,调用rpbuf_buffer_is_available(buffer)

  6. 发送数据:

  7. buf_va = rpbuf_buffer_va(buffer);

  8. buf_len = rpbuf_buffer_len(buffer);

  9. 直接对buf_va 地址进行写入即可

  10. rpbuf_transmit_buffer(buffer, offset, data_len);

  11. 释放buffer:rpbuf_free_buffer(buffer);

    应用层端口,具体细节可以参考package/allwinner/rpbuf/

    1. 创建buffer
    2. fd = open(0, O_RDWR);
    3. ioctl(fd, RPBUF_CTRL_DEV_IOCTL_CREATE_BUF, &buffer->info);
    4. buf_fd = open(buf_dev_path, O_RDWR);
    5. addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, buf_fd, 0);
    6. 接收数据:
    7. rpbuf_receive_buffer_block(buffer, &offset, &data_len) 阻塞接收
    8. rpbuf_receive_buffer_nonblock(buffer, &offset, &data_len) 非阻塞接收
    9. 发送数据:
    10. buf_va = rpbuf_buffer_va(buffer);
    11. 直接对buf_va 地址进行写入即可
    12. rpbuf_transmit_buffer(buffer, offset, data_len);
    13. 释放buffer:
    14. close(buf_fd);
    15. ioctl(fd, RPBUF_CTRL_DEV_IOCTL_DESTROY_BUF, &buffer->info);
    16. close(fd);

e907 端接口,可以参考ekernel/subsys/aw/rpbuf/rpbuf_demo/rpbuf_demo.c
e907 端使用流程:

  1. 获取controller:调用controller = rpbuf_get_controller_by_id(0); 代码默认提供一个controller,
    这里直接使用
  2. 创建buffer:调用rpbuf_alloc_buffer(controller, name, len, ops, cbs, priv);
  3. 接收数据:收到数据时候会调用cbd->rx_cb 回调
  4. 判断状态:创建出的buffer 不一样马上可用,需要用判断状态,调用rpbuf_buffer_is_available
    (buffer)
  5. 发送数据:
  6. buf_va = rpbuf_buffer_va(buffer);
  7. buf_len = rpbuf_buffer_len(buffer);
  8. 直接对buf_va 地址进行写入即可
  9. rpbuf_transmit_buffer(buffer, offset, data_len);
  10. 释放buffer:rpbuf_free_buffer(buffer);

7.4.4 Note

  1. 关于controller:代码默认已经提供了一个基于rpmsg 实现的controller0 了,正常情况下
    直接使用改controller 即可
  2. 关于rpbuf_alloc_buffer 的ops 参数:controller0 已经基于ion 实现了内存分配函数。如
    无必要,使用controller 的内存分配函数即可,即创建buffer 时,ops 参数置NULL。
  3. 关于互斥:由于通信双方都能拿到的buffer 的地址,难以在驱动实现互斥,所以需要在具体
    应用上自行保证互斥。

8 其他

8.1 rpmsg 需知

  1. 端点是rpmsg 通信的基础;每个端点都有自己的src 和dst 地址,范围(1 - 1023,除了0x35)

  2. rpmsg 每次发送数据最大为512 -16 字节;(数据块大小为512,头部占用16 字节)

  3. rpmsg 使用name server 机制,当E907 创建的端点名,和linux 注册的rpmsg 驱动名一样的时候,rpmsg bus 总线会调用其probe 接口。所以如果需要

Linux 端主动发起创建端点并通知e907,则需要借助上面提到的rpmsg_ctrl 驱动。

  1. rpmsg 是串行调用回调的,故建议rpmsg_driver 的回调中不要调用耗时长的函数,避免影响其他rpmsg 驱动的运行

8.2 rpbuf 简介

rpbuf 全志基于rpmsg 开发的一套通信机制,它主要解决rpmsg 不适合传输大数据量的问题。
其实现原理是使用rpmsg 传输数据的地址,而不是数据的本身,避免了数据的多次拷贝以及每次
传输不能大于496 字节的限制。
rpbuf 中使用名字和长度来唯一标识一个buffer,故不能创建相同名字的buffer。
rpbuf 中的buffer 有3 个状态:

  1. remote_dummy_buffers:该buffer 远端已创建,本地未创建
  2. local_dummy_buffers:该buffer 本地已创建,远端未创建
  3. buffers:远端、本地已创建,此时buffer 才可用

8.3 修改e907 地址

目前在perf1 板子上,给e907 预留的内存为:0x48000000 开始的4M 空间

如果需要修改E907 固件的运行地址和大小,可按如下步骤进行修改:

8.3.1 修改设备树(Linux)

cconfigs
vim ../board.dts
# 找到e907_dram项,修改成想要的地址,例如这里向修改成0x49000000
e907_dram: riscv_memserve {
reg = <0x0 0x49000000 0x0 0x00400000>;
no-map;
};
# 重新编译内核
mkernel

8.3.2 修改配置项(melis)

mmelis menuconfig
# 如下图进行修改;e907没有mmu,故第一项和第二项相等
# 将第一项和第二项改成0x49000000
# 第三项为大小,可按需修改

image-20221121183344375

图8-1: e907 dram config

8.3.3 修改链接脚本(melis)

cmelis
vim source/projects/v853-e907-ver1-board/kernel.lds
# 如下图所示,按照所需修改DRAM_SEG_KRN 项目
mmelis -j16

image-20221121183431822

图8-2: e907 lds config

8.4 添加新板级注意事项

当用户需要添加新的板子时,需要注意修改build/expand_melis.sh 来支持mmelis, cmelis命令。例如,用户在添加了新的板级v853_user,在melis 添加了新的板

级e907_user,则需要对build/expand_melis.sh文件进行如下修改:

image-20221122091718934

图8-3: 新板级配置

8.5 melis 系统

8.5.1 常用命令

  1. help:列出当前系统支持的所有命令
  2. p addr [len]:打印内存数据
  3. m addr value:修改内存数据
  4. top:显示当前系统各个线程CPU 占用率
  5. ps:显示当前系统各个线程状态
  6. free:查看当前系统内存信息

8.5.2 自定义命令

当用户想要在e907 控制台上执行自定义的命令时候,可以用FINSH_FUNCTION_EXPORT_ALIAS导出自定义的函数。例如:

image-20221122091828089

图8-4: 添加自定义命令

image-20221122091847075

图8-5: 执行自定义命令

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【嵌入式项目开源】基于ESP32的墨水屏桌面小屏幕

首先简要介绍一下这个项目&#xff1a; 这个项目的开源主要包括硬件&#xff0c;固件和软件两部分&#xff0c;外壳后面如果做了也会开源出来。该项目主要是参考了以下教学视频。 链接&#xff1a;桌面小屏幕实战教学 其中硬件部分改动不大&#xff0c;主要是把USB驱动改成了Ty…

推荐系统从入门到入门(1)——推荐系统综述与协同过滤

本系列博客总结了不同框架、不同算法、不同界面的推荐系统&#xff0c;完整阅读需要大量时间&#xff08;又臭又长&#xff09;&#xff0c;建议根据目录选择需要的内容查看&#xff0c;欢迎讨论与指出问题。 目录 系列文章梗概 系列文章目录 一、问题背景介绍 1.推荐算法与…

企业拥有PMO(项目管理办公室)的好处

PMO&#xff08;项目管理办公室&#xff09;&#xff0c;是一个企业内定义和维护项目管理标准的办公室或部门。PMO为项目的执行提供指导和标准。他们创造切实的目标&#xff0c;与整个企业的愿景保持一致&#xff0c;并确保所有目标的实现。 PMO指导以项目模板、标准化流程、…

DoIP协议概述

大家好哈&#xff0c;我是穿拖鞋的汉子&#xff01; 伴随着需求不断提升&#xff08;车身数据传输速率和带宽需求&#xff09;&#xff0c;为了满足需求将以太网引进到车载网络中。车载以太网在诊断传输层的应用协议是ISO 13400&#xff08;Diagnostic On IP—DoIP&#xff09;…

模型实战(1)之YOLOv5 实现目标检测+训练自己的数据集

模型实战&#xff08;1&#xff09;之YOLOv5 实现目标检测训练自己的数据集 写一个小总结吧&#xff0c;关于yolov5使用可以参考我的两外两篇博文&#xff1a; 1.YOLOV5算法一之Windows10下yolov5安装测试并训练自己的数据集 2.YOLOV5算法二之数据集转换及自动划分训练集与测试…

代理模式之提出问题和代理模式的概念

代理模式之提出问题和代理模式的概念 1. 提出问题 ①现有代码缺陷 针对带日志功能的实现类&#xff0c;我们发现有如下缺陷&#xff1a; 对核心业务功能有干扰&#xff0c;导致程序员在开发核心业务功能时分散了精力 附加功能分散在各个业务功能方法中&#xff0c;不利于统一…

docker创建带有用户密码认证和web可视化界面的私有仓库

docker-registry的搭建 有时候使用Docker Hub这样的公共仓库可能不方便&#xff0c;用户可以创建一个本地仓库供私人使用。比如&#xff0c;基于公司内部项目构建的镜像。 docker-registry是官方提供的工具&#xff0c;可以用于构建私有的镜像仓库。 安装运行docker-registry…

Go语言设计与实现 -- 上下文

我们先来看一下context.Context的接口&#xff1a; // A Context carries a deadline, a cancellation signal, and other values across // API boundaries. // // Contexts methods may be called by multiple goroutines simultaneously. type Context interface {// Deadl…

【TypeScript】TS接口类型(三)

&#x1f431;个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️作者简介&#xff1a;前端领域新星创作者、华为云享专家、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff…

modnet:real-time trimap-free portrail matting via objective decomposition

目前抠图&#xff08;Image Matting&#xff09;的主流算法有哪些&#xff1f; - 知乎什么是抠图对于一张图I&#xff0c; 我们感兴趣的人像部分称为前景F&#xff0c;其余部分为背景B&#xff0c;则图像I可以视为F与B的加权…https://www.zhihu.com/question/68146993/answer/…

SpringCloud-Gateway配置及持久化、过滤器、异常处理

文章目录yml配置代码配置持久化数据结构predicates(断言) 和filters&#xff08;过滤&#xff09;新增配置说明相关接口全局过滤器局部过滤器全局异常处理gateway不能和web一起使用 需要排除掉<dependency><groupId>org.springframework.cloud</groupId><…

【Unity】Delegate, Event, UnityEvent, Action, UnityAction, Func 傻傻分不清

【Unity】Delegate, Event, UnityEvent, Action, UnityAction, Func 傻傻分不清Delegate 委托&#xff0c;函数指针一个简单的例子&#xff1a;一对一依赖一个简单的例子&#xff1a;一对多依赖所以话说……委托有啥用呢&#xff1f;事件 Event&#xff0c;特殊的委托UnityEven…

Failed to read artifact descriptor for XXX.jar错误分析

今天遇到极其恶心的坑&#xff0c;自己定义编写的工具类&#xff0c;之前使用一直没有问题&#xff0c;正常引入pom文件中&#xff0c;也能正常的使用工具类中自建类。今天就是无法导入包&#xff0c;报错信息如下。 Failed to read artifact descriptor for com.yuxuntoo.www…

JavaScript篇.day03-循环结构(while, for)

目录 1.循环结构 2.例题 (1)奇数乘积(while/do-while) (2)水仙花数(while) (3)最大公约数(for) (4)最小公倍数(for) (5)打印星星(for) (6)乘法表(for) 1.循环结构 循环结构在程序中可执行多次循环结构有while循环, do-while循环, for循环 名称执行顺序循环执行次数应用…

wireshark练习抓取网络数据包用C编程完成modbus协议,从云端服务器读取温湿度数据。

文章目录前言一、疯狂聊天室1、配置网络2、创建房间3、互发消息二、wireshark抓取网络数据包1.找到对应的包2、分析抓取包中的信息三、Modbus协议概述1、Modbus主/从协议原理2、通用Modbus帧结构---协议数据单元(PDU)3、两种Modbus串行传输模式4、ModbusTCP通信结构四、C编程完…

零基础自学网络安全,如何3个月快速入门?

说到自学网络安全这一块&#xff0c;我来给大家分享一下我的经验。 一、了解相关网站 在入这行之前&#xff0c;我是先泡了一段时间网络安全相关的论坛&#xff0c;了解行业的信息&#xff0c;也可以确认自己是否真的想做这一行&#xff0c;毕竟这一行看起来很炫酷&#xff0…

Python编程 内置文件中常用方法

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.函数 &#xff08;1&#xff09;range() &#xff08;2&#xff09;zi…

做自动化测试3年,薪资为何会被应届生倒挂?

各位职场人都听说过薪资倒挂这词儿吧&#xff0c;这个情况在行业内早就不是什么稀罕事了&#xff0c;我有一个认识的&#xff0c;作为公司3年工龄的软件测试老员工&#xff0c;技术过关&#xff0c;能够独立工作&#xff0c;并且思考优化方向&#xff0c;我不吹牛的说&#xff…

【STL学习之路】vector的使用

文章目录vector介绍vector使用一、构造函数二、迭代器三、vector增删查改关于STL中参数的分析&#xff08;以push_back为例&#xff09;sort算法和仿函数使用vector介绍 vector就是顺序表的封装&#xff0c;是一个模板类&#xff0c;如上图所示。为方便vector里可以存任何数据类…

ChatGPT 免账号使用

一.ChatGPT 简介 ChatGPT是人工智能研究实验室OpenAI新推出的一种人工智能技术驱动的自然语言处理工具&#xff0c;使用了Transformer神经网络架构&#xff0c;也是GPT-3.5架构&#xff0c;这是一种用于处理序列数据的模型&#xff0c;拥有语言理解和文本生成能力&#xff0c;尤…