解决标准输入输出的问题

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 Transport = case string:trim(Name0) of
<<"rtu">> -> <<"rtu">> ->
#modbus_transport_rtu{ #modbus_transport_rtu{
port = maps:get(<<"port">>, PropsMap, undefined), port = map_of_binary(<<"port">>, PropsMap, undefined),
baudrate = maps:get(<<"baudrate">>, PropsMap, undefined), baudrate = map_of_integer(<<"baudrate">>, PropsMap, undefined),
parity = maps:get(<<"parity">>, PropsMap, undefined), parity = map_of_binary(<<"parity">>, PropsMap, undefined),
stopbits = maps:get(<<"stopbits">>, PropsMap, undefined), stopbits = map_of_integer(<<"stopbits">>, PropsMap, undefined),
timeout = maps:get(<<"timeout">>, PropsMap, undefined) timeout = map_of_time(<<"timeout">>, PropsMap, undefined)
}; };
<<"tcp">> -> <<"tcp">> ->
#modbus_transport_tcp { #modbus_transport_tcp {
@ -276,12 +276,13 @@ parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc
%% AST的合法性和一致性 %% AST的合法性和一致性
validate([]) -> validate([]) ->
ok; ok;
validate([#modbus{transport = #modbus_transport_rtu{port = Port, baudrate = Baudrate}}|T]) -> validate([#modbus{transport = #modbus_transport_rtu{port = Port0, baudrate = Baudrate}}|T]) ->
case filelib:is_file(Port) andalso Baudrate > 0 of Port = binary_to_list(Port0),
case filename:validate(Port) andalso Baudrate > 0 of
true -> true ->
validate(T); validate(T);
false -> false ->
throw({invalid_transport_rtu, {Port, Baudrate}}) throw({invalid_transport_rtu, {Port0, Baudrate}})
end; end;
validate([#modbus{transport = #modbus_transport_tcp{host = Host, port = Port}}|T]) -> validate([#modbus{transport = #modbus_transport_tcp{host = Host, port = Port}}|T]) ->
case Host /= undefined andalso Port > 0 of 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}}; {next_state, ?DISCONNECTED, State#state{socket = undefined}};
%% , todo is_pending的状态要形成闭环 %% , 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 case connect(Transport) of
{ok, ConnectResult} -> {ok, ConnectResult} ->
Actions = case not queue:is_empty(Q) of Actions = case not queue:is_empty(Q) of
@ -207,8 +208,8 @@ handle_event(info, modbus_connect, ?DISCONNECTED, State = #state{ast = #ast{modb
end, end,
case ConnectResult of case ConnectResult of
{rtu, Port, DelayMs} -> {rtu, Port, DelayMs} ->
%% %% todo
erlang:start_timer(0, self(), read_next), % erlang:start_timer(0, self(), read_next),
{next_state, ?CONNECTED, State#state{mode = rtu, port = Port, delay_ms = DelayMs, is_pending = false}, Actions}; {next_state, ?CONNECTED, State#state{mode = rtu, port = Port, delay_ms = DelayMs, is_pending = false}, Actions};
Socket -> Socket ->
{next_state, ?CONNECTED, State#state{mode = tcp, socket = Socket}, Actions} {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 %% 5
retry_connect(), retry_connect(),
{keep_state, State} {keep_state, State}
end; end.
handle_event(_EventType, _EventContent, _StateName, State = #state{}) ->
NextStateName = the_next_state_name,
{next_state, NextStateName, State}.
%% @private %% @private
%% @doc This function is called by a gen_statem when it is about to %% @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{}) -> -spec connect(Transport :: #modbus_transport_rtu{} | #modbus_transport_tcp{}) ->
{ok, {rtu, Port :: port(), DelayMs :: integer()}} | {ok, Socket :: gen_tcp:socket()} | {error, Reason :: any()}. {ok, {rtu, Port :: port(), DelayMs :: integer()}} | {ok, Socket :: gen_tcp:socket()} | {error, Reason :: any()}.
%% databits为8位 %% databits为8位
connect(#modbus_transport_rtu{port = Port, baudrate = BaudRate, stopbits = StopBits, parity = Parity, timeout = Timeout}) -> connect(#modbus_transport_rtu{port = SerialPort, baudrate = BaudRate, stopbits = StopBits, parity = Parity0, timeout = Timeout}) ->
RealExecCmd = "", lager:warning("call me here connect, serial_port: ~p", [SerialPort]),
Port = erlang:open_port({spawn_executable, RealExecCmd}, [binary, {packet, 2}, exit_status]),
%%
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), DelayMs = frame_delay(BaudRate, 8, Parity, StopBits),
lager:debug("port is: ~p", [Port]),
Len0 = byte_size(Port),
ConnectCmd = <<?MODBUS_CONNECT:8, Len0:8, Port/binary, BaudRate:32, StopBits:8, Parity:8, Timeout:32>>,
%% %%
Port ! {self(), {command, ConnectCmd}},
{ok, {rtu, Port, DelayMs}}; {ok, {rtu, Port, DelayMs}};
connect(#modbus_transport_tcp{host = Host, port = Port, timeout = Timeout0}) -> connect(#modbus_transport_tcp{host = Host, port = Port, timeout = Timeout0}) ->
Timeout = case is_integer(Timeout0) andalso Timeout0 > 0 of Timeout = case is_integer(Timeout0) andalso Timeout0 > 0 of

View File

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