RPMsg inter-partition messaging
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Port monorepo to latest ocaml-wire (opam pin)

Migrate all consumers to the new wire API:
- wire.c library → wire.3d (Wire_c → Wire_3d)
- Wire.struct_/module_ → Wire.Everparse.struct_/module_
- Wire.Codec: record/|+/seal → Codec.v with Field.v and $
- Wire.bf_uint* → Wire.U8/U16/U16be/U32/U32be
- Wire.UInt32 → Wire.Private.UInt32
- Wire.cases → Wire.lookup, Wire.map now uses labeled args
- Wire.Codec.decode now returns result
- Add wire pin to root.opam.template

+36 -25
+5 -3
fuzz/fuzz_rpmsg.ml
··· 10 10 let info = Rpmsg.{ name; src; dst } in 11 11 let buf = Bytes.create Rpmsg.endpoint_info_size in 12 12 Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0; 13 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in 14 - if decoded.src <> src then fail "src mismatch"; 15 - if decoded.dst <> dst then fail "dst mismatch" 13 + match Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 with 14 + | Error _ -> fail "decode failed" 15 + | Ok decoded -> 16 + if decoded.src <> src then fail "src mismatch"; 17 + if decoded.dst <> dst then fail "dst mismatch" 16 18 17 19 let test_decode_crash_safety buf = 18 20 if String.length buf < Rpmsg.endpoint_info_size then ()
+17 -13
lib/rpmsg.ml
··· 18 18 19 19 type endpoint_info = { name : string; src : int; dst : int } 20 20 21 + let f_ei_name = Wire.Field.v "name" (Wire.byte_array ~size:(Wire.int 32)) 22 + let f_ei_src = Wire.Field.v "src" Wire.uint32 23 + let f_ei_dst = Wire.Field.v "dst" Wire.uint32 24 + 21 25 let endpoint_info_codec = 22 - let open Wire.Codec in 23 - record "rpmsg_endpoint_info" (fun name src dst -> { name; src; dst }) 24 - |+ field "name" 25 - (Wire.byte_array ~size:(Wire.int 32)) 26 - (fun t -> 27 - (* Pad/truncate name to exactly 32 bytes *) 28 - let b = Bytes.make 32 '\x00' in 29 - let len = min (String.length t.name) 31 in 30 - Bytes.blit_string t.name 0 b 0 len; 31 - Bytes.to_string b) 32 - |+ field "src" Wire.uint32 (fun t -> t.src) 33 - |+ field "dst" Wire.uint32 (fun t -> t.dst) 34 - |> seal 26 + Wire.Codec.v "rpmsg_endpoint_info" 27 + (fun name src dst -> { name; src; dst }) 28 + Wire.Codec. 29 + [ 30 + ( f_ei_name $ fun t -> 31 + (* Pad/truncate name to exactly 32 bytes *) 32 + let b = Bytes.make 32 '\x00' in 33 + let len = min (String.length t.name) 31 in 34 + Bytes.blit_string t.name 0 b 0 len; 35 + Bytes.to_string b ); 36 + (f_ei_src $ fun t -> t.src); 37 + (f_ei_dst $ fun t -> t.dst); 38 + ] 35 39 36 40 let endpoint_info_size = Wire.Codec.wire_size endpoint_info_codec 37 41
+14 -9
test/test_wire.ml
··· 12 12 (* RPMSG_ADDR_ANY from include/uapi/linux/rpmsg.h *) 13 13 let rpmsg_addr_any = 0xFFFFFFFF 14 14 15 + let decode_exn codec buf off = 16 + match Wire.Codec.decode codec buf off with 17 + | Ok v -> v 18 + | Error e -> Alcotest.failf "decode: %a" Wire.pp_parse_error e 19 + 15 20 (* _IOW(type, nr, size) from include/uapi/asm-generic/ioctl.h *) 16 21 let iow typ nr size = (1 lsl 30) lor (size lsl 16) lor (typ lsl 8) lor nr 17 22 ··· 27 32 let info = Rpmsg.{ name = "rpmsg-test-channel"; src = 1024; dst = 1025 } in 28 33 let buf = Bytes.create Rpmsg.endpoint_info_size in 29 34 Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0; 30 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in 35 + let decoded = decode_exn Rpmsg.endpoint_info_codec buf 0 in 31 36 (* Name is padded to 32 bytes with nulls *) 32 37 let expected_name = "rpmsg-test-channel" in 33 38 Alcotest.(check bool) ··· 41 46 let info = Rpmsg.{ name = "a"; src = 0; dst = 0 } in 42 47 let buf = Bytes.create Rpmsg.endpoint_info_size in 43 48 Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0; 44 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in 49 + let decoded = decode_exn Rpmsg.endpoint_info_codec buf 0 in 45 50 Alcotest.(check char) "first byte" 'a' (String.get decoded.name 0); 46 51 (* Rest should be null-padded *) 47 52 Alcotest.(check char) "second byte" '\x00' (String.get decoded.name 1); ··· 52 57 let info = Rpmsg.{ name = String.make 31 'X'; src = 100; dst = 200 } in 53 58 let buf = Bytes.create Rpmsg.endpoint_info_size in 54 59 Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0; 55 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in 60 + let decoded = decode_exn Rpmsg.endpoint_info_codec buf 0 in 56 61 (* Name field is 32 bytes, last byte should be null terminator *) 57 62 Alcotest.(check char) "last name byte" '\x00' (String.get decoded.name 31); 58 63 Alcotest.(check int) "src" 100 decoded.src; ··· 63 68 let info = Rpmsg.{ name = String.make 50 'Z'; src = 42; dst = 43 } in 64 69 let buf = Bytes.create Rpmsg.endpoint_info_size in 65 70 Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0; 66 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in 71 + let decoded = decode_exn Rpmsg.endpoint_info_codec buf 0 in 67 72 (* Last byte must be null *) 68 73 Alcotest.(check char) "null terminator" '\x00' (String.get decoded.name 31); 69 74 Alcotest.(check int) "src" 42 decoded.src; ··· 92 97 let test_decode_known_vector () = 93 98 (* Kernel self-test default: rpmsg-client-sample with RPMSG_ADDR_ANY *) 94 99 let raw = raw_info "rpmsg-client-sample" rpmsg_addr_any rpmsg_addr_any in 95 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec raw 0 in 100 + let decoded = decode_exn Rpmsg.endpoint_info_codec raw 0 in 96 101 Alcotest.(check bool) 97 102 "name" true 98 103 (String.sub decoded.name 0 19 = "rpmsg-client-sample"); ··· 119 124 (* OpenAMP demo channel: name="rpmsg-openamp-demo-channel", src=1024, dst=1025 120 125 Common on Zynq UltraScale+ and STM32MP1 targets. *) 121 126 let raw = raw_info "rpmsg-openamp-demo-channel" 1024 1025 in 122 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec raw 0 in 127 + let decoded = decode_exn Rpmsg.endpoint_info_codec raw 0 in 123 128 Alcotest.(check bool) 124 129 "name" true 125 130 (String.sub decoded.name 0 26 = "rpmsg-openamp-demo-channel"); ··· 146 151 in 147 152 let buf = Bytes.create 40 in 148 153 Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0; 149 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in 154 + let decoded = decode_exn Rpmsg.endpoint_info_codec buf 0 in 150 155 Alcotest.(check int) "src ADDR_ANY" rpmsg_addr_any decoded.src; 151 156 Alcotest.(check int) "dst ADDR_ANY" rpmsg_addr_any decoded.dst 152 157 ··· 154 159 let info = Rpmsg.{ name = "test"; src = 0; dst = 0 } in 155 160 let buf = Bytes.create 40 in 156 161 Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0; 157 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in 162 + let decoded = decode_exn Rpmsg.endpoint_info_codec buf 0 in 158 163 Alcotest.(check int) "src 0" 0 decoded.src; 159 164 Alcotest.(check int) "dst 0" 0 decoded.dst 160 165 ··· 168 173 for i = 0 to 31 do 169 174 Alcotest.(check char) (Fmt.str "name[%d]" i) '\x00' (Bytes.get buf i) 170 175 done; 171 - let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in 176 + let decoded = decode_exn Rpmsg.endpoint_info_codec buf 0 in 172 177 Alcotest.(check int) "src" 1 decoded.src; 173 178 Alcotest.(check int) "dst" 2 decoded.dst 174 179