<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>个人知识汇</title><link>http://www.swwtech.cn/</link><description>工业网络知识分享</description><item><title>[Raspberry PI CM4] 桥接两个物理网卡实现PN故障模拟</title><link>http://www.swwtech.cn/RasperryCM4/EthernetBridge/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;本文介绍如何使用树莓派CM4 + 双网口扩展板 实现PN 故障模拟功能&lt;br&gt;&lt;img style=&quot;max-width:100%;&quot; title=&quot;&quot; alt=&quot;null&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2025/08/202508201005543119019.jpg&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-u521Bu5EFAu6865u63A5-4&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;创建桥接&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;创建桥接&lt;/h2&gt;&lt;br&gt;
本章节介绍如何使用nmcli 工具设置桥接，[参考资料](https://www.raspberrypi.com/documentation/computers/configuration.html#setting-up-a-headless-raspberry-pi &quot;参考资料&quot;) 
&lt;br&gt;

&lt;ul&gt;
&lt;li&gt;创建一个桥接&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nmcli connection add type bridge con-name 'Bridge' ifname bridge0
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;

&lt;ul&gt;
&lt;li&gt;将网卡添加到桥接配置中&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;将eth0 和 eth1 网卡分别添加到桥接&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nmcli connection add type ethernet slave-type bridge con-name 'Ethernet0' ifname eth0 master bridge0

sudo nmcli connection add type ethernet slave-type bridge con-name 'Ethernet1' ifname eth1 master bridge0
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;设置桥接的IP地址&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nmcli connection modify &quot;Bridge&quot; ipv4.method manual ipv4.addresses 192.168.10.50/24
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;启动生效桥接&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nmcli connection up Bridge
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;🍭 配置好后，这些配置重启不会丢失，无需再次配置&lt;/p&gt;
&lt;br&gt;

&lt;h2 id=&quot;h2-u5B89u88C5u7BA1u7406u548Cu914Du7F6Eu6865u63A5u7684u547Du4EE4u884Cu5DE5u5177brctl-45&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;安装管理和配置桥接的命令行工具brctl&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;安装管理和配置桥接的命令行工具brctl&lt;/h2&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo apt install bridge-utils
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;


&lt;h3 id=&quot;h3-u67E5u770Bu5F53u524Du6545u969Cu6A21u62DFu89C4u5219-52&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;查看当前故障模拟规则&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;查看当前故障模拟规则&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo tc -s qdisc show dev eth1
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;

&lt;h3 id=&quot;h3-u6E05u9664u6545u969Cu6A21u62DFu89C4u5219-60&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;清除故障模拟规则&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;清除故障模拟规则&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://github.githubassets.com/images/icons/emoji/exclamation.png&quot; title=&quot;:exclamation:&quot; alt=&quot;:exclamation:&quot; data-emoji=&quot;&quot; class=&quot;emoji&quot;&gt;  设置新规则之前，需要清除之前设置的规则！&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo tc qdisc del dev eth1 root
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;h3-u6865u63A5u6A21u62DFu5EF6u65F6u6296u52A8-67&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;桥接模拟延时抖动&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;桥接模拟延时抖动&lt;/h3&gt;&lt;p&gt;执行以下命令,可模拟eth1网卡延迟+抖动&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PN 周期是4ms的情况下，添加4ms延时，将导致Jitter增大或者单次丢包&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo tc qdisc add dev eth1 root netem delay 4ms 1ms
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;PN 周期是4ms的情况下，添加20ms延时，将导致连续丢包和连接超时断开&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo tc qdisc add dev eth1 root netem delay 20ms 1ms
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;PN 周期是4ms的情况下，添加200ms延时，将导致连接超时断开&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo tc qdisc add dev eth1 root netem delay 200ms 20ms
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;

&lt;h3 id=&quot;h3-u6865u63A5u6A21u62DFu4E22u5305-87&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;桥接模拟丢包&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;桥接模拟丢包&lt;/h3&gt;&lt;p&gt;执行以下命令,可模拟eth1网卡丢包（百分比）&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo tc qdisc add dev eth1 root netem loss 30%
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;

&lt;h3 id=&quot;h3-u6865u63A5u6A21u62DFu5EF6u65F6+u4E22u5305-97&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;桥接模拟延时+丢包&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;桥接模拟延时+丢包&lt;/h3&gt;&lt;p&gt;执行以下命令,可模拟eth1网卡丢包50%&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo tc qdisc add dev eth1 root netem delay 20ms 5ms loss 30%
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;


&lt;h2 id=&quot;h2-u5728u6811u8393u6D3Eu642Du5EFAu7F51u9875u6D4Bu8BD5u73AFu5883u89E6u53D1u6545u969Cu6A21u62DF-108&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;在树莓派搭建网页测试环境触发故障模拟&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;在树莓派搭建网页测试环境触发故障模拟&lt;/h2&gt;&lt;h3 id=&quot;h3-u5B89u88C5flask20uFF08u8F7Bu91CFu7EA7Webu6846u67B6uFF09-110&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;安装flask （轻量级Web框架）&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;安装flask （轻量级Web框架）&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# 创建虚拟环境
python3 -m venv ~/webctrl

# 激活环境
source ~/webctrl/bin/activate

#在虚拟环境中安装 Flask
pip3 install flask
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;h3-u521Bu5EFAu7F51u9875u5185u5BB9-124&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;创建网页内容&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;创建网页内容&lt;/h3&gt;&lt;p&gt;在用户根目录 /home/wef/ 下创建 web_control.py 文件，并编辑&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nano web_control.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入以下内容&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;from flask import Flask, render_template_string, request
import subprocess
app = Flask(__name__)


# HTML页面（内嵌模板）
HTML = '''
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;PN 故障模拟器&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;树莓派控制面板&amp;lt;/h1&amp;gt;
    &amp;lt;button onclick=&quot;runCommand('start2ms')&quot;&amp;gt;抖动&amp;lt;/button&amp;gt;
    &amp;lt;button onclick=&quot;runCommand('start7ms')&quot;&amp;gt;丢包&amp;lt;/button&amp;gt;
    &amp;lt;button onclick=&quot;runCommand('start15ms')&quot;&amp;gt;掉站&amp;lt;/button&amp;gt;
    &amp;lt;button onclick=&quot;runCommand('start100ms')&quot;&amp;gt;频繁掉站&amp;lt;/button&amp;gt;
    &amp;lt;button onclick=&quot;runCommand('stop')&quot;&amp;gt;停止&amp;lt;/button&amp;gt;
    &amp;lt;p id=&quot;result&quot;&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;script&amp;gt;
        function runCommand(cmd) {
            fetch('/run?cmd=' + cmd)
                .then(response =&amp;gt; response.text())
                .then(data =&amp;gt; {
                    document.getElementById(&quot;result&quot;).innerText = data;
                });
        }
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
'''



@app.route('/')
def home():
    return render_template_string(HTML)
@app.route('/run')
def run_command():
    cmd = request.args.get('cmd')
    try:
        if cmd == 'start2ms':
            output = subprocess.check_output(&quot;sudo tc qdisc add dev eth1 root netem delay 3ms 1ms&quot;, shell=True, text=True)
        elif cmd == 'start7ms':
            output = subprocess.check_output(&quot;sudo tc qdisc add dev eth1 root netem delay 7ms&quot;, shell=True, text=True)
        elif cmd == 'start15ms':
            output = subprocess.check_output(&quot;sudo tc qdisc add dev eth1 root netem delay 15ms&quot;, shell=True, text=True)
        elif cmd == 'start100ms':
            output = subprocess.check_output(&quot;sudo tc qdisc add dev eth1 root netem delay 100ms&quot;, shell=True, text=True)
        elif cmd == 'stop':
            output = subprocess.check_output(&quot;sudo tc qdisc del dev eth1 root&quot;, shell=True, text=True)
        else:
            output = &quot;unknow cmd&quot;
        return output
    except Exception as e:
        return f&quot;error: {str(e)}&quot;
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)  # 允许局域网访问
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ctrl+x 保存退出&lt;br&gt;增加文件的执行权限&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo chmod 777 web_control.py
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;h3-flask20u5F00u673Au81EAu542Fu52A8uFF0Cu5E76u6267u884Cweb_control.py20u5185u5BB9-205&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;flask 开机自启动，并执行web_control.py 内容&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;flask 开机自启动，并执行web_control.py 内容&lt;/h3&gt;&lt;p&gt;创建systemd服务：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo nano /etc/systemd/system/web_control.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入以下内容&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;[Unit]
Description=Web Control Service
After=network.target
[Service]

ExecStart=/home/wef/webctrl/bin/python3 /home/wef/web_control.py
Restart=always
[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ctrl+x 保存退出&lt;/p&gt;
&lt;p&gt;启用服务&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo systemctl enable webcontrol.service
sudo systemctl start webcontrol.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入树莓派的IP+端口5000，打开如下界面&lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;max-width:100%;&quot; title=&quot;webserver&quot; alt=&quot;webserver&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2025/08/202508200959156216382.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;可以点击相应的按钮，执行不同故障模拟命令&lt;/p&gt;
&lt;/body&gt;</description><pubDate>Thu, 31 Jul 2025 14:22:54 +0800</pubDate></item><item><title>Ixxat CAN 接口状态</title><link>http://www.swwtech.cn/ProductTest/Ixxat%20CAN%20%E6%8E%A5%E5%8F%A3%E7%8A%B6%E6%80%81/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;blockquote&gt;&lt;h2 id=&quot;h2-CAN20u63A5u53E3u72B6u6001u7684u83B7u53D6-1&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;CAN 接口状态的获取&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;CAN 接口状态的获取&lt;/h2&gt;&lt;/blockquote&gt;&lt;h3 id=&quot;h3-canControlGetStatus-3&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;canControlGetStatus&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;canControlGetStatus&lt;/h3&gt;&lt;p&gt;周期性调用canControlGetStatus API&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;HRESULT EXTERN_C canControlGetStatus (
HANDLE hCanCtl,
PCANLINESTATUS pStatus
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pStatus 指针指向一个CANLINESTATUS 结构体&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;typedef struct _CANLINESTATUS
{
UINT8 bOpMode;
UINT8 bBtReg0;
UINT8 bBtReg1;
UINT8 bBusLoad;
UINT8 dwStatus;
} CANLINESTATUS, *PCANLINESTATUS;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;应用程序可根据返回的指针指向一个CANLINESTATUS 中的各属性进行CAN接口状态的判断&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;bOpMode 当前CAN控制器的模式&lt;/p&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_OPMODE_STANDARD: 接收11位标识符&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_OPMODE_EXTENDED: 接收29位标识符&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_OPMODE_ERRFRAME: 错误消息通过特殊的CAN消息传递给应用程序&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_OPMODE_LISTONLY: 只听模式&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_OPMODE_LOWSPEED: 使用低速CAN模式&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_OPMODE_AUTOBAUD: 自动检测波特率&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;bBtReg0 和 bBtReg1 分别对应Philips SJA 1000 CAN控制器的BTR0和BTR1 寄存器（16MHz 时钟频率），可换算为CAN总线的波特率&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;bBusLoad 表示当前CAN总线的负载率的百分比（需要使用的CAN 接口型号支持该功能，可通过canControlGetCaps 获取控制器支持的功能特性CANCAPABILITIES中的dwFeatures）&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;typedef struct _CANCAPABILITIES
{
UINT16 wCtrlType;
UINT16 wBusCoupling;
UINT32 dwFeatures;
UINT32 dwClockFreq;
UINT32 dwTscDivisor;
UINT32 dwCmsDivisor;
UINT32 dwCmsMaxTicks;
UINT32 dwDtxDivisor;
UINT32 dwDtxMaxTicks;
} CANCAPABILITIES, *PCANCAPABILITIES;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;dwStatus 当前CAN 控制器的状态&lt;/p&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_STATUS_TXPEND: 正在传输一条CAN报文&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_STATUS_OVRRUN: 接收缓存器过载，需要Reset CAN控制器&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_STATUS_ERRLIM: CAN 错误计数器溢出&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_STATUS_BUSOFF: CAN 控制器 bus-off&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_STATUS_ININIT: CAN 控制器处于stopped状态&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; CAN_STATUS_BUSCERR: CAN 总线耦合错误&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ol&gt;
&lt;h3 id=&quot;h3-CAN20u6D88u606Fu4E2Du7684CANMSGINFO-66&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;CAN 消息中的CANMSGINFO&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;CAN 消息中的CANMSGINFO&lt;/h3&gt;&lt;p&gt;在使用canChannelPeekMessage，canChannelPeekMsgMult，canChannelReadMessage，canChannelReadMsgMult 等API 读取CAN总线上接收到的消息时，可首先判断PCANMSG 中的uMsgInfo bType 属性，用于判断接收到的CAN消息是数据报文还是状态或错误报文&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;typedef struct _CANMSG
{
UINT32 dwTime;
UINT32 dwMsgId;
CANMSGINFO uMsgInfo;
UINT8 abData[8];
} CANMSG, *PCANMSG;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;typedef struct _CANMSGINFO
{
UINT8 bType;
UINT8 bFlags2;
UINT8 bFlags;
UINT8 bAccept;
} CANMSGINFO, *PCANMSGINFO;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; bType&lt;ul&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;CAN_MSGTYPE_DATA: 正常数据帧
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;pre&gt;&lt;code&gt;CAN_MSGTYPE_INFO: 信息帧，如控制器状态变化等
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;pre&gt;&lt;code&gt;CAN_MSGTYPE_ERROR: 控制器检测到的错误帧
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;pre&gt;&lt;code&gt;CAN_MSGTYPE_STATUS: 状态帧,当前CAN 控制器的状态,参见上文dwStatus
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;pre&gt;&lt;code&gt;CAN_MSGTYPE_WAKEUP: 唤醒帧
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;pre&gt;&lt;code&gt;CAN_MSGTYPE_TIMEOVR: 超时帧
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;pre&gt;&lt;code&gt;CAN_MSGTYPE_TIMERST: 时间复位帧
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;示例代码&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;
    hResult = canChannelReadMessage(hCanChn, 100, &amp;amp;sCanMsg);

    if (hResult == VCI_OK)
    {
      if (sCanMsg.uMsgInfo.Bytes.bType == CAN_MSGTYPE_DATA)
      {
        // show data frames 
        if (sCanMsg.uMsgInfo.Bits.rtr == 0)
        {
          UINT8 j;

          _tprintf(TEXT(&quot;\nTime: %10u  ID: %3X  DLC: %1u  Data:&quot;),
            sCanMsg.dwTime, sCanMsg.dwMsgId, sCanMsg.uMsgInfo.Bits.dlc);

          for (j = 0; j &amp;lt; sCanMsg.uMsgInfo.Bits.dlc; j++)
          {
            _tprintf(TEXT(&quot; %.2X&quot;), sCanMsg.abData[j]);
          }
        }
        else
        {
          _tprintf(TEXT(&quot;\nTime: %10u ID: %3X  DLC: %1u  Remote Frame&quot;),
            sCanMsg.dwTime, sCanMsg.dwMsgId, sCanMsg.uMsgInfo.Bits.dlc);
        }
      }
      else if (sCanMsg.uMsgInfo.Bytes.bType == CAN_MSGTYPE_INFO)
      {
        // show informational frames
        switch (sCanMsg.abData[0])
        {
          case CAN_INFO_START:
            _tprintf(TEXT(&quot;\nCAN started...&quot;));
            break;

          case CAN_INFO_STOP:
            _tprintf(TEXT(&quot;\nCAN stoped...&quot;));
            break;

          case CAN_INFO_RESET:
            _tprintf(TEXT(&quot;\nCAN reseted...&quot;));
            break;
        }
      }
      else if (sCanMsg.uMsgInfo.Bytes.bType == CAN_MSGTYPE_ERROR)
      {
        // show error frames
        switch (sCanMsg.abData[0])
        {
          case CAN_ERROR_STUFF:
            _tprintf(TEXT(&quot;\nstuff error...&quot;));
            break;

          case CAN_ERROR_FORM:
            _tprintf(TEXT(&quot;\nform error...&quot;));
            break;

          case CAN_ERROR_ACK:
            _tprintf(TEXT(&quot;\nacknowledgment error...&quot;));
            break;

          case CAN_ERROR_BIT:
            _tprintf(TEXT(&quot;\nbit error...&quot;));
            break;

          case CAN_ERROR_CRC:
            _tprintf(TEXT(&quot;\nCRC error...&quot;));
            break;

          case CAN_ERROR_OTHER:
          default:
            _tprintf(TEXT(&quot;\nother error...&quot;));
            break;
        }
      }
      else if (sCanMsg.uMsgInfo.Bytes.bType == CAN_MSGTYPE_STATUS)
      {
         // show status frames
        switch (sCanMsg.abData[0])
        {
          case CAN_STATUS_TXPEND:
            _tprintf(TEXT(&quot;\n transmission pending...&quot;));
            break;

          case CAN_STATUS_OVRRUN:
            _tprintf(TEXT(&quot;\n data overrun occurred...&quot;));
            break;

          case CAN_STATUS_ERRLIM:
            _tprintf(TEXT(&quot;\n error warning limit exceeded...&quot;));
            break;

          case CAN_STATUS_BUSOFF:
            _tprintf(TEXT(&quot;\n bus off status...&quot;));
            break;

          case CAN_STATUS_ININIT:
            _tprintf(TEXT(&quot;\n init mode active...&quot;));
            break;

          case CAN_STATUS_BUSCERR:
            _tprintf(TEXT(&quot;\n bus coupling error...&quot;));
            break;
          default:
            _tprintf(TEXT(&quot;\nother error...&quot;));
            break;
        }
    }
  }
 
&lt;/code&gt;&lt;/pre&gt;
&lt;/body&gt;</description><pubDate>Thu, 15 Aug 2024 09:32:29 +0800</pubDate></item><item><title>[MQTT] TLS 单向认证和双向认证</title><link>http://www.swwtech.cn/ProductTest/%5BMQTT%5D%20TLS%20%E5%8D%95%E5%90%91%E8%AE%A4%E8%AF%81%E5%92%8C%E5%8F%8C%E5%90%91%E8%AE%A4%E8%AF%81/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;引用自：&lt;a href=&quot;https://www.jianshu.com/p/fb5fe0165ef2&quot;&gt;https://www.jianshu.com/p/fb5fe0165ef2&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-tls-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;TLS单向认证具体过程&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;TLS单向认证具体过程&lt;/h2&gt;&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131410226300590.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;①客户端的浏览器向服务器传送客户端SSL协议的版本号，加密算法的种类，产生的随机数，以及其他服务器和客户端之间通讯所需要的各种信息。&lt;/p&gt;
&lt;p&gt;②服务器向客户端传送SSL协议的版本号，加密算法的种类，随机数以及其他相关信息，同时服务器还将向客户端传送自己的证书。&lt;/p&gt;
&lt;p&gt;③客户利用服务器传过来的信息验证服务器的合法性，服务器的合法性包括：证书是否过期，发行服务器证书的CA是否可靠，发行者证书的公钥能否正确解开服务器证书的”发行者的数字签名”，服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过，通讯将断开;如果合法性验证通过，将继续进行第四步。&lt;/p&gt;
&lt;p&gt;④用户端随机产生一个用于后面通讯的”对称密码”，然后用服务器的公钥(服务器的公钥从步骤②中的服务器的证书中获得)对其加密，然后将加密后的”预主密码”传给服务器。&lt;/p&gt;
&lt;p&gt;⑤如果服务器要求客户的身份认证(在握手过程中为可选)，用户可以建立一个随机数然后对其进行数据签名，将这个含有签名的随机数和客户自己的证书以及加密过的”预主密码”一起传给服务器。&lt;/p&gt;
&lt;p&gt;⑥如果服务器要求客户的身份认证，服务器必须检验客户证书和签名随机数的合法性，具体的合法性验证过程包括：客户的证书使用日期是否有效，为客户提供证书的CA是否可靠，发行CA 的公钥能否正确解开客户证书的发行CA的数字签名，检查客户的证书是否在证书废止列表(CRL)中。检验如果没有通过，通讯立刻中断;如果验证通过，服务器将用自己的私钥解开加密的”预主密码 “，然后执行一系列步骤来产生主通讯密码(客户端也将通过同样的方法产生相同的主通讯密码)。&lt;/p&gt;
&lt;p&gt;⑦服务器和客户端用相同的主密码即”通话密码”，一个对称密钥用于SSL协议的安全数据通讯的加解密通讯。同时在SSL通讯过程中还要完成数据通讯的完整性，防止数据通讯中的任何变化。&lt;/p&gt;
&lt;p&gt;⑧客户端向服务器端发出信息，指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥，同时通知服务器客户端的握手过程结束。&lt;/p&gt;
&lt;p&gt;⑨服务器向客户端发出信息，指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥，同时通知客户端服务器端的握手过程结束。&lt;/p&gt;
&lt;p&gt;⑩-SSL的握手部分结束，SSL安全通道的数据通讯开始，客户和服务器开始使用相同的对称密钥进行数据通讯，同时进行通讯完整性的检验。&lt;/p&gt;
&lt;p&gt;SSL单向认证只要求站点部署了ssl证书就行，任何用户都可以去访问(IP被限制除外等)，只是服务端提供了身份认证。&lt;/p&gt;
&lt;h2 id=&quot;h2-tls-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;TLS双向认证具体过程&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;TLS双向认证具体过程&lt;/h2&gt;&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131411584471392.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;① 浏览器发送一个连接请求给安全服务器。&lt;/p&gt;
&lt;p&gt;② 服务器将自己的证书，以及同证书相关的信息发送给客户浏览器。&lt;/p&gt;
&lt;p&gt;③ 客户浏览器检查服务器送过来的证书是否是由自己信赖的CA中心（如沃通CA）所签发的。如果是，就继续执行协议;如果不是，客户浏览器就给客户一个警告消息：警告客户这个证书不是可以信赖的，询问客户是否需要继续。&lt;/p&gt;
&lt;p&gt;④ 接着客户浏览器比较证书里的消息，例如域名和公钥，与服务器刚刚发送的相关消息是否一致，如果是一致的，客户浏览器认可这个服务器的合法身份。&lt;/p&gt;
&lt;p&gt;⑤ 服务器要求客户发送客户自己的证书。收到后，服务器验证客户的证书，如果没有通过验证，拒绝连接;如果通过验证，服务器获得用户的公钥。&lt;/p&gt;
&lt;p&gt;⑥ 客户浏览器告诉服务器自己所能够支持的通讯对称密码方案。&lt;/p&gt;
&lt;p&gt;⑦ 服务器从客户发送过来的密码方案中，选择一种加密程度最高的密码方案，用客户的公钥加过密后通知浏览器。&lt;/p&gt;
&lt;p&gt;⑧ 浏览器针对这个密码方案，选择一个通话密钥，接着用服务器的公钥加过密后发送给服务器。&lt;/p&gt;
&lt;p&gt;⑨ 服务器接收到浏览器送过来的消息，用自己的私钥解密，获得通话密钥。&lt;/p&gt;
&lt;p&gt;⑩ 服务器、浏览器接下来的通讯都是用对称密码方案，对称密钥是加过密的。&lt;/p&gt;
&lt;p&gt;双向认证则是需要服务端与客户端提供身份认证，只能是服务端允许的客户能去访问，安全性相对于要高一些。&lt;/p&gt;
&lt;h2 id=&quot;h2-mqtt-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;MQTT 服务器设置双向认证&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;MQTT 服务器设置双向认证&lt;/h2&gt;&lt;p&gt;EMQX&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111343249766226.png&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;类型设置为SSL&lt;/li&gt;&lt;li&gt;监听地址设置为0。0.0.0:1883&lt;br&gt;&lt;strong&gt;3. 双向认证进行勾选使能&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;4. 强制验证对端证书设置为TRUE&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;重新设置为CA和服务器证书、秘钥&lt;/li&gt;&lt;/ol&gt;
&lt;h2 id=&quot;h2-mqtt-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;MQTT 客户端设置双向认证&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;MQTT 客户端设置双向认证&lt;/h2&gt;&lt;p&gt;客户端双向认证需提供客户端的CA,证书和秘钥&lt;br&gt;客户端的CA和服务器端的CA需要是同一个&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131416111568579.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;单向认证客户端只需要使用服务器端的CA即可&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131418001551276.png&quot;&gt;&lt;/p&gt;
&lt;/body&gt;</description><pubDate>Mon, 13 May 2024 14:08:37 +0800</pubDate></item><item><title>[MQTT] TLS 证书生成</title><link>http://www.swwtech.cn/ProductTest/TlsCertificate/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;在互联网通讯时，为了保证数据交换的加密型，完整性和一致性，需要对连接进行加密处理&lt;br&gt;最常用的如HTTPS，以及工业IOT常使用的OPC UA 和MQTT 都使用SSL/TLS 对通讯进行加密&lt;/p&gt;
&lt;p&gt;本文介绍如何为TLS 加密通讯生成安全证书等文件&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用OpenSSL 生成TLS证书&lt;/li&gt;&lt;li&gt;使用Anybus Certificate Generator生成TLS证书&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;h2--openssl-tls-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;使用OpenSSL 生成TLS证书&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;使用OpenSSL 生成TLS证书&lt;/h2&gt;&lt;p&gt;1.创建自签名 CA 证书&lt;/p&gt;
&lt;p&gt;前置准备：已安装 OpenSSL&lt;br&gt;运行以下命令生成密钥对，该命令随即会提示您输入密钥保护密码，后续在生成、签发、验证证书时均需要此密码。&lt;br&gt;请妥善相关密钥及密码。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;openssl genrsa -des3 -out rootCA.key 2048
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行以下命令通过密钥对中的私有密钥生成 CA 证书，该命令随即会提示您设置证书的唯一标识名称 DN（Distinguished Name）。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.签发服务器证书&lt;/p&gt;
&lt;p&gt;使用 CA 证书来签发服务器证书，用于验证服务器所有者的身份，服务器证书通常颁发给主机名、服务器名称或域名（如 &lt;a href=&quot;http://www.emqx.com&quot;&gt;www.emqx.com&lt;/a&gt;, localhot）。我们需要 CA 密钥（rootCA.key）、CA 证书（ rootCA.crt）和服务端 CSR （server.csr）生成服务器证书。&lt;/p&gt;
&lt;p&gt;运行以下命令生成服务器证书密钥对：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;openssl genrsa -out server.key 2048
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行以下命令使用 Server 密钥对制作 CSR。经 CA 根证书私钥签名后，CSR 可生成颁发给用户的证书公钥文件。该命令随即也会要求设置证书的唯一标识名称。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;openssl req -new -key server.key -out server.csr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;系统将提示以下信息，对应的含义如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;Country Name (2 letter code) [AU]: CN
State or Province Name (full name) [Some-State]: BJ
Locality Name (eg, city) []: BJ
Organization Name (eg, company) [Internet Widgits Pty Ltd]: HMS
Organizational Unit Name (eg, section) []: MUGC
Common Name (e.g. server FQDN or YOUR name) []: emqx.swwtech.cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;⚠️ Common Name 处一定要填写服务器的域名或者IP地址&lt;/p&gt;
&lt;p&gt;使用 CSR 生成服务器证书，此时也可指定证书的有效天数，此处为 365 天：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 365
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;签发客户端证书&lt;br&gt;签发客户端证书的步骤与签发服务器证书类似，只是在生成 CSR 时，需要将 Common Name 设置为客户端的唯一标识，如用户名、客户端 ID 等。&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;客户端证书与服务端证书使用相同的 CA 证书签名，因此客户端证书也可以使用上述 CA 证书签名。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr
openssl x509 -req -in client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out client.crt -days 365
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至此得到了一组证书,包括CA,服务器和客户端&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;.
├── rootCA.crt
├── rootCA.key
├── rootCA.srl
├── server.crt
├── server.csr
└── server.key
├── client.crt
├── client.csr
└── client.key
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;h2--anybus-certificate-generator-tls-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;使用Anybus Certificate Generator生成TLS证书&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;使用Anybus Certificate Generator生成TLS证书&lt;/h2&gt;&lt;p&gt;Anybus Certificate Generator 是Anybus 提供的证书生成软件，可以为Anybus 旗下的Anybus CompactCom M40 IIOT 模块生成TLS证书&lt;br&gt;其底层是基于OpenSSL,因此生成的CA和设备证书也同样适用于其他产品&lt;/p&gt;
&lt;p&gt;Anybus Certificate Generator 软件下载地址&lt;br&gt;&lt;a href=&quot;https://www.anybus.com/docs/librariesprovider7/default-document-library/software/anybus-certificate-generator.zip?sfvrsn=7bd553d7_18&quot;&gt;https://www.anybus.com/docs/librariesprovider7/default-document-library/software/anybus-certificate-generator.zip?sfvrsn=7bd553d7_18&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;软件安装完成后，打开后如下图所示&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131333157525069.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;1.创建自签名 CA 证书&lt;/p&gt;
&lt;p&gt;点击软件左下角的“Mange…”，弹窗“Mange CA Certificates”，可以查看已经生成的CA证书&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131335395928662.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;可以点击“New…”， &lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131336304944210.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;填写完相关信息后，可点击“Generate CA Certificate” 新建CA证书&lt;/p&gt;
&lt;p&gt;新建的CA证书，会出现在“Mange CA Certificate” 窗口的列表中&lt;/p&gt;
&lt;p&gt;点击选中需要的CA证书，然后点击“Show in folder”,可以打开CA证书保存的文件夹&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131339487766960.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;2.创建服务器/客户端证书&lt;/p&gt;
&lt;p&gt;在“Mange CA Certificate” 窗口，点击选中需要的CA证书，然后点击“Show associated certificate…”,可以弹出&lt;br&gt;“Certificats issued by ???” 显示该CA证书创建的服务器/客户端证书&lt;/p&gt;
&lt;p&gt;点击“New”, 可以使用该CA证书创建新的服务器/客户端证书&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131343388213946.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;在弹出的窗口中，填写相关的信息&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131344272318122.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;⚠️Common Name(CN)处，如果是服务器使用则填写服务器的域名或者IP地址&lt;/p&gt;
&lt;p&gt;填写完毕，点击“Continue”,会生成需要的证书，并显示在“Certificats issued by ???”窗口列表&lt;/p&gt;
&lt;p&gt;点击生成的证书，点击“Show in folder” 可以查看证书存放的文件夹&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405131348067364574.png&quot;&gt;&lt;/p&gt;
&lt;/body&gt;</description><pubDate>Mon, 13 May 2024 13:19:40 +0800</pubDate></item><item><title>[MQTT] Atlas2 使用MQTT 发布工业网络诊断数据</title><link>http://www.swwtech.cn/ProductTest/Atlas2MQTT/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;服务器搭建请参考另外一篇文章&lt;br&gt;&lt;a href=&quot;http://www.swwtech.cn/ProductTest/EMQX/&quot;&gt;http://www.swwtech.cn/ProductTest/EMQX/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Atlas2 plus 能够主动扫描和被动监听PROFINET, Ethernet/IP 等工业实时以太网和PROFIBUS现场总线的健康状态&lt;br&gt;并通过MQTT或者OPC UA 对外提供诊断信息&lt;/p&gt;
&lt;p&gt;本文介绍如何使能Atlas2 plus的MQTT数据发布功能&lt;/p&gt;
&lt;h2 id=&quot;h2-atlas2-plus-office-ip-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;Atlas2 plus Office端口IP地址设置&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Atlas2 plus Office端口IP地址设置&lt;/h2&gt;&lt;p&gt;如需Atlas2 plus 通过互联网对外发布MQTT数据，其Office端口的IP设置需能够允许访问互联网&lt;br&gt;可在Settings-Network-Office interface 处设置其IP地址&lt;/p&gt;
&lt;p&gt;是采用DCHP自动获取还是使用Manual 方式，取决于其连接的网络配置，请与该网络的IT部门确认&lt;br&gt;本文使用DHCP方式自动获取IP地址和DNS等相关设置&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111406388784892.png&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-atlas2-plus-mqtt-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;Atlas2 plus MQTT 配置&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Atlas2 plus MQTT 配置&lt;/h2&gt;&lt;p&gt;在Settings-Connectivity-MQTT 处设置相关的配置&lt;/p&gt;
&lt;p&gt;在Host 处需填写 MQTT Broker 服务器的域名或者IP地址&lt;br&gt;在Port 处需填写 MQTT Broker 服务器开放的连接端口&lt;/p&gt;
&lt;p&gt;强烈建议勾选“Use TLS”,&lt;br&gt;    在CA File 处上传CA证书&lt;br&gt;    在Client Certificate File 处上传客户端证书&lt;br&gt;    在Client Certificate Key File处上传客户端秘钥&lt;/p&gt;
&lt;p&gt;📑 TLS证书生成请参考：&lt;a href=&quot;http://www.swwtech.cn/ProductTest/TlsCertificate/&quot;&gt;http://www.swwtech.cn/ProductTest/TlsCertificate/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111413457593809.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;在User Name 处填写客户端用户名&lt;br&gt;在Password处填写客户端密码&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111413531549322.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后点击Connect&lt;/p&gt;
&lt;p&gt;如果连接正常,会在页面显示已连接&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111414572611765.png&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2--atlas2-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;应用订阅Atlas2发布的诊断数据&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;应用订阅Atlas2发布的诊断数据&lt;/h2&gt;&lt;p&gt;客户应用可连接到同样的MQTT 服务器，订阅Atlas2 发布的主题&lt;br&gt;我们以MQTTX客户端为例，说明如何订阅该数据&lt;br&gt;MQTTX 下载地址 &lt;a href=&quot;https://mqttx.app/zh&quot;&gt;https://mqttx.app/zh&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;MQTTX 需要连接到同一MQTT Broker 服务器&lt;br&gt;因此Host 处需填写相同的域名或者IP地址， Port 也填写相同的1883端口&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111419206018885.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;用户名密码填写服务器分配的用户名密码&lt;/p&gt;
&lt;p&gt;使能TLS，并设置认证证书等相关文件路径&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111420422599768.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;配置完成后，点击Connect建立连接&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111422027668884.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;新增订阅，使用通配符 “&lt;span style=&quot;color: #df2a3f&quot;&gt;/osiris/#&lt;/span&gt;”，可以订阅到Atlas2 发布的所有主题&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111423539215181.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;订阅后，可以成功接收到Atlas2 发布的主题，可以选择JSON格式，更方便查看其内容&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111425321476562.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;使用“&lt;span style=&quot;color: #df2a3f&quot;&gt;/osiris/#&lt;/span&gt;”订阅多个主题，接收时可在接收窗口看到所接收的主题具体是什么&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111427202962053.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果有多个Atlas2 都连接到服务器发送相同的主题，订阅者可在每一条数据找到“metadata”,&lt;br&gt;里面包含Atlas2的具体序列号和发送该主题的时间戳&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111429073444849.png&quot;&gt;&lt;/p&gt;
&lt;/body&gt;</description><pubDate>Sat, 11 May 2024 13:59:28 +0800</pubDate></item><item><title>[MQTT] 阿里云服务器搭建MQTT Broker 服务器</title><link>http://www.swwtech.cn/ProductTest/EMQX/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;h2 id=&quot;h2-u76EEu5F55&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;目录&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;目录&lt;/h2&gt;&lt;p&gt;在阿里云ECS 云服务器上搭建EMQX MQTT Broker环境，包括如下几个步骤，我们依次进行介绍**&lt;/p&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 安装docker,方便部署应用&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 安装docker portainer, 图形化管理docker&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 安装EMQX&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 【可选】安装nginx-proxy-manager 反向代理管理系统，方便外网访问&lt;/li&gt;&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; EMQX 安全配置和用户管理&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;以上都需要远程登陆阿里云服务器（&lt;span style=&quot;color: #b72432&quot;&gt;Ubuntu 22.04.4 LTS&lt;/span&gt;），方法不在此赘述&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;h2--docker&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;安装  docker&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;安装&lt;a title=&quot;docker&quot; href=&quot;https://docker.com/&quot;&gt;docker&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;1.更新软件包&lt;br&gt;在终端中执行以下命令来更新Ubuntu软件包列表和已安装软件的版本:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo apt update
sudo apt upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.安装docker依赖&lt;br&gt;Docker在Ubuntu上依赖一些软件包。执行以下命令来安装这些依赖&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;apt-get install ca-certificates curl gnupg lsb-release
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.添加Docker官方GPG密钥&lt;br&gt;执行以下命令来添加Docker官方的GPG密钥:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4.添加Docker软件源&lt;br&gt;执行以下命令来添加Docker的软件源:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo add-apt-repository &quot;deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5.安装docker&lt;br&gt;执行以下命令来安装Docker:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;apt-get install docker-ce docker-ce-cli containerd.io
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;6.运行docker&lt;br&gt;我们可以通过启动docker来验证我们是否成功安装。命令如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;systemctl start docker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;7.查看docker版本&lt;br&gt;我们可以通过下面的命令来查看docker的版本&lt;br&gt;sudo docker version&lt;/p&gt;
&lt;h2 id=&quot;h2--docker-portainer-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;安装  docker portainer 社区版本&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;安装&lt;a title=&quot;docker portainer&quot; href=&quot;https://www.portainer.io/&quot;&gt;docker portainer&lt;/a&gt;社区版本&lt;/h2&gt;&lt;p&gt;docker 传统上需要使用命令行进行管理，docker portainer 提供了图形化的界面进行容器的安装和管理&lt;/p&gt;
&lt;p&gt;1.使用docker search 命令查找可用的镜像&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;docker search portainer
NAME                                  DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
portainer/portainer                   This Repo is now deprecated, use portainer/p…   2517                
portainer/portainer-ce                Portainer CE - a lightweight service deliver…   2244                 
portainer/agent                       An agent used to manage all the resources in…   234                  
portainer/portainer-ee                Portainer BE - a fully featured service deli…   110                  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们需要安装的是portainer/portainer-ce&lt;/p&gt;
&lt;p&gt;2.拉取所需的镜像&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;docker pull portainer/portainer-ce
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.创建portainer 数据卷&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;docker volume create portainer_data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4.运行portainer&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;docker run -d -p 9000:9000 --restart always -v /var/run/docker.sock:/var/run/docker.sock  -v portainer_data:/data portainer/portainer-ce
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将容器端口9000映射到主机端口9000，可使用&lt;a href=&quot;http://server-ip:9000&quot;&gt;http://server-ip:9000&lt;/a&gt; 访问portainer Dashboard&lt;/p&gt;
&lt;p&gt; 🛡️ 服务器防火墙需开放端口9000&lt;/p&gt;
&lt;h2 id=&quot;h2--emqx&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;安装EMQX&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;安装EMQX&lt;/h2&gt;&lt;p&gt;1.新建数据卷，用于持久化EMQX 的数据&lt;br&gt;进入到portainer 的网页管理界面，在”Volumes”新建一个名为”emqxdatalog”的数据卷&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405110952191296293.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;2.新建容器EMQX&lt;br&gt;在”Container”新建一个名为”emqx”的容器&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
Image处填入“emqx/emqx”&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405110956417940720.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
Manual network port publishing处新增两个端口映射&lt;br&gt;18083端口是用于EMQX 的配置界面&lt;br&gt;1883用户后续的MQTT 连接&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405110958395176628.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
Advanced container settings 下Volumes 处挂载持久化配置文件&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111001243357398.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
Restart policy 选择Always，随主机一起启动&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111002458622378.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
部署&lt;br&gt;点击“Deply the container”进行部署&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111004558444386.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
查看状态&lt;br&gt;在Volumes 处可以查看容器的运行状态&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111006175459713.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;可使用&lt;a href=&quot;http://server-ip:18083&quot;&gt;http://server-ip:18083&lt;/a&gt; 访问EMQX Dashboard配置界面&lt;br&gt;&lt;strong&gt;默认用户名：admin&lt;br&gt;默认密码：public&lt;br&gt;登录后需重新设置密码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; 🛡️ 服务器防火墙需开放端口18083和1883&lt;/p&gt;
&lt;h2 id=&quot;h2--nginx-proxy-manager-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;【可选】安装nginx-proxy-manager 反向代理管理系统，方便外网访问&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;【可选】安装nginx-proxy-manager 反向代理管理系统，方便外网访问&lt;/h2&gt;&lt;p&gt;使用IP+端口的方式既不安全，也不容易记忆，因此可以安装nginx-proxy-manager，使用反向代理&lt;br&gt;将域名访问代理到相关的域名+端口&lt;/p&gt;
&lt;p&gt;🏁 在域名的DNS解析中，将域名指向该服务器的IP&lt;br&gt;例如&lt;br&gt;emqx.swwtech.cn 指向本服务器的IP地址&lt;/p&gt;
&lt;p&gt;1.新建数据卷，用于持久化EMQX 的数据&lt;br&gt;进入到portainer 的网页管理界面，在”Volumes”新建一个名为”nginxproxymanager”的数据卷&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111304196294633.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;2.新建容器&lt;br&gt;在”Container”新建一个名为”nginx-proxy-manager-zh”的容器&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
Image处填入“chishin/nginx-proxy-manager-zh”&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111308182280097.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
Manual network port publishing处新增三个端口映射&lt;br&gt;81端口是用于nginx-proxy-manager 的配置界面&lt;br&gt;80端口和443端口分别是HTTP和HTTPS协议所使用的端口&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111309323760296.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
Advanced container settings 下Volumes 处挂载持久化配置文件&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111314092195708.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
Restart policy 选择Always，随主机一起启动&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111002458622378.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
部署&lt;br&gt;点击“Deply the container”进行部署&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111004558444386.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 
查看状态&lt;br&gt;在Volumes 处可以查看容器的运行状态&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111315219709921.png&quot;&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt; 🛡️ 服务器防火墙需开放端口80,81和443 用于外网访问&lt;/p&gt;
&lt;p&gt; 此时可以使用&lt;a href=&quot;http://server-ip:81&quot;&gt;http://server-ip:81&lt;/a&gt; 访问nginx-proxy-manager 配置界面&lt;br&gt;&lt;strong&gt;默认用户名：&lt;a href=&quot;mailto:admin@example.com&quot;&gt;admin@example.com&lt;/a&gt;&lt;br&gt;默认密码：changeme&lt;br&gt;登录后需重新设置密码&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-u65B0u5EFAu4EE3u7406u670Du52A1&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;新建代理服务&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;新建代理服务&lt;/h3&gt;&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111320594332626.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;后续就可以使用emqx.swwtech.cn 代替访问 &lt;a href=&quot;http://server-ip:18083&quot;&gt;http://server-ip:18083&lt;/a&gt; EMQX 管理界面&lt;/p&gt;
&lt;h2 id=&quot;h2-emqx-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;EMQX 安全配置和用户管理&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;EMQX 安全配置和用户管理&lt;/h2&gt;&lt;p&gt;EMQX 支持多种MQTT连接方式，其中包括基于TLS 的加密连接，如果需要TLS加密通讯，需要进行TLS证书的生成和相关的配置&lt;/p&gt;
&lt;p&gt;📑 TLS证书生成请参考：&lt;a href=&quot;http://www.swwtech.cn/ProductTest/TlsCertificate/&quot;&gt;http://www.swwtech.cn/ProductTest/TlsCertificate/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-emqx-tls-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;EMQX 开启TLS双向认证&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;EMQX 开启TLS双向认证&lt;/h3&gt;&lt;p&gt;在EMQX 管理页面，进入到“监听器”配置界面&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111340148179924.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;删除其他监听器配置，只保留类型为SSL 的监听器，并进入其配置页面&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111343249766226.png&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;类型设置为SSL&lt;/li&gt;&lt;li&gt;监听地址设置为0。0.0.0:1883&lt;/li&gt;&lt;li&gt;双向认证进行勾选使能&lt;/li&gt;&lt;li&gt;强制验证对端证书设置为TRUE&lt;/li&gt;&lt;li&gt;重新设置为CA和服务器证书、秘钥&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;然后点击更新，使能TLS&lt;/p&gt;
&lt;h3 id=&quot;h3-emqx-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;EMQX 用户管理&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;EMQX 用户管理&lt;/h3&gt;&lt;p&gt;EMQX 管理页面，进入到“客户端认证”配置界面，创建Password-Based 的认证方式，数据源选择“内置数据库”，其他保持默认&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111349279375296.png&quot;&gt;&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111349395902749.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;在新建的数据库处，点击用户管理，新建需要的MQTT 客户端用户&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/05/202405111350553099626.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;至此， EMQX 作为MQTT Broker 服务器搭建完成，MQTT 客户端可使用创建的证书+用户名/密码 与服务器进行连接，发布订阅数据&lt;/p&gt;
&lt;/body&gt;</description><pubDate>Sat, 11 May 2024 08:52:32 +0800</pubDate></item><item><title>使用Ixxat CAN 接口卡为树莓派扩展CAN接口</title><link>http://www.swwtech.cn/ProductTest/IxxatCAN/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;h1 id=&quot;h1-1-ixxat-can-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;1. Ixxat CAN 接口卡&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1. Ixxat CAN 接口卡&lt;/h1&gt;&lt;p&gt;HMS 旗下的Ixxat 品牌提供多种接口形式的PC CAN接口卡&lt;br&gt;&lt;a href=&quot;https://www.ixxat.com/zh/home&quot;&gt;https://www.ixxat.com/zh/home&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;h3-pc-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;PC接口形式&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;PC接口形式&lt;/h3&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;USB&lt;/li&gt;&lt;li&gt;PCI&lt;/li&gt;&lt;li&gt;PCIe&lt;/li&gt;&lt;li&gt;PCIe mini&lt;/li&gt;&lt;li&gt;M.2&lt;/li&gt;&lt;li&gt;PMC&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;h3-u652Fu6301u7684u64CDu4F5Cu7CFBu7EDF&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;支持的操作系统&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;支持的操作系统&lt;/h3&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Windows 7,8,10,11&lt;/li&gt;&lt;li&gt;Linux&lt;/li&gt;&lt;li&gt;Vxworks 7 等实时操作系统&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;h3--can-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;提供的CAN 接口&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;提供的CAN 接口&lt;/h3&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;CAN&lt;/li&gt;&lt;li&gt;CAN FD&lt;/li&gt;&lt;li&gt;LIN&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;本文介绍如何为树莓派Compute module 4 IO底板通过USB 扩展CAN 接口&lt;br&gt;使用的产品是USB-to-CAN V2&lt;br&gt;&lt;a href=&quot;https://www.ixxat.com/zh/products/pc-interfaces-overview/details/usb-to-can-v2?ordercode=1.01.0281.12001&quot;&gt;https://www.ixxat.com/zh/products/pc-interfaces-overview/details/usb-to-can-v2?ordercode=1.01.0281.12001&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;h1-2-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;2. 硬件列表&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2. 硬件列表&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;树莓派Compute module 4 核心板&lt;br&gt;&lt;img title=&quot;CM4&quot; alt=&quot;CM4&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2023/12/202312051336068562294.jpg&quot;&gt;&lt;/li&gt;&lt;li&gt;树莓派Compute module 4 IO底板&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2023/12/202312051336541177448.jpg&quot;&gt;&lt;/li&gt;&lt;li&gt;Ixxat USB-to-CAN V2&lt;br&gt;&lt;img title=&quot;1-01-0283-22042-Ixxat-USB-to-CAN-V2-auto_Download_720px_JPEG.jpg&quot; alt=&quot;1-01-0283-22042-Ixxat-USB-to-CAN-V2-auto_Download_720px_JPEG.jpg&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/03/1-01-0283-22042-Ixxat-USB-to-CAN-V2-auto_Download_720px_JPEG.jpg&quot;&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;h1-3-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;3. 硬件安装&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3. 硬件安装&lt;/h1&gt;&lt;p&gt;将Ixxat USB-to-CAN V2 的USB 接口插入到 Compute module 4 IO底板的USB 插口中&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;⚠️根据CAN报文的收发机制，测试CAN报文的收发，至少需要连接两个CAN节点&lt;br&gt;并在CAN总线的两端CANH和CANL之间连接120ohm终端电阻&lt;/p&gt;
&lt;p&gt;示例安装&lt;br&gt;💻节点1  IB200（终端电阻120）&amp;lt;—-CAN H/L 电缆—–&amp;gt;（终端电阻120）节点2 USBtoCAN 💻&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;h1-4-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;4. 驱动&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4. 驱动&lt;/h1&gt;&lt;p&gt;在Linux 系统下， Ixxat 提供两种方式的驱动程序，一种是ECI Driver, 另外一种是SocketCAN Driver&lt;br&gt;考虑到SocketCAN 提供通用的API, 我们在本文中使用SocketCAN 驱动&lt;/p&gt;
&lt;blockquote&gt;
&lt;h2 id=&quot;h2-u9A71u52A8u4E0Bu8F7D&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;驱动下载&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;驱动下载&lt;/h2&gt;&lt;/blockquote&gt;
&lt;p&gt;在Ixxat 技术支持官网下载SocketCAN Driver 驱动文件&lt;br&gt;下载页面地址&lt;br&gt;&lt;a href=&quot;https://www.ixxat.com/zh/technical-support/resources/downloads-and-documentation?ordercode=1.01.0281.12001&quot;&gt;https://www.ixxat.com/zh/technical-support/resources/downloads-and-documentation?ordercode=1.01.0281.12001&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;h2 id=&quot;h2-u9A71u52A8u5B89u88C5&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;驱动安装&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;驱动安装&lt;/h2&gt;&lt;/blockquote&gt;
&lt;p&gt;解压下载后的驱动文件，文件夹中的ix_usb_can_2.0 名称起始的文件夹是USB-to-CAN V2 使用的驱动&lt;/p&gt;
&lt;p&gt;进入该文件夹进行驱动的配置与安装&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;h3-linux-kernel-header-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;Linux kernel header 必要的依赖头文件和编译工具安装&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Linux kernel header 必要的依赖头文件和编译工具安装&lt;/h3&gt;&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo apt install linux-headers-$(uname -r)
sudo apt install --reinstall build-essential
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以使用命令查看依赖的文件和工具是否已经安装&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;ls /usr/src/linux-headers-$(uname -r)
输出结果
arch  include  Makefile  Module.symvers  scripts  tools
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;h3-u8FDBu5165u9A71u52A8u6587u4EF6u5939u7F16u8BD1u548Cu5B89u88C5&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;进入驱动文件夹编译和安装&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;进入驱动文件夹编译和安装&lt;/h3&gt;&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;make all
sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;h3-u67E5u770Bu9A71u52A8u662Fu5426u6B63u786Eu5B89u88C5&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;查看驱动是否正确安装&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;查看驱动是否正确安装&lt;/h3&gt;&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo dmesg | grep ix
[    3.638893] vc4-drm gpu: bound fe206000.pixelvalve (ops vc4_crtc_ops [vc4])
[    3.639325] vc4-drm gpu: bound fe207000.pixelvalve (ops vc4_crtc_ops [vc4])
[    3.639716] vc4-drm gpu: bound fe20a000.pixelvalve (ops vc4_crtc_ops [vc4])
[    3.640034] vc4-drm gpu: bound fe216000.pixelvalve (ops vc4_crtc_ops [vc4])
[    3.640432] vc4-drm gpu: bound fec12000.pixelvalve (ops vc4_crtc_ops [vc4])
[  349.068706] ix_usb_can: loading out-of-tree module taints kernel.
[  349.069396] ix_usb_can: KERNELVERSION: 0x60149 (393545)
[  349.104862] ix_usb_can: FwInfo 1.8
[  349.725168] ix_usb_can 1-1.1:1.0 can0: USB-to-CAN_FD: Connected Channel 0 (device HW719254)
[  349.725915] ix_usb_can 1-1.1:1.0 can1: USB-to-CAN_FD: Connected Channel 1 (device HW719254)
[  349.726256] usbcore: registered new interface driver ix_usb_can
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上输出，可以看到ix_usb_can 的两个CAN 通道分别被绑定到了can0 和can1&lt;/p&gt;
&lt;h1 id=&quot;h1-5-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;5. 波特率配置&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5. 波特率配置&lt;/h1&gt;&lt;p&gt;每次应用在使用Socket CAN 之前需要对CAN 通道进行使能并设置波特率&lt;/p&gt;
&lt;p&gt;可以使用以下命令启动CAN通道并设置波特率&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo ip link set can0 up type can bitrate 250000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后使用ifconfig 查看can0 的状态&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;ifconfig
can0: flags=193&amp;lt;UP,RUNNING,NOARP&amp;gt;  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
        RX packets 7  bytes 42 (42.0 B)
        RX errors 1  dropped 0  overruns 0  frame 1
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者ip link show命令查看更详细的状态&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt; ip -d -s link show can0
3: can0: &amp;lt;NOARP,UP,LOWER_UP,ECHO&amp;gt; mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
    link/can  promiscuity 0  allmulti 0 minmtu 0 maxmtu 0
    can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 100
          bitrate 250000 sample-point 0.875
          tq 125 prop-seg 13 phase-seg1 14 phase-seg2 4 sjw 1 brp 5
          ifi_can: tseg1 1..32 tseg2 2..33 sjw 1..4 brp 2..257 brp_inc 1
          clock 40000000
          re-started bus-errors arbit-lost error-warn error-pass bus-off
          0          0          0          0          0          0         numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 parentbus pci parentdev 0000:01:00.0
    RX:  bytes packets errors dropped  missed   mcast
          3551     864      0     147       0       0
    TX:  bytes packets errors dropped carrier collsns
          4578     579      0       0       0       0
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h2 id=&quot;h2--can-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;开机自动使能CAN通道并设置波特率&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;开机自动使能CAN通道并设置波特率&lt;/h2&gt;&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nano /etc/network/interfaces.d/can0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入以下内容，并保存&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;allow-hotplug can0
iface can0 can static
  bitrate 250000
  restart-ms 100
  txqueuelen 1000
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;h1-6-can-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;6. CAN 收发测试&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;6. CAN 收发测试&lt;/h1&gt;&lt;p&gt;可以使用CAN-utils 工具集 测试CAN 消息的收发&lt;/p&gt;
&lt;blockquote&gt;
&lt;h2 id=&quot;h2--can-utils&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;安装CAN-utils&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;安装CAN-utils&lt;/h2&gt;&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo apt install can-utils
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h2 id=&quot;h2--can-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;接收CAN 消息&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;接收CAN 消息&lt;/h2&gt;&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt; candump can0
  can0  703   [1]  7F
  can0  083   [8]  10 81 11 00 00 00 00 00
  can0  083   [8]  00 00 00 00 00 00 00 00
  can0  703   [1]  7F
  can0  083   [8]  10 81 11 00 00 00 00 00
  can0  083   [8]  00 00 00 00 00 00 00 00
  can0  703   [1]  7F
  can0  083   [8]  10 81 11 00 00 00 00 00
  can0  083   [8]  00 00 00 00 00 00 00 00
  can0  703   [1]  7F
  can0  083   [8]  10 81 11 00 00 00 00 00
  can0  083   [8]  00 00 00 00 00 00 00 00
  can0  703   [1]  7F
  can0  083   [8]  10 81 11 00 00 00 00 00
  can0  083   [8]  00 00 00 00 00 00 00 00
  can0  703   [1]  7F
  can0  083   [8]  10 81 11 00 00 00 00 00
  can0  083   [8]  00 00 00 00 00 00 00 00
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试时发现candump 不会显示自身节点发送的数据，只显示接收到的其他节点报文&lt;br&gt;如果需要candump显示自身节点发送出去的报文，需在配置CAN接口时使能loopback 功能&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nano /etc/network/interfaces.d/can1

allow-hotplug can1
iface can1 can static
bitrate 250000
restart-ms 100
txqueuelen 1000
loopback on
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;🔌 重启生效&lt;/p&gt;
&lt;blockquote&gt;
&lt;h2 id=&quot;h2--can-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;发送CAN 消息&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;发送CAN 消息&lt;/h2&gt;&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;#For example to send a message with 
#identifier 0x123 
#and 
#payload [0x40,0x00,0x10,0x00,0x00,0x00,0x0,0x000]

cansend can0 603#4000100000000000
&lt;/code&gt;&lt;/pre&gt;
&lt;/body&gt;</description><pubDate>Thu, 07 Mar 2024 13:17:21 +0800</pubDate></item><item><title>[CompactCom 40] PROFIBUS 自动读取IO数据配置Config</title><link>http://www.swwtech.cn/ProductTest/DpConfigIO/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;h1 id=&quot;h1-1-get_cfg-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;1. Get_Cfg 服务&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1. Get_Cfg 服务&lt;/h1&gt;&lt;p&gt;PROFIBUS DP 协议规定了可选的SD2 报文 Get_Cfg，&lt;br&gt;如果从站支持此报文服务，那么主站可以通过发送Get_Cfg来获取从站当前实际的IO数据配置Config&lt;/p&gt;
&lt;p&gt;SD2 的报文格式如下&lt;br&gt;&lt;img title=&quot;20240226094051170891165172359.png&quot; alt=&quot;20240226094051170891165172359.png&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/02/20240226094051170891165172359.png&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-1-1-get_cfg-request-gt-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;1.1 Get_Cfg Request请求报文(主–&gt;收)&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.1 Get_Cfg Request请求报文(主–&amp;gt;收)&lt;/h2&gt;&lt;p&gt;每个字段的含义如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SD2 		起始符SD2固定赋值为0x68&lt;/li&gt;&lt;li&gt;LE和LEr  长度，固定赋值为0x05&lt;/li&gt;&lt;li&gt;DA 		目标地址，赋值为0x80+从站ID&lt;/li&gt;&lt;li&gt;SA 		源地址，赋值为0x80+主站ID&lt;/li&gt;&lt;li&gt;FC 		功能码，固定赋值为0x6D&lt;/li&gt;&lt;li&gt;DSAP 	目标服务点，固定赋值为0x3B&lt;/li&gt;&lt;li&gt;SSAP		源服务点，固定赋值为0x3E&lt;/li&gt;&lt;li&gt;PDU		Get_Cfg请求中没有数据&lt;/li&gt;&lt;li&gt;FCS		校验和，是从DA到SSAP字段的算数和&lt;/li&gt;&lt;li&gt;ED		结束符固定使用0x16&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;h2-1-2-get_cfg-response-lt-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;1.2 Get_Cfg Response响应报文（主&lt;–发）&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.2 Get_Cfg Response响应报文（主&amp;lt;–发）&lt;/h2&gt;&lt;p&gt;每个字段的含义如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SD2 		起始符SD2固定赋值为0x68&lt;/li&gt;&lt;li&gt;LE和LEr  长度，0x05 + IO 配置Config PDU的数据长度&lt;/li&gt;&lt;li&gt;DA 		目标地址，赋值为0x80+主站ID&lt;/li&gt;&lt;li&gt;SA 		源地址，赋值为0x80+从ID&lt;/li&gt;&lt;li&gt;FC 		功能码，固定赋值为0x6D&lt;/li&gt;&lt;li&gt;DSAP 	目标服务点，固定赋值为0x3B&lt;/li&gt;&lt;li&gt;SSAP		源服务点，固定赋值为0x3E&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: #df2a3f&quot;&gt;&lt;strong&gt;PDU		IO 配置Config 的响应数据&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;FCS		校验和，是从DA到PDU字段的算数和&lt;/li&gt;&lt;li&gt;ED		结束符固定使用0x16&lt;/li&gt;&lt;/ul&gt;
&lt;h1 id=&quot;h1-2-usb-rs485-io-config&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;2.使用USB转RS485 工具读取 IO 配置Config&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.使用USB转RS485 工具读取 IO 配置Config&lt;/h1&gt;&lt;h2 id=&quot;h2-2-1-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;2.1 物理连接&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.1 物理连接&lt;/h2&gt;&lt;p&gt;使用任意的USB转RS485,USB端插入电脑USB接口处&lt;br&gt;测试使用的型号是&lt;a title=&quot;ZTEK ZE571A&quot; href=&quot;https://3.cn/1VVOD-fq&quot;&gt;ZTEK ZE571A&lt;/a&gt;&lt;br&gt;&lt;img title=&quot;202403261116029267965.png&quot; alt=&quot;202403261116029267965.png&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/03/202403261116029267965.png&quot;&gt;&lt;br&gt;&lt;img title=&quot;202403261115172339151.png&quot; alt=&quot;202403261115172339151.png&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/03/202403261115172339151.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;👓 USB转RS485 的 D+ 连接 PROFIBUS 从站DB9 的PIN3 B&lt;br&gt;👓 USB转RS485 的 D- 连接 PROFIBUS 从站DB9 的PIN8 A&lt;/p&gt;
&lt;p&gt;⚠️PROFIBUS DB9 数据信号 A/B 标记是和 RS485 的信号A/B 标记相反的&lt;/p&gt;
&lt;p&gt;⚠️电脑通过USB转RS485 1对1 连接PROFIBUS 从站， 不要连接其他任何主站设备&lt;/p&gt;
&lt;h2 id=&quot;h2-2-2-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;2.2 通讯参数配置&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.2 通讯参数配置&lt;/h2&gt;&lt;p&gt;端口号选择USB转RS485在电脑上的实际端口号&lt;/p&gt;
&lt;p&gt;波特率设置为9600bps&lt;br&gt;数据位 8bits&lt;br&gt;停止位 1bits&lt;br&gt;校验位 Even偶校验&lt;/p&gt;
&lt;p&gt;🚩&lt;br&gt;&lt;img title=&quot;ComParameters.png&quot; alt=&quot;ComParameters.png&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/02/ComParameters.png&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-2-3-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;2.3 从站设置&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.3 从站设置&lt;/h2&gt;&lt;p&gt;为了方便测试和计算FCS，我们假设从站的ID 设置为 5， 主站的ID 设置为 1&lt;/p&gt;
&lt;h2 id=&quot;h2-2-4-&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;2.4 模拟测试&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.4 模拟测试&lt;/h2&gt;&lt;p&gt;通过以上配置，我们可以通过主站发送以下数据，即Get_Cfg请求报文Request&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;68 05 05 68 85 81 6D 3B 3E EC 16
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从站在收到请求后， 会进行响应，响应报文Response&lt;br&gt;⚠️ 由于PROFIBUS 时序要求严格，可能发送多次请求后从站才会响应&lt;/p&gt;
&lt;p&gt;例如示例的响应如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;68 0F 0F 68 81 85 08 3E 3B 43 DF 00 01 00 83 DF 00 02 00 0E 16
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据响应中的LE/LEr 可以判断出，PDU 长度是0x0F-0x05 = 0x0A&lt;/p&gt;
&lt;p&gt;数据内容是&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;43 DF 00 01 00 83 DF 00 02 00 0E
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即为该从站的IO配置Config&lt;/p&gt;
&lt;br&gt;

&lt;p&gt;&lt;img title=&quot;config.png&quot; alt=&quot;config.png&quot; src=&quot;http://www.swwtech.cn/zb_users/upload/2024/02/config.png&quot;&gt;&lt;/p&gt;
&lt;/body&gt;</description><pubDate>Mon, 26 Feb 2024 09:28:17 +0800</pubDate></item><item><title>[Raspberry PI CM4] 设置网卡静态IP</title><link>http://www.swwtech.cn/RasperryCM4/StaticIP/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;h1 id=&quot;h1-1-networkmanager&quot;&gt;&lt;a class=&quot;reference-link&quot; name=&quot;1. NetworkManager&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1. NetworkManager&lt;/h1&gt;&lt;p&gt;在版本比较旧的树莓派系统上，可以修改 /etc/dhcpcd.conf 设置静态IP&lt;/p&gt;
&lt;p&gt;但在新的系统上需要使用 NetworkManager 进行网络管理&lt;/p&gt;
&lt;p&gt;首先使用&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;nmcli connection show
NAME                UUID                                  TYPE      DEVICE
HMS-Lab-5G          7f8194c6-a86a-4517-8517-198b1eeb8069  wifi      wlan0
lo                  693c2185-73c8-4466-bb50-e9c17cf36b24  loopback  lo
Wired connection 1  e197b89b-7a02-3621-9bf9-668a997539fa  ethernet  eth0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看当前的网络连接情况&lt;/p&gt;
&lt;p&gt;然后使用&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nmcli connection modify &quot;Wired connection 1&quot; ipv4.method manual ipv4.addresses 192.168.0.2/24
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意连接名称需使用双引号&lt;/p&gt;
&lt;p&gt;配置需要的静态IP 地址&lt;/p&gt;
&lt;p&gt;最后重启生效&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看是否生效&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt; ifconfig
eth0: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500
        inet 192.168.0.2  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::131:1b88:fe03:502d  prefixlen 64  scopeid 0x20&amp;lt;link&amp;gt;
        ether d8:3a:dd:64:8b:e3  txqueuelen 1000  (Ethernet)
        RX packets 1  bytes 115 (115.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 28  bytes 3907 (3.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
&lt;/code&gt;&lt;/pre&gt;
&lt;/body&gt;</description><pubDate>Thu, 22 Feb 2024 16:38:12 +0800</pubDate></item><item><title>[Raspberry PI CM4] Linux 软件源更改</title><link>http://www.swwtech.cn/RasperryCM4/SourceList/</link><description>&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;树莓派默认软件源地址是国外的服务器地址，经常出现更新速度慢或者连不上的情况。&lt;br&gt;我们只需要将软件源换成国内镜像源这个问题就得以解决了。&lt;/p&gt;
&lt;p&gt;下面我们更改为阿里云的软件源&lt;/p&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 首先修改配置文件/etc/apt/sources.list&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nano /etc/apt/sources.list
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;deb https://mirrors.aliyun.com/debian bookworm main contrib non-free non-free-firmware
deb https://mirrors.aliyun.com/debian-security/ bookworm-security main contrib non-free non-free-firmware
deb https://mirrors.aliyun.com/debian bookworm-updates main contrib non-free non-free-firmware
&lt;/code&gt;&lt;/pre&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 然后修改配置文件 /etc/apt/sources.list.d/raspi.list&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo nano /etc/apt/sources.list.d/raspi.list
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;deb http://mirrors.aliyun.com/raspbian/raspbian/ bookworm  main non-free contrib rpi
deb-src http://mirrors.aliyun.com/raspbian/raspbian/ bookworm main non-free contrib rpi
&lt;/code&gt;&lt;/pre&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 修改完成后，重启&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 执行更新&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo apt-get update
sudo apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; checked=&quot;&quot; class=&quot;task-list-item-checkbox&quot;&gt; 软件源签名问题解决办法&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;如果更新时，提示软件源没有签名无法更新错误&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 9165938D90FDDD2E
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以使用下面的命令添加签名&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
Executing: /tmp/apt-key-gpghome.W4j5VSu42Z/gpg.1.sh --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E
gpg: key 9165938D90FDDD2E: public key &quot;Mike Thompson (Raspberry Pi Debian armhf ARMv6+VFP) &amp;lt;mpthompson@gmail.com&amp;gt;&quot; imported
gpg: Total number processed: 1
gpg:               imported: 1
&lt;/code&gt;&lt;/pre&gt;
&lt;/body&gt;</description><pubDate>Thu, 22 Feb 2024 15:13:35 +0800</pubDate></item></channel></rss>