解决标准输入输出的问题

This commit is contained in:
anlicheng 2025-07-01 23:50:35 +08:00
parent f9910a23de
commit 9c38133b1f
3 changed files with 39 additions and 28 deletions

View File

@ -258,11 +258,11 @@ parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc
Transport = case string:trim(Name0) of
<<"rtu">> ->
#modbus_transport_rtu{
port = maps:get(<<"port">>, PropsMap, undefined),
baudrate = maps:get(<<"baudrate">>, PropsMap, undefined),
parity = maps:get(<<"parity">>, PropsMap, undefined),
stopbits = maps:get(<<"stopbits">>, PropsMap, undefined),
timeout = maps:get(<<"timeout">>, PropsMap, undefined)
port = map_of_binary(<<"port">>, PropsMap, undefined),
baudrate = map_of_integer(<<"baudrate">>, PropsMap, undefined),
parity = map_of_binary(<<"parity">>, PropsMap, undefined),
stopbits = map_of_integer(<<"stopbits">>, PropsMap, undefined),
timeout = map_of_time(<<"timeout">>, PropsMap, undefined)
};
<<"tcp">> ->
#modbus_transport_tcp {
@ -276,12 +276,13 @@ parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc
%% AST的合法性和一致性
validate([]) ->
ok;
validate([#modbus{transport = #modbus_transport_rtu{port = Port, baudrate = Baudrate}}|T]) ->
case filelib:is_file(Port) andalso Baudrate > 0 of
validate([#modbus{transport = #modbus_transport_rtu{port = Port0, baudrate = Baudrate}}|T]) ->
Port = binary_to_list(Port0),
case filename:validate(Port) andalso Baudrate > 0 of
true ->
validate(T);
false ->
throw({invalid_transport_rtu, {Port, Baudrate}})
throw({invalid_transport_rtu, {Port0, Baudrate}})
end;
validate([#modbus{transport = #modbus_transport_tcp{host = Host, port = Port}}|T]) ->
case Host /= undefined andalso Port > 0 of

View File

@ -198,7 +198,8 @@ handle_event(info, {tcp_error, Socket, Reason}, ?CONNECTED, State = #state{mode
{next_state, ?DISCONNECTED, State#state{socket = undefined}};
%% , todo is_pending的状态要形成闭环
handle_event(info, modbus_connect, ?DISCONNECTED, State = #state{ast = #ast{modbus = #modbus{transport = Transport}}, queue = Q}) ->
handle_event(info, {timeout, _Ref, modbus_connect}, ?DISCONNECTED, State = #state{ast = #ast{modbus = #modbus{transport = Transport}}, queue = Q}) ->
lager:debug("call me will connect, transport: ~p", [Transport]),
case connect(Transport) of
{ok, ConnectResult} ->
Actions = case not queue:is_empty(Q) of
@ -207,8 +208,8 @@ handle_event(info, modbus_connect, ?DISCONNECTED, State = #state{ast = #ast{modb
end,
case ConnectResult of
{rtu, Port, DelayMs} ->
%%
erlang:start_timer(0, self(), read_next),
%% todo
% erlang:start_timer(0, self(), read_next),
{next_state, ?CONNECTED, State#state{mode = rtu, port = Port, delay_ms = DelayMs, is_pending = false}, Actions};
Socket ->
{next_state, ?CONNECTED, State#state{mode = tcp, socket = Socket}, Actions}
@ -218,11 +219,7 @@ handle_event(info, modbus_connect, ?DISCONNECTED, State = #state{ast = #ast{modb
%% 5
retry_connect(),
{keep_state, State}
end;
handle_event(_EventType, _EventContent, _StateName, State = #state{}) ->
NextStateName = the_next_state_name,
{next_state, NextStateName, State}.
end.
%% @private
%% @doc This function is called by a gen_statem when it is about to
@ -244,16 +241,29 @@ code_change(_OldVsn, StateName, State = #state{}, _Extra) ->
-spec connect(Transport :: #modbus_transport_rtu{} | #modbus_transport_tcp{}) ->
{ok, {rtu, Port :: port(), DelayMs :: integer()}} | {ok, Socket :: gen_tcp:socket()} | {error, Reason :: any()}.
%% databits为8位
connect(#modbus_transport_rtu{port = Port, baudrate = BaudRate, stopbits = StopBits, parity = Parity, timeout = Timeout}) ->
RealExecCmd = "",
Port = erlang:open_port({spawn_executable, RealExecCmd}, [binary, {packet, 2}, exit_status]),
connect(#modbus_transport_rtu{port = SerialPort, baudrate = BaudRate, stopbits = StopBits, parity = Parity0, timeout = Timeout}) ->
lager:warning("call me here connect, serial_port: ~p", [SerialPort]),
%%
Parity = case Parity0 of
<<"none">> -> 0;
<<"odd">> -> 1;
<<"even">> -> 2;
_ -> 0
end,
RealExecCmd = "/usr/local/code/cloudkit/modbus/apps/modbus/priv/bin/modbus_agent",
Args = [
"--port " ++ binary_to_list(SerialPort),
"--baud_rate " ++ integer_to_list(BaudRate),
"--stop_bits " ++ integer_to_list(StopBits),
"--parity " ++ integer_to_list(Parity),
"--timeout " ++ integer_to_list(Timeout)
],
Port = erlang:open_port({spawn_executable, RealExecCmd}, [binary, {packet, 2}, exit_status, {args, Args}]),
lager:debug("args: ~p", [Args]),
DelayMs = frame_delay(BaudRate, 8, Parity, StopBits),
Len0 = byte_size(Port),
ConnectCmd = <<?MODBUS_CONNECT:8, Len0:8, Port/binary, BaudRate:32, StopBits:8, Parity:8, Timeout:32>>,
lager:debug("port is: ~p", [Port]),
%%
Port ! {self(), {command, ConnectCmd}},
{ok, {rtu, Port, DelayMs}};
connect(#modbus_transport_tcp{host = Host, port = Port, timeout = Timeout0}) ->
Timeout = case is_integer(Timeout0) andalso Timeout0 > 0 of

View File

@ -9,11 +9,11 @@ modbus {
}
# 或TCP配置
transport tcp {
host 192.168.1.100;
port 502;
timeout 500ms;
}
#transport tcp {
# host 192.168.1.100;
# port 502;
# timeout 500ms;
#}
# 日志设置
error_log /var/log/modbus_error.log;