QuecPython+蜂窝模组基础开发
开发准备
硬件:
- 一块 QuecPython_EC2X_EVB 开发板 (以该开发板为例,更多开发板介绍参见下文开发板列表)
- USB 数据线 (USB-A TO USB-C)
- PC (Windows10)
蜂窝模组开发板列表:
- EC2X_EVB
- EC600X_EVB
- EC800X_EVB
- EC600X/EC800X_CORE_EVB
- BG95_EVB
- EC200X_EVB
- EG91X_EVB
- EC600U_235_EVB
- BG95/EG915U/EG912U_CORE_EVB
- EC800G_HUA_EVB
- EC800X_DUINO_EVB
- EC800X_PICO_EVB
软件:
- 下载安装 USB驱动,用于开发调试QuecPython模组
- 下载调试工具 —— QPYcom - QuecPython全栈式开发调试工具
- 获取下载 QuecPython 固件和相关软件资源
- 安装Python语言的 文本编辑器,例如 VSCode
设备上手:
根据使用的设备参考上文的开发板列表完成设备的上电开机(包括天线安装、SIM卡安装、连接电源、开机等)
驱动准备
驱动下载
驱动程序(device driver)全称为“设备驱动程序”,是一种可以使计算机和设备通信的特殊程序,操作系统只能通过这个接口,才能控制硬件设备的工作。
- 打开QuecPython官网驱动下载链接
- 进入页面后先选择驱动栏,然后在驱动栏选择与自己模组型号和电脑系统匹配的驱动,不同平台的模组所需要的驱动程序不一致,需要根据模组型号去下载对应的驱动包
- 模组型号可以通过模组上的镭雕获取,也可以通过AT指令获取,镭雕如下图所示,镭雕上型号为EG912U
- 左侧筛选栏选择
EG912U
,可以筛选出该型号的USB驱动QuecPython_USB Driver Win10_U_G)点击下载按钮下载驱动:
模组型号 | 操作系统 | 驱动名称 |
---|---|---|
BG95 BG600L | Win10 | QuecPython_USB_Driver_Win10_BG |
EC800E EC600E EC800Z | Win10 | QuecPython_USB_Driver_Win10_E |
EG912N EG915N UC200A EC600K EG810M EC800K EG800K EC200N EC800M EC600N EC600M EC200A | Win10 | QuecPython_USB_Driver_Win10_ASR |
EG915U EC200U EC800G EC600U EC600G EC800G | Win10 | QuecPython_USB_Driver_Win10_U_G |
驱动安装
下载后解压驱动压缩包,找到"setup.exe" 或者是"setup.bat",双击运行即可,安装完之后打开设备管理器就可以看到设备管理器中端口的黄色感叹号消失了,说明安装成功,能够正常通信。
出现 Mobile ECM Network Adapter 或 CDC Ethernet Control Modle (ECM) 等设备未被识别属于正常现象,不影响固件烧录和后续开发,无需理会。
右键打开【我的电脑】——选择【管理】——选择【设备管理器】,然后在设备管理器中选择 【端口】
按照步骤打开页面后如图所示能刷新出Quectel USB 名称开头的串口则USB驱动安装成功
安装驱动后:
驱动安装常见问题参考: 开发环境与工具相关问题
获取工具
QPYcom获取
使用QuecPython进行开发需要用到专用的开发调试工具——QPYcom,包括但不限于调试代码、分析日志、文件传输、烧录固件、合并固件等。
QPYcom : 适用于QuecPython开发的一站式调试工具
注意:该工具无需安装,解压即用。
安装VSCode插件
编辑Python代码一般会用到专用于Python或者兼容多种语言的IDE,可以有效提升开发效率,这里推荐VSCode
针对VScode,QuecPython推出专用插件实现代码提示、代码补全和串口调试等功能,安装方法见下图
- 在VSCode中点击侧边栏插件市场,在插件市场中搜索 “QuecPython”,根据搜索结果下载该插件即可
- 在VSCode插件商店网站 搜索“QuecPython”,根据搜索结果下载该插件后会自动打开VSCode并安装
固件烧录
获取固件
模组在出厂时通常烧录有标准 AT 固件或 QuecOpen 固件,如需基于 QuecPython 对模块进行开发,需要手动为其重新烧录专门的 QuecPython 固件。
官网固件下载地址:资源下载 | QuecPython
面对官网种类众多的固件,如何选择合适的固件包,首先需要知道使用的模组的型号,模组型号可以通过模组的镭雕或者发送AT指令来获得。
在获取到模组型号之后根据模组的型号去官网下载该模组对应的固件即可。
固件的名称一般为QPY_OCPU_模组型号_FW
,例如QPY_OCPU_EC800M_CNGC_FW,如果是EC800M_CNGC的模组就可以下载这个固件,并且可以在版本这一列选择想要下载的固件版本,固件的版本号格式统一为V+四位数版本号
,例如V0001
点击下载列的下载按钮即可下载,下载成功后会得到一个固件名称命名的压缩包文件(zip包)
从官网下载的固件包为压缩包格式,固件压缩包下载到本地后,需进行解压。解压后可获得两个文件,其中 .bin 、.lod或 .pac 格式的是 QuecPython 固件本体,.md 格式的是更新日志。
固件解压后的本体文件有以下后缀区分(官网发布日期于2024.05.20之后的固件,所有模组型号固件已统一为.bin后缀)
固件下载文件名称后缀 | 固件文件对应模组型号 | 备注 |
---|---|---|
zip、bin | EC600M、EC600N、EG915N、EC200N、EG810M | 固件压缩包解压后可得 |
pac | EC600U、EC200U、EG912U、EC800G、EC600G | 固件压缩包解压后可得 |
lod | BC25 | 固件压缩包解压后可得 |
binpkg | EC600E、EC800E | 解压后固件名称同名文件夹内 |
hbinpkg | EC800Z | 解压后固件名称同名文件夹内 |
blf | EC200A | 解压后固件名称同名文件夹内 |
mbn | BG95 | 解压后固件名称同名文件夹内 |
请务必将压缩包内容解压至一个不包含中文、空格和其他特殊字符的路径下,否则下载工具可能无法正常识别到固件,同时下载工具路径也不可包含中文、空格和其他特殊字符。
烧录固件
- Step1:创建项目
首先确保模组连接正常并已开机,打开QPYcom工具进入下载页面,点击"创建"项目,新建要下载的固件项目,项目名称自定义,配置完成后持久化保存
- Step2:选择固件
选择要下载到模组的固件(根据要下载的模组型号选择对应的固件,若为新格式固件则所有模组型号都选择.bin文件即可)
其中BG95系列选择官网下载固件包解压后mbn结尾的文件,M/N系列选择官网下载固件包解压后的bin文件,U/G系列模组选择解压后的PAC文件,BC25选择lod文件,A系列选择blf文件,E系列选择binpkg文件
- Step3:设置下载模式
单击“Download script”右侧的下拉选择箭头,选择"Download FW"
- Step4:开始烧录固件
点击"Download FW"后,开始下载固件,下载过程会有进度条和进度百分比显示,等待下载完毕会有弹窗提示下载成功
模组型号 | 注意事项 |
---|---|
BC25 | 需要打开固件下载串口后再点击"Download FW",直接点击会提示打开串口 |
BG95 | 需要打开DM串口后再点击"Download FW",直接点击会提示打开串口 |
FCM360W | 需要打开串口后点击"Download FW"后等待进度条出现后再按下开发板“RESET”按钮开始下载固件 |
EC600E | 需要短接开发板 BOOT 和 GND 并按下开发板“RESET”按钮出现下载口后,立即点击"Download FW"开始下载固件 |
EC800E | 需要短接开发板 EXT 和 GND 并按下开发板“RESET”按钮出现下载口后,立即点击"Download FW"开始下载固件 |
EC800Z | 需要短接开发板 BOOT 和 EXT 并按下开发板“RESET”按钮出现下载口后,立即点击"Download FW"开始下载固件 |
REPL调试
REPL全称为Read-Eval-Print-Loop (交互式解释器),可以在REPL中进行QuecPython程序的调试
运行 QPYcom 工具后,选择正确的串口(波特率无需指定)并打开,即可开始 Python 命令行交互。
- Step1:进入交互页面
进入交互页面首先需要打开USB交互口,注意不同平台交互口名称有差异
以EC600N/M系列模组举例,打开QPYcom工具,端口选择连接Quectel USB REPL Port,选择“交互”界面
模组 | 交互口名称 | 驱动名称 |
---|---|---|
EC600N/M EC200A | Quectel USB REPL Port | QuecPython_USB_Driver_Win10_ASR |
EC200U EC600U/G EG800G EG912U EG915U | Quectel USB REPL Port | QuecPython_USB_Driver_Win10_U_G |
BG95/BG600L | Quectel USB REPL Port | QuecPython_USB_Driver_Win10_BG |
EC600E,EC800E | Quectel USB 串行设备 | QuecPython_USB_Driver_Win10_E |
注意只有使用最新版本的固件和新版本的驱动才会显示 Quectel USB REPL Port
在老版本的固件和驱动上串口的显示名称会根据平台的不同有所区别
其中U、G系列模组交互口名称为Quectel USB Serial-1 Port
N/M、A系列模组交互口名称为Quectel USB MI05 COM Port
BG95、BG600L系列模组交互口名称为Quectel USB NEMA Port
- Step2:打开串口
点击“打开串口”按钮,在交互界面输入print(‘hello world’),按回车后可以看到执行的结果信息
<span style="color:#262626"><span style="background-color:#ffffff"><span style="background-color:#2d2d2d"><span style="color:#cccccc"><code class="language-python"><span style="color:#67cdcc">>></span><span style="color:#67cdcc">></span> <span style="color:#cc99cd">print</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'hello world'</span><span style="color:#cccccc">)</span>
hello world
</code></span></span></span></span>
注意:工具交互页面输入时需要输入英文字符,中文字符将会被屏蔽
开发第一个脚本
编写第一个脚本文件
创建helloworld.py文件输出“hello world”,打印“hello world”,编写脚本如下所示:
<span style="color:#262626"><span style="background-color:#ffffff"><span style="background-color:#2d2d2d"><span style="color:#cccccc"><code class="language-python"><span style="color:#cc99cd">print</span><span style="color:#cccccc">(</span><span style="color:#7ec699">"hello world"</span><span style="color:#cccccc">)</span>
</code></span></span></span></span>
通过QPYcom将上面编辑好的文件下载到模组中去并运行
PC与模组间的文件传输
下载方法一:
- Step1:打开串口
首先选择模组的交互口,点击"打开串口"按钮
- Step2:通过工具按钮下载
可以通过文件页面右侧上面的 "+","-" 按钮来上传和删除文件
- Step3:通过拖拽形式下载
也可以通过拖拽的方式将文件页面左侧显示的本地文件直接拖拽到右侧模组中去(也可以拖拽文件夹)
- Step4:下载进度和结果
下载过程中会在状态栏显示下载文件名和下载进度
下载方法二:
- Step1:创建项目
根据需求,创建用户项目(点击"创建"按钮),步骤同上文烧录固件
- Step2:配置要下载的文件
选择需要下载到模块的用户脚本(在"用户脚本"区域通过右键菜单添加)
- Step3:设置下载模式
左击下拉选择箭头,选择"下载脚本",即"Download Script"
- Step4:开始下载脚本
点击"下载脚本"开始下载脚本,下载过程中有进度条提示
执行脚本文件
- Step1:下载脚本
将要执行的脚本文件下载到模组中去,具体步骤参考上文
- Step2:通过repl执行脚本
打开串口之后,在QPYcom交互页面输入以下代码执行脚本文件
<span style="color:#262626"><span style="background-color:#ffffff"><span style="background-color:#2d2d2d"><span style="color:#cccccc"><code class="language-python"><span style="color:#cc99cd">import</span> example
example<span style="color:#cccccc">.</span><span style="color:#cc99cd">exec</span><span style="color:#cccccc">(</span><span style="color:#7ec699">"/usr/helloworld.py"</span><span style="color:#cccccc">)</span> <span style="color:#999999"># filePath为要执行的脚本文件路径</span>
</code></span></span></span></span>
- Step3:通过GUI工具执行脚本
或者通过QPYcom文件页面 执行 按钮执行脚本文件,在工具的文件页面选择要执行的脚本文件然后点击 "▷"按钮
执行结果如图
停止程序运行
如何停止正在运行的程序,根据运行的脚本文件类型有以下方法:
程序名是否 为main.py | 程序中是否 包含了死循环 | 程序中是否 使用了多线程 | 停止步骤 |
---|---|---|---|
✓ | ✓ | ✓ | (1)按 Ctrl + A 键进入 RAW 模式 (2)按 Ctrl + D 键重启 QuecPython 虚拟机 (3)按 Ctrl + B 键回到普通交互模式 (4)若以上方法无效,请重新烧录固件 |
✗ | (1)按 Ctrl + C 键打断程序运行 (2)若以上方法无效,请重新烧录固件 | ||
✗ | ✓ | (1)按 Ctrl + A 键进入 RAW 模式 (2)按 Ctrl + D 键重启 QuecPython 虚拟机 (3)按 Ctrl + B 键回到普通交互模式 (4)若以上方法无效,请耐心等待程序运行结束 | |
✗ | (1)按 Ctrl + C 键打断程序运行 (2)若以上方法无效,请重新烧录固件 | ||
✗ | ✓ | ✓ | (1)按 Ctrl + D 键重启 QuecPython 虚拟机 (2)若以上方法无效,请直接重启模块 |
✗ | (1)按 Ctrl + D 键重启 QuecPython 虚拟机 (2)若以上方法无效,请直接重启模块 | ||
✗ | ✓ | (1)按 Ctrl + C 键打断程序运行 (2)若以上方法无效,请重新烧录固件或直接重启模块 | |
✗ | (1)按 Ctrl + C 键打断程序运行 (2)若以上方法无效,请重新烧录固件或直接重启模块 |
蜂窝基础开发
本章节主要介绍 QuecPython 模组的拨号上网流程,拿到模组后如何注网拨号以及网络异常的处理等
QuecPython 拨号上网流程
设备硬件连接
首先按照上文的硬件准备步骤安装开发板配套的天线(部分开发板型号有板载天线的不需要安装),并将SIM卡插入开发板上的SIM卡座,然后将模组连接电源并开机,开机后模组会自动进行网卡激活。
获取拨号信息
QuecPython的模组默认开机都会自动激活第一路蜂窝无线网卡,只有蜂窝无线网卡激活成功,才能进行socket、http、mqtt等网络业务。
所以在业务动作之前需要先获取拨号信息,包括拨号状态、IP地址、DNS服务器地址等,以此来判断网卡是否激活成功
import dataCall
dataCall.getInfo(profileID, ipType)
# profileID - PDP上下文ID,整型值,范围1~3。
# ipType - IP协议类型,整型值,0:IPV4 1:IPV6 2:IPV4&IPV6
返回值格式为
(profileID, ipType, [state, reconnect, addr, priDNS, secDNS])
查询网卡状态信息这一操作,是用户必须进行的。不管是什么应用场景,只要用户需要进行网络业务操作,就必须先查询网卡激活状态,确认蜂窝无线网卡已经激活成功。具体而言,只要用户有如下需求,都需要使用dataCall.getInfo
来查询:
- 确认蜂窝无线网卡激活是否成功,通过
dataCall.getInfo
方法返回值的state来确定,为1表示激活成功。 - 用户使用QuecPython的socket功能时,需要知道模组当前的IP地址。
- 激活多路蜂窝无线网卡后,需要建立多路socket,不同的socket使用不同的网卡,此时需要获取每一路网卡的IP地址信息,然后与对应的socket进行绑定。
- 获取蜂窝无线网卡当前使用DNS地址。
如果获取拨号信息发现网卡激活失败则需要手动激活网卡
手动激活网卡
经过上述的查询处理后如果网卡激活失败则需要手动激活网卡,使用如下的API来手动激活网卡
dataCall.activate(profileID)
# profileID - PDP上下文ID,整型值,范围1~3。
QuecPython的模组默认开机都会自动激活蜂窝无线网卡,正常情况无需手动设置激活或者去激活操作,但是一些特殊场景或者用户的特殊需求,需要使用上述方法来手动激活或者去激活蜂窝无线网卡,比如:
用户关闭了开机自动激活蜂窝无线网卡功能,由用户应用程序根据需要在某个时间进行网卡的激活和去激活操作。这种情况下,就需要用户在其应用程序中,根据需要来调用dataCall.activate
和dataCall.deactivate
方法。
获取SIM卡状态
如果模组蜂窝无线网卡手动激活失败,需要依次排查SIM卡和注网状态,查询SIM状态需要使用以下API来获取
import sim
sim.getStatus()
如果sim.getStatus()
的返回值为0,说明设备没有检测到SIM卡,此时需要确定是否插入了SIM卡。如果用户已经插入SIM卡并且重启设备后,查询状态值还是0,那可能的原因如下:
- SIM卡没有插好,比如插反了、没有插紧。可以重新插入SIM卡并重启设备,开机后再次查询SIM卡状态是否为1。
- SIM卡本身有损坏。可以换一张可以正常使用的SIM卡插入后,重启设备,然后再次查询SIM卡状态是否为1。
- SIM卡卡槽有损坏。如果确认是这个问题,则需要更换新的卡槽。
- SIM卡的硬件电路存在问题,比如接触不良,导致设备无法正常识别SIM卡。需要硬件工程师检查电路确认问题。
用户可以依次排查上面几种情况来确认问题。
如果返回值为1,说明已经检测到SIM卡,则需要检测注网状态
其他状态的SIM卡异常参考SIM卡异常处理
获取设备网络注册状态
设备的蜂窝无线网络注册状态是非常重要的参数。成功激活蜂窝无线网卡的前提,就是设备必须先注网成功。QuecPython提供了相关API用来查询设备的注网状态。通过该API可以查询当前设备的网络状态
import net
net.getState()
API返回值为
([voice_state, voice_lac, voice_cid, voice_rat, voice_reject_cause, voice_psc], [data_state, data_lac, data_cid, data_rat, data_reject_cause, data_psc])
其中data_state为网络注册状态,网络注册状态有多种情况,当返回值为1或者5时可视为网络注册成功,具体返回值参考获取网络注册信息,当网络注册状态不为1或5的情况,可视为网络异常,导致网络异常的原因可能有多种,比方说SIM卡欠费、SIM卡只支持特定网络制式或者特定频段等、射频性能不好、没有配置APN等,以上异常的情况的详细处理步骤参考模块网络注册失败
正常情况下,只要模组网卡能激活成功,用户是不需要查询注网状态的。需要查询设备注网状态的场景主要如下:
- 模组蜂窝无线网卡激活失败,需要依次排查SIM卡和注网状态。此时可以使用
net.getState
来查询注网状态,确认设备注网有没有成功,如果注册网络状态异常则需要按照上述步骤继续检查。
网络状态检测
QuecPython提供了检测网络状态的API接口,可以用于检测网络状态是否已经就绪。
checkNet.waitNetworkReady(timeout)
等待模组网络就绪。该方法会依次检测SIM卡状态、模组网络注册状态和PDP Context激活状态;在设定的超时时间之内,如果检测到PDP Context激活成功,会立即返回,否则直到超时才会退出。可以直接使用该API接口来检测网络代替上文的检测SIM卡状态、模组网络注册状态和PDP Context激活状态三个步骤,如果检测出对应步骤有异常再去对异常的部分进行检测处理
参数描述:
timeout
- 超时时间,整型值,范围1~3600秒,默认60
秒。
返回值描述:
返回一个元组,格式为:(stage, state)
参数 | 类型 | 含义 |
---|---|---|
stage | 整型 | 表示当前正在检测什么状态: 1 - 正在检测SIM卡状态; 2 - 正在检测网络注册状态; 3 - 正在检测PDP Context激活状态。 |
state | 整型 | 根据stage值,来表示不同的状态,具体如下: stage = 1时,state表示 SIM卡的状态,范围0-21,每个状态值的详细说明,请参考sim.getStatus()方法的返回值说明; stage = 2时,state表示网络注册状态,范围0-11,每个状态值的详细说明,请参考net.getState()方法的返回值说明; stage = 3时,state表示PDP Context激活状态,0表示没有激活成功,1表示激活成功。 |
异常处理
网络异常分为两种。一种是在开机时发生网络异常,一种是开机已经注网成功,然后在后续的业务处理过程中网络异常
设备开机时的网络异常处理
模组开机时的网络异常,主要包括3种情况,分别是:
- SIM卡异常
- 模组网络注册失败
- 蜂窝无线网卡自动激活失败
这3种情况导致的直接结果,就是模组无法连接到网络。因此我们将这些情况都称之为“网络异常”,以上三种异常情况的检查和处理流程参见上文。
设备运行过程中网络异常处理
蜂窝无线网卡激活成功后,用户的应用程序还需要关注一件事——设备与网络的连接状态。这是因为在设备运行过程中,可能会因为一些异常原因(如网络异常、环境干扰、信号差等)导致模组与网络的连接断开。如果用户应用程序没有关注这种网络事件,很可能导致用户应用程序中和网络相关的业务执行异常,导致出现无法预料的问题。
QuecPython提供了网络事件监听功能,用户应用程序可以通过注册回调函数的方式来监听网络状态变化事件。当设备与无线网络的连接状态发生变化时,系统就会自动将对应的事件通过用户注册的回调函数,推送给用户的应用程序。
注册网络监听回调函数的方法如下:
dataCall.setCallback(fun)
回调函数的示例如下:
def netCallback(args):profileID = args[0]netState = args[1]if netState == 0:print('### network {} disconnected.'.format(profileID))elif netState == 1:print('### network {} connected.'.format(profileID))
该回调函数的参数是一个元组,包含3个元素,目前用户只需要关注前两个元素即可。前两个参数说明如下:
参数 | 类型 | 说明 |
---|---|---|
args[0] | 整型 | 蜂窝无线网卡编号,表示当前是哪一路无线网卡的网络连接状态发生了变化。 |
args[1] | 整型 | 网络状态,0表示网络连接断开,1表示网络连接成功。 |
建议用户注册该回调函数,用于监听网络连接状态,确保当网络连接状态发生变化时,用户应用程序可以根据网络状态变化进行及时的处理。通常,我们可以参考下面的方式来处理:
- 回调函数中收到网络连接状态发生变化的事件后,通过消息队列功能将网络事件发送给其他线程去处理。当然,用户也可以使用QuecPython的
sys_bus
功能来代替消息队列。 - 其他线程在收到网络事件时,判断如果是网络连接断开事件,则停止socket、mqtt等这类和网络相关的业务。同时,该线程也可以选择启动一个定时器,比如先将定时器时间设定为60s。如果60s后,网络还没有恢复,则执行CFUN0/1切换,然后看网络是否可以恢复。
什么是CFUN0/1切换?
通过《蜂窝网络基础概念》章节中关于CFUN的说明,可以知道,CFUN指的是移动终端的功能模式。CFUN0/1切换是指通过
net.setModemFun(0)
方法先将设备切换到模式0(最小功能模式),然后再通过net.setModemFun(1)
方法将设备切换到模式1(全功能模式)。当切换到模式0,设备的整个射频网络协议栈全部关闭,SIM卡模块停止供电;再次切换到模式1时,会重新恢复对SIM卡的供电并重新进行初始化,同时与射频相关的软硬件功能都会重新开启,此时设备会重新发起网络注册流程。为什么要进行CFUN0/1切换?
QuecPython具有自动重连功能,如果发生网络异常导致设备与网络的连接断开,异常消失后,不是应该自动恢复吗?为什么上面提到的处理方式中,还要进行CFUN0/1的切换?
我们需要搞清楚,QuecPython的自动重连功能指的是在网络异常恢复后,模组自动重新激活无线网卡,而不是重新注册到网络。设备的网络注册行为是由系统的射频网络协议栈自动控制的,理论上在网络异常因素消失后,射频网络协议栈会自动重新发起网络注册。但是不排除因为一些原因,导致设备没有及时重新进行网络注册的情况。这时因为设备网络注册尚未成功,无线网卡也无法重新激活。因此,我们主动进行了CFUN0/1的切换操作。其实就像是我们平时使用手机时,有时候遇到网络差或者没信号的时候,我们会选择先关闭手机的移动网络,然后再重新打开是一样的道理。当然,用户也可以选择进行重启。
相关文章:
QuecPython+蜂窝模组基础开发
开发准备 硬件: 一块 QuecPython_EC2X_EVB 开发板 (以该开发板为例,更多开发板介绍参见下文开发板列表)USB 数据线 (USB-A TO USB-C)PC (Windows10) 蜂窝模组开发板列表: EC2X_EVBEC600X_EVBEC800X_EVBEC600X/EC800X_CORE_EVBBG95_EVBEC200X_EVBEG91…...
-MAC桢-
MAC桢和IP的关系: 主机A想跨网络和B通信需要IP地址进行路由选择,但一个局域网,比如路由器进行路由选择之前,首先要将数据包发送给路由器B,也就是局域网通信也就是同一个网段的主机进行通信,所以必须通过mac…...
反转链表 - 简单
************* C topic: 206. 反转链表 - 力扣(LeetCode) ************* Give the topic an inspection. It seems really easy. At very first, I think that I will use reverse cammand to kill this topic. But a few seconds later I found that…...
负载均衡 ELB 在 zkmall开源商城高流量场景下的算法优化
在电商大促、直播带货等高频交易场景下,流量突发增长对系统稳定性提出严峻挑战。ZKmll 开源商城通过对负载均衡 ELB(Elastic Load Balancer)算法的深度优化,结合业务场景特性设计动态加权轮询 地域感知 热点分流的混合策略&…...
YOLOv5推理代码解析
代码如下 import cv2 import numpy as np import onnxruntime as ort import time import random# 画一个检测框 def plot_one_box(x, img, colorNone, labelNone, line_thicknessNone):"""description: 在图像上绘制一个矩形框。param:x: 框的坐标 [x1, y1, x…...
创建三个网络,分别使用RIP、OSPF、静态,并每个网络10个电脑。使用DHCP分配IP
DHCP 自动分配IP,集中管理,提高效率 在路由器中设置 Router>en Router#conf t Router(config)#ip dhcp pool ip30 //创建DHCP地址池 Router(dhcp-config)#network 192.168.30.0 255.255.255.0 // 配置网络地址和子网掩码 Router(dhcp-config)#defa…...
[网络层]网络层设备路由器
路由表 路由器能进行路由转发,所依靠的核心数据结构就是路由表,那么路由表是怎么来的, 静态路由和动态路由: 说的是表项,这个表项是静态的还是动态的,就跟ARP缓存表的表项静态动态是一回事, …...
Maven 项目中将本地依赖库打包到最终的 JAR 中
文章目录 前言详细步骤 前言 在现代后端开发中,构建高效且可扩展的 Web 应用程序通常依赖于多种第三方库和内部依赖。这些依赖可以来自公共仓库,也可能是公司内部自研的库或尚未发布到公共仓库的 JAR 包。本文将详细介绍如何在 Maven 项目中处理本地依赖…...
大模型的Lora如何训练?
大模型LoRA(Low-Rank Adaptation)训练是一种参数高效的微调方法,通过冻结预训练模型权重并引入低秩矩阵实现轻量化调整。以下是涵盖原理、数据准备、工具、参数设置及优化的全流程指南: 一、LoRA的核心原理 低秩矩阵分解 在原始权重矩阵$ W 旁添加两个低秩矩阵 旁添加两个…...
CSS3 伪类和使用场景
CSS3 伪类(Pseudo-classes)大全 CSS3 引入了许多新的伪类,以下是完整的 CSS3 伪类分类列表(包括 CSS2 的伪类): 一、结构性伪类(Structural Pseudo-classes) 这些伪类根据元素在文…...
GitDiagram - GitHub 仓库可视化工具
GitDiagram - GitHub 仓库可视化工具 项目链接:https://github.com/ahmedkhaleel2004/gitdiagram 将任何 GitHub 仓库转换为交互式架构图,只需替换 URL 中的 hub 为 diagram。 ✨ 核心功能 即时可视化:将代码库结构转换为系统设计/架构图…...
[特殊字符] 本地大模型编程实战(29):用大语言模型LLM查询图数据库NEO4J(2)
本文将基于langgraph框架,用LLM查询NEO4J图数据库,构建可定制、能应对复杂场景的工作流! 🌟 核心亮点 是否用户提问是否电影相关?生成Cypher查询直接回答执行查询生成最终答案 🧩 模块化实现 1️⃣ 定义状态机 from …...
Python中操作Neo4j图数据库
在当今数据驱动的时代,关系型数据库在处理高度关联的数据时常常显得力不从心。图数据库,尤其是Neo4j,以其独特的图结构和高效的关系查询能力,成为了解决这一问题的利器。结合Python的简洁与强大,我们可以更高效地构建和…...
人工智能时代:解锁职业新身份,从“认证师”到“工程师”的进阶之路
在人工智能技术浪潮席卷全球的今天,技术的飞速迭代正在重塑职业版图。从算法优化到伦理决策,从系统测试到应用开发,AI技术不再只是程序员的专属领域,而是成为各行各业从业者必须掌握的“生存技能”。当企业争相布局AI赛道,个人如何在这场变革中抢占先机?答案或许藏在两个…...
浙江大学 deepseek 公开课 第三季 第3期 - 陈喜群 教授 (附PPT下载) by 突破信息差
浙江大学DeepSeek系列公开课第三季重磅开启,特邀该校多领域权威学者联袂主讲。课程聚焦AI技术如何重构基础学科研究范式,深度解码以DeepSeek为代表的智能模型在交叉学科中的创新应用。在"XAI"融合浪潮下,学术大咖将剖析传统学科与人…...
企业级商城系统容器化部署技术方案
容器化部署已成为企业级商城系统构建高可用、弹性架构的核心技术。结合行业实践与技术趋势,以下从架构设计、工具链选型、关键挑战及解决方案等维度,提供一套完整的实施技术方案: 一、架构设计与技术选型 微服务架构拆分 服务拆分原则&#x…...
Java设计模式之适配器模式:从入门到精通
适配器模式(Adapter Pattern)是Java中最常用的结构型设计模式之一,它像一座桥梁连接两个不兼容的接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作。本文将全面深入地解析适配器模式,从基础概念到高级应用,包含丰富的代码示例、详细注释、使用场景分析以及多维对…...
Spark,RDD中的转换算子
RDD中的转换算子 map算子 对数字1-10进行乘除,*2 filter算子 对数字1-10进行过滤,过滤出偶数 filatMap算子 对单词进行拆分 reduceByKey算子 对具有相同键的所有值进行聚合操作 统计词频词频统计简洁写法 ———————————————— 版权声明…...
牛客周赛 Round 92(再现京津冀蓝桥杯???)
1. 小红的签到题 现在小红希望你写出一个长度为 nnn 的、使用了下划线命名法命名的变量。为了显出特征,请保证该变量至少由两个单词组成。 输入描述: 输入一个正整数 n(3≦n≦100),代表需要构造的变量长度。 输出描述: 输出一个长度为 n 的字符串&#x…...
React 18 的新功能:构建高性能应用的革新之道
React 18 的发布标志着前端开发进入了一个全新的并发时代。作为 React 历史上最重要的版本之一,它不仅带来了底层架构的深度重构,更通过一系列创新功能重新定义了现代 Web 应用的开发范式。这些特性在保持向后兼容的同时,为开发者提供了前所未…...
Python-Flask-Dive
Python-Flask-Dive 适用Python编写一个Flask的快速上手模板,后续如果需要使用Python快速进行we端的验证可以直接下载使用 1-项目创建 本项目仓库代码地址:https://gitee.com/enzoism/python_flask_dive 1-Python环境 ## 1-空工程初始化环境 mkdir my_pr…...
热门CPS联盟小程序聚合平台与CPA推广系统开发搭建:助力流量变现与用户增长
一、行业趋势:CPS与CPA模式成流量变现核心 在移动互联网流量红利见顶的背景下,CPS(按销售付费)和CPA(按行为付费)模式因其精准的投放效果和可控的成本,成为企业拉新与用户增长的核心工具。 CPS…...
16.three官方示例+编辑器+AI快速学习webgl_buffergeometry_lines_indexed
本实例主要讲解内容 这个Three.js示例展示了如何使用**索引几何体(Indexed Geometry)**创建复杂的分形线条图案。通过递归算法生成科赫雪花(Koch Snowflake)曲线,并利用索引缓冲区优化顶点数据存储,实现高效的线条渲染。 核心技术包括: 索…...
PowerBI基础
一、前言 在当今数据驱动的时代,如何高效地整理、分析并呈现数据,已成为企业和个人提升决策质量的关键能力。Power BI 作为微软推出的强大商业智能工具,正帮助全球用户将海量数据转化为直观、动态的可视化洞察。数据的世界充满可能性…...
【MCP】魔搭社区MCP服务(高德地图、everything文件搜索)
【MCP】魔搭社区MCP服务(高德地图、everything文件搜索) 1、上手使用2、环境配置(1)cherry-studio配置(2)添加魔搭大模型服务(如果已经设置了其他大模型服务,可跳过)&…...
适合大数据和宽表的数据存储和分析场景的数据库
适合大数据和**宽表(wide table)**的数据存储和分析场景的数据库,通常需要具备以下几个特性: 支持高吞吐量的写入和读取;能处理百万级列或数百列的宽表结构;良好的压缩和分区能力;支持分布式扩展和容错;一定程度的 SQL 支持或灵活的查询引擎。✅ 推荐数据库类型及代表产…...
ORB特征点检测算法
角点是图像中灰度变化在两个方向上都比较剧烈的点。与边缘(只有一个方向变化剧烈)或平坦区域(灰度变化很小)不同,角点具有方向性和稳定性。 tips:像素梯度计算 ORB算法流程简述 1.关键点检测(使用FAST…...
Node和npm初学
了解Node和npm 目录 1. 什么是 npm? 2. npm有哪些使用场景? 3. npm有什么核心特性? 4.npm的常用命令有那些? 5. 关键配置文件是什么? 6. 安全与最佳实践 7.什么是 Node.js? 8.Node.js有什么优势? 9.如何安装和下载? 10.如何验证安装成功?…...
【android bluetooth 案例分析 03】【PTS 测试 】【PBAP/PCE/SGSIT/SERR/BV-01-C】
1. PBAP/PCE/SGSIT/OFFS/BV-01-C 1. 测试项说明: Please initiate a GATT connection over BR/EDR to the PTS.Description: Verify that the Implementation Under Test (IUT) can initiate GATT connect request over BR/EDR to PTS.测试项名称: Ple…...
VIC-2D 7.0 为平面样件机械试验提供全视野位移及应变数据软件
The VIC-2D系统是一个完全集成的解决方案,它基于优化的相关算法为平面试样的力学测试提供非接触、全场的二维位移和应变数据,可测量关注区域内的每个像素子集的面内位移,并通过多种张量选项计算全场应变。The VIC-2D 系统可测量超过 2000%变形…...
深入理解Embedding Models(嵌入模型):从原理到实战(下)
🐇明明跟你说过:个人主页 🏅个人专栏:《深度探秘:AI界的007》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、什么是 Embedding 2、什么是嵌入模型 二、构建嵌入…...
labview硬件采集
(1)硬件的描述 (2)实验步骤1: (3)实验步骤2 库名/路径的选择要使用32位的开发资料 (4)实验步骤3 (5)实验步骤4 找到DoSetV12() 设置返回类型 设置chan 设置state labv…...
自动驾驶技术栈——DoIP通信协议
一、DoIP协议简介 DoIP,英文全称是Diagnostic communication over Internet Protocol,是一种基于因特网的诊断通信协议。 DoIP协议基于TCP/IP等网络协议实现了车辆电子控制单元(ECU)与诊断应用程序之间的通信,常用于汽车行业的远程诊断、远…...
uniapp引入七鱼客服微信小程序SDK
小程序引入七鱼sdk 1.微信公众平台引入2.代码引入3.在pagesQiyu.vue初始化企业appKey4.跳转打开七鱼客服 1.微信公众平台引入 账号设置->第三方设置->添加插件->搜索 QIYUSDK ->添加 2.代码引入 在分包中引入插件 "subPackages": [{"root":…...
【SSM-SpringMVC(二)】Spring接入Web环境!本篇开始研究SpringMVC的使用!SpringMVC数据响应和获取请求数据
SpringMVC的数据响应方式 页面跳转 直接返回字符串通过ModelAndView对象返回 回写数据 直接返回字符串返回对象或集合 页面跳转: 返回字符串方式 直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转 RequestMapping("/con&…...
【AXI总线专题】AXI-FULL-Master
【AXI总线专题】AXI-FULL-Master 1.axi-full概述2.信号定义3.测试4.仿真波形5.附录clogb2函数axi4中的一些参数解释wishbone总线 6.工程文件 概述 参考文档: 《3-2-03米联客2022版AXI4总线专题-20211123.pdf》 《IHI0022E_amba_axi_and_ace_protocol_spec.pdf》 1.a…...
风车OVF镜像:解放AI开发限制的Ubuntu精简系统
风车OVF镜像:解放AI开发限制的Ubuntu精简系统 AI白嫖续杯一站式-风车ovf AI白嫖续杯一站式解决-风车ovf 前言 作为一名AI开发者,我经常在Windows和Linux环境之间切换开发。然而,Windows平台上的各种免费版限制逐渐成为我工作效率的瓶颈。在寻…...
降低60.6%碰撞率!复旦大学地平线CorDriver:首次引入「走廊」增强端到端自动驾驶安全性
导读 复旦大学&地平线新作-CorDriver: 首次通过引入"走廊"作为中间表征,揭开一个新的范式。预测的走廊作为约束条件整合到轨迹优化过程中。通过扩展优化的可微分性,使优化后的轨迹能无缝地在端到端学习框架中训练,从而提高安全…...
查看购物车
一.查看购物车 查看购物车使用get请求。我们要查看当前用户的购物车,就要获取当前用户的userId字段进行条件查询。因为在用户登录时就已经将userId封装在token中了,因此我们只需要解析token获取userId即可,不需要前端再传入参数了。 Control…...
11 配置Hadoop集群-免密登录
一、复习导入 前面的课程中我们在虚拟机上安装并测试使用了hadoop的示例程序wordcount,并且在准备好了集群的同步工具,那接下来,我们就可去配置hadoop集群了。 二、授新 (一)认识ssh命令 SSH(Secure Shell…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】金融风控分析案例-10.1 风险数据清洗与特征工程
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL金融风控分析案例:风险数据清洗与特征工程实战一、案例背景:金融风控数据处理需求二、风险数据清洗实战(一)缺失值…...
《AI大模型应知应会100篇》第60篇:Pinecone 与 Milvus,向量数据库在大模型应用中的作用
第60篇:Pinecone与Milvus,向量数据库在大模型应用中的作用 摘要 本文将系统比较Pinecone与Milvus两大主流向量数据库的技术特点、性能表现和应用场景,提供详细的接入代码和最佳实践,帮助开发者为大模型应用选择并优化向量存储解…...
如何在通义灵码里使用 MCP 能力?
通义灵码编程智能体支持 MCP 工具使用,根据用户需求描述,通过模型自主规划,实现 MCP 工具调用,并深度集成国内最大的 MCP 中文社区——魔搭 MCP 广场,涵盖开发者工具、文件系统、搜索、地图等十大热门领域 2400 MCP 服…...
关于mac配置hdc(鸿蒙)
关于mac配置hdc(鸿蒙) 在最开始配置的hdc -v时候老是出现格式不匹配 于是乎在网上找官网也不行,最后在csdn上找到了这篇文章Mac配置hdc才有的头绪 环境变量的问题 自己做一个简单的总结 首先在访达里面打开ide 打开之后输入下面的命令,一步一步的找…...
几何_平面方程表示_点+向量形式
三维平面方程可以写成: π : n ⊤ X d 0 \boxed{\pi: \mathbf{n}^\top \mathbf{X} d 0} π:n⊤Xd0 📐 一、几何直观解释 ✅ 平面是“法向量 平面上一点”定义的集合 一个平面可以由: 一个单位法向量 n ∈ R 3 \mathbf{n} \in \mat…...
iOS safari和android chrome开启网页调试与检查器的方法
手机开启远程调试教程(适用于 Chrome / Safari) 前端移动端调试指南|适用 iPhone 和 Android|WebDebugX 出品 本教程将详细介绍如何在 iPhone 和 Android 手机上开启网页检查器,配合 WebDebugX 实现远程调试。教程包含…...
Matlab 模糊pid控制的永磁同步电机PMSM
1、内容简介 Matlab 226-模糊pid控制的永磁同步电机PMSM 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略基于模糊控制的高精度伺服速度控制器的设计与实现_刘京航...
ActiveMQ 高级特性:延迟消息与优先级队列实战(二)
三、优先级队列实战 3.1 优先级队列概念与应用场景 优先级队列是一种特殊的队列,与普通队列按照先进先出(FIFO)的规则不同,优先级队列中的元素按照其优先级进行排序,在消费消息时,高优先级的消息会优先被…...
ActiveMQ 高级特性:延迟消息与优先级队列实战(一)
引言 在当今的分布式系统开发中,消息中间件扮演着至关重要的角色,而 ActiveMQ 作为一款广泛使用的开源消息中间件,凭借其丰富的特性和良好的性能,深受开发者的青睐。它支持多种消息模型,如点对点和发布 / 订阅&#x…...
动手学深度学习12.4.硬件-笔记练习(PyTorch)
以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。 本节课程地址:31 深度学习硬件:CPU 和 GPU【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址&am…...