Systemctl 重启后无法启动使用 ttyACM0 端口的服务

Systemctl 重启后无法启动使用 ttyACM0 端口的服务

我需要在 ttyACM0 端口可用后启动我自己用 C# (.NET6) 编写的服务 (SignalR 客户端)。此服务应在其他服务 (SignalR 服务器)。

重启后服务器服务正常启动(毫无问题)客户服务状态给出信息:

● RfidHwSigRClient.service
Loaded: loaded (/etc/systemd/system/RfidHwSigRClient.service;
disabled; vendor preset: enabled)    Active: inactive (dead) since Mon
2023-03-06 22:20:58 CET; 2min 17s ago   Process: 1583
ExecStart=/usr/bin/dotnet
/home/predator/Projects/VSLinuxDbg/RfidHwSigRClient/RfidHwSigRClient.dll
(code=exited, status=0/SUCCESS)   Process: 767 ExecStartPre=/bin/sleep
10 (code=exited, status=0/SUCCESS)  Main PID: 1583 (code=exited,
status=0/SUCCESS)

Mar 06 22:20:46 PredatorClient systemd[1]: Starting
RfidHwSigRClient.service... Mar 06 22:20:57 PredatorClient
dotnet[1583]: Microsoft.Hosting.Lifetime[0] Application started.
Hosting environment: Production; Content root path: / Mar 06 22:20:57
PredatorClient systemd[1]: Started RfidHwSigRClient.service. Mar 06
22:20:58 PredatorClient dotnet[1583]:
Microsoft.Extensions.Hosting.Internal.Host[9] BackgroundService failed
System.UnauthorizedAccessException: Access to the port '/dev/usb_rfid'
is denied.  ---> System.IO.IOException: Device or resource busy    ---
End of inner exception stack trace ---    at
System.IO.Ports.SafeSerialDeviceHandle.Open(String portName)    at
System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate,
Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout,
Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean
rtsEnable, Boolean discardNull, Byte parityReplace)    at
System.IO.Ports.SerialPort.Open()    at
Predator.Hardware.RfIDCard.RfId.Connect() in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\Hardware\RFIDCard\RfId.cs:line
159    at
Predator.SignalRComm.RfidHwSigRClient.RfidBroker.ConnectAsync() in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\SignalRComm\Derived\RfidHwSigRClient\RfidHwSigRClient\RfidBroker.cs:line
95    at
Predator.SignalRComm.RfidHwSigRClient.RfidBroker.ExecuteAsync(CancellationToken
stoppingToken) in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\SignalRComm\Derived\RfidHwSigRClient\RfidHwSigRClient\RfidBroker.cs:line
77    at
Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService
backgroundService) Mar 06 22:20:58 PredatorClient dotnet[1583]:
Microsoft.Extensions.Hosting.Internal.Host[10] The
HostOptions.BackgroundServiceExceptionBehavior is configured to
StopHost. A BackgroundService has thrown an unhandled exception, and
the IHost instance is stopping. To avoid this behavior, configure this
to Ignore; however the BackgroundService will not be restarted.
System.UnauthorizedAccessException: Access to the port '/dev/usb_rfid'
is denied.  ---> System.IO.IOException: Device or resource busy    ---
End of inner exception stack trace ---    at
System.IO.Ports.SafeSerialDeviceHandle.Open(String portName)    at
System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate,
Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout,
Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean
rtsEnable, Boolean discardNull, Byte parityReplace)    at
System.IO.Ports.SerialPort.Open()    at
Predator.Hardware.RfIDCard.RfId.Connect() in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\Hardware\RFIDCard\RfId.cs:line
159    at
Predator.SignalRComm.RfidHwSigRClient.RfidBroker.ConnectAsync() in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\SignalRComm\Derived\RfidHwSigRClient\RfidHwSigRClient\RfidBroker.cs:line
95    at
Predator.SignalRComm.RfidHwSigRClient.RfidBroker.ExecuteAsync(CancellationToken
stoppingToken) in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\SignalRComm\Derived\RfidHwSigRClient\RfidHwSigRClient\RfidBroker.cs:line
77    at
Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService
backgroundService) Mar 06 22:20:58 PredatorClient dotnet[1583]:
Microsoft.Hosting.Lifetime[0] Application is shutting down...

问题是该端口不可用。

一旦启动 Ubuntu,我就可以systemctl restart service_name从命令行重新启动客户端服务(),并且服务正常运行(端口已准备好)。

我读过几个论坛上关于如何启动服务的文章。不幸的是,没有任何成功。

我的 udev 规则如下:

KERNEL=="ttyACM*", ATTRS{manufacturer}=="MOD elektronik*", ATTRS{product}=="MOD RFID reader", MODE="0666", SYMLINK+="usb_rfid", ENV{SYSTEMD_WANTS}+="RfidHwSigRClient.service"

我的 RfidHwSigRClient.service 如下所示:

[unit]
Description=RFId Card Reader SignalR Client Service
BindsTo=dev-usb_rfid.device
Requires=MainSigRServer.service
After=dev-usb_rfid.device MainSigRserver.service
StartLimitIntervalSec=300
StartLimitBurst=30

[Service]
User=predator
Group=predator
Type=notify
ExecStartPre=/bin/sleep 10
ExecStart=/usr/bin/dotnet /home/predator/Projects/VSLinuxDbg/RfidHwSigRClient/RfidHwSigRClient.dll
TimeoutStartSec=30s
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-use

我还尝试过 10 秒后启动服务 ( ExecStartPre=/bin/sleep 10),但没有任何成功。用户 Predator 属于组 Dialout。Ubuntu 是 18.04 LTS。

请问,有人知道我做错了什么吗?谢谢。R。

答案1

我不得不使用大约 15 秒的睡眠来启动客户端服务。如果睡眠时间为 10 秒,则端口尚未准备好(拒绝访问)。但是,我仍然不知道如何在端口和服务器服务都准备好后立即启动客户端服务。

我的RfidHwSigRClient.service临时配置如下:

[Unit]
Description=RFId Card Reader SignalR Client Service
BindsTo=dev-usb_rfid.device
After=dev-usb_rfid.device MainSigRServer.service
StartLimitIntervalSec=300
StartLimitBurst=30

[Service]
Type=notify
ExecStartPre=/bin/sleep 15
ExecStart=/usr/bin/dotnet /home/predator/Projects/VSLinuxDbg/RfidHwSigRClient/RfidHwSigRClient.dll
Restart=on-failure
RestartSec=5s
User=predator
Group=predator

[Install]
WantedBy=dev-usb_rfid.device

Udev 规则 99-usb-serial.rules 是:

KERNEL=="ttyACM*", ATTRS{manufacturer}=="MOD elektronik*", ATTRS{product}=="MOD RFID reader", SYMLINK+="usb_rfid", MODE="0666", ACTION=="add", RUN+="/home/predator/Projects/Scripts/rfid_plugged.sh", TAG+="systemd" ENV{SYSTEMD_WANTS}+="MainSigRServer.service"

谢谢..

相关内容