123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- MODULE BlTools;
- (**
- AUTHOR Timothée Martiel, 01/2016
- PURPOSE Command interface to Bootloader
- *)
- IMPORT
- Commands, Files, Streams, Strings,
- CryptoHashes, CryptoUtils,
- TFTPServer,
- BlCommands;
- CONST
- ArgError * = 1;
- ExecError * = 2;
- TYPE
- Resource = POINTER TO RECORD
- file, resource: ARRAY 256 OF CHAR;
- next: Resource
- END;
- VAR
- session: BlCommands.Session;
- resources: Resource;
- (** StartSession (ip address | 'UART') *)
- PROCEDURE StartSession * (context: Commands.Context);
- VAR
- udp: BlCommands.UdpSession;
- uart: BlCommands.UartSession;
- arg: ARRAY 32 OF CHAR;
- uartPort: LONGINT;
- BEGIN
- IF context.arg.GetString(arg) THEN
- IF arg = 'UART' THEN
- IF ~context.arg.GetInteger(uartPort, FALSE) THEN
- context.error.String("Error: expected COM port number");
- context.error.Ln;
- context.result := 1;
- RETURN
- END;
- NEW(uart, uartPort);
- session := uart;
- context.out.String("Session established");
- context.out.Ln
- ELSE
- TFTPServer.Stop;
- NEW(udp, arg);
- IF udp # NIL THEN
- TRACE(udp);
- session := udp;
- resources := NIL;
- context.out.String("Session established");
- context.out.Ln
- ELSE
- context.error.String("Error: invalid IP address");
- context.error.Ln;
- context.result := ArgError
- END
- END
- ELSE
- context.error.String("Error: expected IP address or 'UART'");
- context.error.Ln;
- context.result := ArgError
- END
- END StartSession;
- PROCEDURE StopSession * (context : Commands.Context);
- BEGIN
- session.Close;
- context.out.String("Session stopped");
- context.out.Ln
- END StopSession;
- (** Load filename resourcename ~ *)
- PROCEDURE Load * (context : Commands.Context);
- VAR
- file, resource: ARRAY 256 OF CHAR;
- r: Resource;
- BEGIN
- IF session = NIL THEN
- context.error.String("Error: no session started yet. Please call BlTools.SelectBoard first");
- context.error.Ln;
- RETURN
- END;
- IF context.arg.GetString(file) THEN
- IF context.arg.GetString(resource) THEN
- IF session.Load(file, resource) THEN
- context.out.String(resource);
- NEW(r);
- COPY(file, r.file);
- COPY(resource, r.resource);
- r.next := resources;
- resources := r;
- context.out.String(" loaded");
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- ELSE
- context.error.String("Error: expected resource name");
- context.error.Ln;
- context.result := ArgError
- END
- ELSE
- context.error.String("Error: expected file name");
- context.error.Ln;
- context.result := ArgError
- END
- END Load;
- (** Program resource destination [options] ~ *)
- PROCEDURE Program * (context : Commands.Context);
- VAR
- resource, dest: ARRAY 256 OF CHAR;
- mem: BlCommands.MemoryDest;
- zfpga: BlCommands.ZynqFpgaDest;
- file: BlCommands.FileDest;
- i: LONGINT;
- BEGIN
- IF context.arg.GetString(resource) THEN
- IF context.arg.GetString(dest) THEN
- IF dest = "ZynqFpga" THEN
- IF session.Program(resource, zfpga) THEN
- context.out.String("Programming FPGA done");
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- ELSIF dest = "memory" THEN
- IF context.arg.GetInteger(mem.address, TRUE) THEN
- WHILE context.arg.GetInteger(i, TRUE) DO INCL(mem.cpus, i) END;
- IF session.Program(resource, mem) THEN
- context.out.String("Programming ARM done");
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- ELSE
- context.error.String("Error: expected load address");
- context.error.Ln;
- context.result := ArgError
- END
- ELSIF dest = "file" THEN
- IF context.arg.GetString(file.name) THEN
- IF session.Program(resource, file) THEN
- context.out.String("Programming file done");
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- ELSE
- context.error.String("Error: expected file name");
- context.error.Ln;
- context.result := ArgError
- END
- ELSE
- context.error.String("Error: unknown destination '");
- context.error.String(dest);
- context.error.String("'.");
- context.error.Ln;
- context.result := ArgError
- END
- ELSE
- context.error.String("Error: expected destination");
- context.error.Ln;
- context.result := ArgError
- END
- ELSE
- context.error.String("Error: expected resource name");
- context.error.Ln;
- context.result := ArgError
- END
- END Program;
- (** Check resource algorithm *)
- PROCEDURE Check * (context : Commands.Context);
- VAR
- buffer: ARRAY 1024 OF CHAR;
- reference, resource: ARRAY 256 OF CHAR;
- algorithm, hashName: ARRAY 32 OF CHAR;
- hash: CryptoHashes.Hash;
- file: Files.File;
- reader: Files.Reader;
- r: Resource;
- len: LONGINT;
- BEGIN
- IF context.arg.GetString(resource) THEN
- IF context.arg.GetString(algorithm) THEN
- (* Get hash object *)
- hashName := "Crypto";
- Strings.Append(hashName, algorithm);
- hash := CryptoHashes.NewHash(hashName);
- IF hash = NIL THEN
- context.error.String("Error: unknown hash algorithm: ");
- context.error.String(algorithm);
- context.error.String(' (module ');
- context.error.String(hashName);
- context.error.String(' not found)');
- context.error.Ln;
- context.result := ArgError;
- RETURN
- END;
- (* Get & read file *)
- r := resources;
- WHILE (r # NIL) & (r.resource # resource) DO r := r.next END;
- IF r = NIL THEN
- context.error.String("Error: could not find the resource: ");
- context.error.String(resource);
- context.error.Ln;
- context.result := ArgError;
- RETURN
- END;
- file := Files.Old(r.file);
- IF file = NIL THEN
- context.error.String("Error: could not open file ");
- context.error.String(r.file);
- context.error.Ln;
- context.result := ArgError;
- RETURN
- END;
- Files.OpenReader(reader, file, 0);
- IF reader = NIL THEN
- context.error.String("Error: could not read file ");
- context.error.String(r.file);
- context.error.Ln;
- context.result := ArgError;
- RETURN
- END;
- hash.Initialize;
- WHILE reader.res = Streams.Ok DO
- reader.Bytes(buffer, 0, LEN(buffer), len);
- hash.Update(buffer, 0, len)
- END;
- hash.GetHash(buffer, 0);
- CryptoUtils.Bin2Hex(buffer, 0, reference, 0, hash.size);
- (* Send command *)
- IF session.Check(resource, algorithm, reference) THEN
- context.out.String("Hash check succeeded");
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- ELSE
- context.error.String("Error: expected algorithm name");
- context.error.Ln;
- context.result := ArgError
- END
- ELSE
- context.error.String("Error: expected resource name");
- context.error.Ln;
- context.result := ArgError
- END
- END Check;
- PROCEDURE Save * (context: Commands.Context);
- VAR
- resource: ARRAY 256 OF CHAR;
- BEGIN
- IF ~context.arg.GetString(resource) THEN
- context.error.String("Error: expected resource name");
- context.error.Ln;
- context.result := ArgError;
- RETURN
- END;
- IF session.Save(resource) THEN
- context.out.String("Resource saved");
- context.out.Ln;
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END;
- END Save;
- PROCEDURE Start * (context : Commands.Context);
- BEGIN
- IF session.Start() THEN
- context.out.String("Application started");
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- END Start;
- PROCEDURE Mount * (context: Commands.Context);
- VAR
- prefix, disk: ARRAY 128 OF CHAR;
- partition: LONGINT;
- BEGIN
- IF ~context.arg.GetString(prefix) THEN
- context.error.String("Error: expected prefix");
- context.error.Ln;
- context.result := ExecError;
- RETURN
- END;
- IF ~context.arg.GetString(disk) THEN
- context.error.String("Error: expected disk name");
- context.error.Ln;
- context.result := ExecError;
- RETURN
- END;
- IF ~context.arg.GetInteger(partition, FALSE) THEN
- context.error.String("Error: expected partition id");
- context.error.Ln;
- context.result := ExecError;
- RETURN
- END;
- IF session.Mount(prefix, disk, partition) THEN
- context.out.String(disk);
- context.out.Char('#');
- context.out.Int(partition, 0);
- context.out.String(" mounted as ");
- context.out.String(prefix);
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- END Mount;
- (** SetSource protocol [options] ~ *)
- PROCEDURE SetSource * (context : Commands.Context);
- VAR
- protocol: ARRAY 32 OF CHAR;
- tftp: BlCommands.TftpSource;
- BEGIN
- IF session = NIL THEN
- context.error.String("Error: no session started yet. Please call BlTools.SelectBoard first");
- context.error.Ln;
- RETURN
- END;
- IF context.arg.GetString(protocol) THEN
- IF protocol = "TFTP" THEN
- IF context.arg.GetString(tftp.host) THEN
- IF session.SetSource(tftp) THEN
- TFTPServer.Start;
- context.out.String("Data source set");
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- ELSE
- context.error.String("Error: expected hostname");
- context.error.Ln;
- context.result := ArgError
- END
- ELSE
- context.error.String("Error: unknown protocol '");
- context.error.String(protocol);
- context.error.String("'.");
- context.error.Ln;
- context.result := ArgError
- END
- ELSE
- context.error.String("Error: expected protocol name");
- context.error.Ln;
- context.result := ArgError
- END
- END SetSource;
- (* SetInput (UDP|UART|file) ~ *)
- PROCEDURE SetInput*(context : Commands.Context);
- VAR
- input: ARRAY 256 OF CHAR;
- BEGIN
- IF context.arg.GetString(input) THEN
- IF session.SetInput(input) THEN
- context.out.String("Change input done");
- context.out.Ln
- ELSE
- context.out.String(session.ack);
- context.out.Ln;
- context.result := ExecError
- END
- ELSE
- context.out.String("Error: expected input");
- context.out.Ln;
- context.result := ArgError
- END
- END SetInput;
- PROCEDURE Timeout*(context: Commands.Context);
- VAR
- time: LONGINT;
- BEGIN
- IF context.arg.GetInteger(time, FALSE) THEN
- IF session.SetTimeout(time) THEN
- context.out.String("Timeout set");
- context.out.Ln
- ELSE
- context.out.String(session.ack);
- context.out.Ln;
- context.result := ExecError
- END
- ELSE
- context.out.String("Error: Expected timeout value");
- context.out.Ln
- END
- END Timeout;
- PROCEDURE Reset * (context: Commands.Context);
- BEGIN
- IF session.Reset() THEN
- context.out.String("Bootloader reset");
- context.out.Ln
- ELSE
- context.error.String(session.ack);
- context.error.Ln;
- context.result := ExecError
- END
- END Reset;
- PROCEDURE Command * (context: Commands.Context);
- VAR
- cmd: ARRAY 1024 OF CHAR;
- len: LONGINT;
- BEGIN
- context.arg.Bytes(cmd, 0, context.arg.Available(), len);
- IF session.ExecuteCommand(cmd) THEN
- context.out.String("Command ");
- context.out.String(cmd);
- context.out.String(" successful");
- context.out.Ln
- ELSE
- context.out.String(session.ack);
- context.out.Ln;
- context.result := ExecError
- END
- END Command;
- PROCEDURE Deploy * (context : Commands.Context);
- BEGIN
-
- END Deploy;
- END BlTools.
- TFTPServer.Start
- SystemTools.DoCommands
- BlTools.StartSession 10.3.34.8 ~
- BlTools.SetSource TFTP 10.3.34.145 ~
- BlTools.Load TestFifo.bin bs ~
- BlTools.Check bs MD5 ~
- BlTools.Program bs ZynqFpga ~
- BlTools.Load A2.Bin a2 ~
- BlTools.Check a2 MD5 ~
- BlTools.Program a2 memory 100000H 0 1 ~
- BlTools.Program a3 ZynqFpga ~
- BlTools.Start ~
- BlTools.StopSession ~
- ~
- SystemTools.DoCommands
- BlTools.StartSession 10.3.34.8 ~
- BlTools.SetSource TFTP 10.3.34.145 ~
- BlTools.Load A2.Bin a2 ~
- BlTools.Check a2 MD5 ~
- BlTools.Program a2 memory 100000H 0 1 ~
- BlTools.Start ~
- BlTools.StopSession ~
- ~
- BlTools.SetInput UART ~
- SystemTools.DoCommands
- BlTools.StartSession 10.3.34.8 ~
- BlTools.SetSource TFTP 10.3.34.145 ~
- BlTools.Timeout 1 ~
- BlTools.StopSession ~
- ~
|