I have a similar task, read/write to a MODBUS fieldbu=
s (RS485).
I can successfully read with this funct=
ion:
let rec really_read ?(timeout =3D 0.5) fd buffer start length =3D=
b>
=C2=A0 let open Unix in
=C2=A0 if length &=
lt;=3D 0 then () else begin
=C2=A0 =C2=A0 match Unix.select [ fd ] [] [] timeout with
=C2=A0 =C2=A0 | [], [], [] -&=
gt; raise (Timeout timeout)
=C2=A0 =C2=A0 | fdl, _, _ -> begin
<=
b>=C2=A0 =C2=A0 =C2=A0 =C2=A0 match r=
ead fd buffer start length with
=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=
0 -> raise End_of_file
=C2=A0 =C2=A0 =C2=A0 =C2=A0 | r -> really_read fd buffer (=
start + r) (length - r)
=C2=A0 =C2=A0 =C2=A0 end
=C2=A0 end=
The code in which I use really_read looks like this:
=C2=A0 Un=
ix.write ctx.descriptor packet 0 packet_len |> ignore;
<=
div>
=C2=A0 let buffer =3D String.m=
ake 2048 (Char.chr 0) in
=C2=A0 let timeout =3D 1.0 in=
=C2=A0 let e=
xpected_bytes =3D 13 in
=C2=A0 really_read ~timeout ctx.descriptor buffer 0 expected_byt=
es;
let modbus_connect device_name baud csize parity cstopb =3D=
b>
=C2=A0 let open Unix in
=C2=A0 let descrip=
tor =3D openfile device_name [ O_RDWR; O_NOCTTY; O_NONBLOCK; O_EXCL; O_CLOE=
XEC; ] 0o660 in
=C2=A0 let old_terminal_setti=
ngs =3D tcgetattr descriptor in
=C2=A0 let slave_id =3D None in
=
=C2=A0 let ctx =3D { device_name; bau=
d; parity; csize; cstopb; descriptor; old_terminal_settings; slave_id; } in=
=
=C2=A0 let term_settings =3D tcgetatt=
r descriptor in
=C2=A0 term_settings.c_obaud <- baud;
=C2=A0 term_settings.c_ibaud =
<- baud;
=
=C2=A0 term_settings.c_cread <- true;
=C2=A0 term_settings.c_clocal <- true;
=C2=A0 term_settings.c_csize =
<- csize;
=
=C2=A0 term_settings.c_cstopb <- cstopb;
=C2=A0 let () =3D match parity with=
b>
=C2=A0 =C2=A0 | Parity_None -=
> begin
=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 term_settings.c_inpck <- false;=
div>
=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 term_settings.c_parenb <- false;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=
erm_settings.c_parodd <- false;
=C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 | Parity_Even -> begin=
font>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=
erm_settings.c_inpck <- true;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 term_settings.c_parenb <=
- true;
=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 term_settings.c_parodd <- false;
=C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 | P=
arity_Odd -> begin
=C2=A0 =C2=A0 =C2=A0 =C2=A0 term_settings.c_inpck <- true;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=
erm_settings.c_parenb <- true;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 term_settings.c_parodd <=
;- true;
=C2=
=A0 =C2=A0 =C2=A0 end in
=C2=A0 term_settings.c_icanon=
<- false;
=C2=A0 term_settings.c_echo =C2=A0 <- false;
=C2=A0 term_settings.c_echoe =C2=A0<=
- false;
=C2=A0 term_settings.c_echok =
=C2=A0<- false;
=C2=A0 term_settings.c_echonl <- false;
=C2=A0 term_settings.c_isig =C2=A0 <=
- false;
=C2=A0 term_settings.c_ixon =
=C2=A0 <- false;
=C2=A0 term_settings.c_ixoff =C2=A0<- false;
=C2=A0 term_settings.c_opost =C2=
=A0<- false;
=C2=A0 term_settings.c_vmin =
=C2=A0 <- 0;
=C2=A0 term_settings.c_vtime =C2=A0<- 0;
=C2=A0 let (=
) =3D tcsetattr descriptor TCSANOW term_settings in
=C2=A0 ctx
ctx is a type in w=
hich I keep the context for the connection.
Hope t=
his may help.
--089e0115ea2efe91a80500806a5e--