BlCommands.Mod 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. MODULE BlCommands;
  2. (**
  3. AUTHOR Timothée Martiel, 01/2016
  4. PURPOSE Library to control the bootloader.
  5. *)
  6. IMPORT
  7. Kernel, Strings, Streams,
  8. Serials,
  9. IP, UDP;
  10. CONST
  11. CR = 0DX;
  12. LF = 0AX;
  13. CommandPort = 59999;
  14. CommandTimeout = 100000;
  15. TYPE
  16. Command = ARRAY 1024 OF CHAR;
  17. (** Resource source description base record *)
  18. Source * = RECORD
  19. END;
  20. (** Source description record for TFTP protocol *)
  21. TftpSource * = RECORD (Source)
  22. host *: ARRAY 32 OF CHAR;
  23. END;
  24. Destination * = RECORD
  25. END;
  26. ZynqFpgaDest * = RECORD (Destination)
  27. END;
  28. MemoryDest * = RECORD (Destination)
  29. address *: LONGINT;
  30. cpus *: SET;
  31. END;
  32. FileDest * = RECORD (Destination)
  33. name *: ARRAY 128 OF CHAR;
  34. END;
  35. (** Bootloader load session *)
  36. Session * = OBJECT
  37. VAR
  38. ack -: ARRAY 128 OF CHAR;
  39. next *: Session;
  40. (** ABSTRACT generic command execution method *)
  41. PROCEDURE ExecuteCommand * (CONST cmd: ARRAY OF CHAR): BOOLEAN;
  42. VAR
  43. ref: Command;
  44. BEGIN
  45. ack := '';
  46. ref := 'OK: ';
  47. Strings.Append(ref, cmd);
  48. IF ~SendCommand(cmd, ack) THEN
  49. RETURN FALSE
  50. ELSIF ack # ref THEN
  51. RETURN FALSE
  52. ELSE
  53. RETURN TRUE
  54. END
  55. END ExecuteCommand;
  56. PROCEDURE SendCommand (CONST cmd: ARRAY OF CHAR; VAR resp: ARRAY OF CHAR): BOOLEAN;
  57. BEGIN
  58. HALT(133)
  59. END SendCommand;
  60. PROCEDURE Load * (CONST filename, resourceName: ARRAY OF CHAR): BOOLEAN;
  61. VAR
  62. cmd: Command;
  63. BEGIN
  64. cmd := "load ";
  65. Strings.Append(cmd, filename);
  66. Strings.Append(cmd, " ");
  67. Strings.Append(cmd, resourceName);
  68. Strings.AppendChar(cmd, CR);
  69. Strings.AppendChar(cmd, LF);
  70. RETURN ExecuteCommand(cmd)
  71. END Load;
  72. PROCEDURE Program * (CONST resourceName: ARRAY OF CHAR; CONST destination: Destination): BOOLEAN;
  73. VAR
  74. cmd: Command;
  75. cpu: LONGINT;
  76. BEGIN
  77. cmd := "program ";
  78. Strings.Append(cmd, resourceName);
  79. IF destination IS ZynqFpgaDest THEN
  80. Strings.Append(cmd, " ZynqFpga")
  81. ELSIF destination IS MemoryDest THEN
  82. WITH destination: MemoryDest DO
  83. Strings.Append(cmd, " memory ");
  84. Strings.AppendInt(cmd, destination.address);
  85. FOR cpu := 0 TO 31 DO
  86. IF cpu IN destination.cpus THEN
  87. Strings.Append(cmd, " ");
  88. Strings.AppendInt(cmd, cpu)
  89. END
  90. END
  91. END
  92. ELSIF destination IS FileDest THEN
  93. WITH destination: FileDest DO
  94. Strings.Append(cmd, " file ");
  95. Strings.Append(cmd, destination.name)
  96. END
  97. ELSE
  98. RETURN FALSE
  99. END;
  100. Strings.AppendChar(cmd, CR);
  101. Strings.AppendChar(cmd, LF);
  102. RETURN ExecuteCommand(cmd)
  103. END Program;
  104. PROCEDURE Check * (CONST resourceName, algorithm, reference: ARRAY OF CHAR): BOOLEAN;
  105. VAR
  106. cmd: Command;
  107. BEGIN
  108. cmd := "check ";
  109. Strings.Append(cmd, resourceName);
  110. Strings.Append(cmd, " ");
  111. Strings.Append(cmd, algorithm);
  112. Strings.Append(cmd, " ");
  113. Strings.Append(cmd, reference);
  114. Strings.AppendChar(cmd, CR);
  115. Strings.AppendChar(cmd, LF);
  116. RETURN ExecuteCommand(cmd)
  117. END Check;
  118. PROCEDURE Save * (CONST resourceName: ARRAY OF CHAR): BOOLEAN;
  119. VAR
  120. cmd: Command;
  121. BEGIN
  122. cmd := "save ";
  123. Strings.Append(cmd, resourceName);
  124. Strings.AppendChar(cmd, CR);
  125. Strings.AppendChar(cmd, LF);
  126. RETURN ExecuteCommand(cmd)
  127. END Save;
  128. PROCEDURE Start * (): BOOLEAN;
  129. VAR
  130. cmd: Command;
  131. BEGIN
  132. cmd := "start";
  133. Strings.AppendChar(cmd, CR);
  134. Strings.AppendChar(cmd, LF);
  135. RETURN ExecuteCommand(cmd)
  136. END Start;
  137. PROCEDURE Mount * (CONST prefix, disk: ARRAY OF CHAR; partition: LONGINT): BOOLEAN;
  138. VAR
  139. cmd: Command;
  140. BEGIN
  141. cmd := "mount ";
  142. Strings.Append(cmd, prefix);
  143. Strings.AppendChar(cmd, ' ');
  144. Strings.Append(cmd, disk);
  145. Strings.AppendChar(cmd, ' ');
  146. Strings.AppendInt(cmd, partition);
  147. Strings.AppendChar(cmd, CR);
  148. Strings.AppendChar(cmd, LF);
  149. RETURN ExecuteCommand(cmd)
  150. END Mount;
  151. PROCEDURE SetSource * (CONST source: Source): BOOLEAN;
  152. VAR
  153. cmd: Command;
  154. BEGIN
  155. IF source IS TftpSource THEN
  156. cmd := "setsource TFTP ";
  157. Strings.Append(cmd, source(TftpSource).host)
  158. END;
  159. Strings.AppendChar(cmd, CR);
  160. Strings.AppendChar(cmd, LF);
  161. RETURN ExecuteCommand(cmd)
  162. END SetSource;
  163. PROCEDURE SetTimeout * (value: LONGINT): BOOLEAN;
  164. VAR
  165. cmd: Command;
  166. val: ARRAY 32 OF CHAR;
  167. BEGIN
  168. cmd := "timeout ";
  169. Strings.IntToStr(value, val);
  170. Strings.Append(cmd, val);
  171. Strings.AppendChar(cmd, CR);
  172. Strings.AppendChar(cmd, LF);
  173. RETURN ExecuteCommand(cmd)
  174. END SetTimeout;
  175. PROCEDURE SetInput * (CONST input: ARRAY OF CHAR): BOOLEAN;
  176. VAR
  177. cmd: Command;
  178. BEGIN
  179. cmd := "setinput ";
  180. Strings.Append(cmd, input);
  181. Strings.AppendChar(cmd, CR);
  182. Strings.AppendChar(cmd, LF);
  183. RETURN ExecuteCommand(cmd)
  184. END SetInput;
  185. PROCEDURE Reset * (): BOOLEAN;
  186. VAR
  187. cmd: Command;
  188. BEGIN
  189. cmd := "reset";
  190. Strings.AppendChar(cmd, CR);
  191. Strings.AppendChar(cmd, LF);
  192. RETURN ExecuteCommand(cmd)
  193. END Reset;
  194. PROCEDURE Close *;
  195. BEGIN
  196. END Close;
  197. END Session;
  198. UdpSession * = OBJECT (Session)
  199. VAR
  200. target: IP.Adr;
  201. socket: UDP.Socket;
  202. port: LONGINT;
  203. PROCEDURE & InitUdpSession * (CONST board: ARRAY OF CHAR);
  204. VAR
  205. res: LONGINT;
  206. BEGIN
  207. port := CommandPort;
  208. target := IP.StrToAdr(board);
  209. NEW(socket, CommandPort, res);
  210. END InitUdpSession;
  211. PROCEDURE SendCommand (CONST cmd: ARRAY OF CHAR; VAR resp: ARRAY OF CHAR): BOOLEAN;
  212. VAR
  213. hostAdr: IP.Adr;
  214. len, hostPort, res: LONGINT;
  215. BEGIN
  216. socket.Send(target, port, cmd, 0, Strings.Length(cmd), res);
  217. socket.Receive(resp, 0, LEN(ack), CommandTimeout, hostAdr, hostPort, len, res);
  218. resp[len] := 0X;
  219. IF res # UDP.Ok THEN
  220. RETURN FALSE
  221. ELSIF ~IP.AdrsEqual(hostAdr, target) THEN
  222. RETURN FALSE
  223. END;
  224. RETURN TRUE
  225. END SendCommand;
  226. PROCEDURE Close *;
  227. BEGIN
  228. socket.Close
  229. END Close;
  230. END UdpSession;
  231. UartSession * = OBJECT (Session)
  232. VAR
  233. writer: Streams.Writer;
  234. reader: Streams.Reader;
  235. PROCEDURE & InitUartSession * (port: LONGINT);
  236. VAR
  237. p: Serials.Port;
  238. BEGIN
  239. p := Serials.GetPort(port);
  240. Streams.OpenReader(reader, p.Receive);
  241. Streams.OpenWriter(writer, p.Send)
  242. END InitUartSession;
  243. PROCEDURE SendCommand (CONST cmd: ARRAY OF CHAR; VAR resp: ARRAY OF CHAR): BOOLEAN;
  244. VAR
  245. timer: Kernel.MilliTimer;
  246. done: BOOLEAN;
  247. BEGIN
  248. writer.String(cmd);
  249. writer.Update;
  250. Kernel.SetTimer(timer, CommandTimeout);
  251. REPEAT
  252. done := reader.GetString(resp);
  253. UNTIL Kernel.Expired(timer) OR done;
  254. RETURN done
  255. END SendCommand;
  256. END UartSession;
  257. END BlCommands.