From: Jérémie D. <Ba...@us...> - 2010-03-28 08:50:43
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "krobot". The branch, master has been updated via 893ed223d609b74ea814468ded4ad5f5d54a29f0 (commit) via eab764ff233b9042af662a60298f855413947201 (commit) via bd4bbf755162f216cc9afab5787917521efca6ac (commit) via 620f4f865763156cdfc80c090c43596a6ffcc991 (commit) from 55d744ede328cc22f5e3cd1f4904183472907936 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 893ed223d609b74ea814468ded4ad5f5d54a29f0 Author: Jérémie Dimino <je...@di...> Date: Sun Mar 28 10:37:48 2010 +0200 krobot-forward-dbus: do not fail on end-of-file commit eab764ff233b9042af662a60298f855413947201 Author: Jérémie Dimino <je...@di...> Date: Sun Mar 28 10:37:13 2010 +0200 rename some modules commit bd4bbf755162f216cc9afab5787917521efca6ac Author: Jérémie Dimino <je...@di...> Date: Sat Mar 27 23:53:38 2010 +0100 adapt position for the new grip commit 620f4f865763156cdfc80c090c43596a6ffcc991 Author: Kro[bot] <krobot@wally.(none)> Date: Sat Mar 27 22:28:51 2010 +0000 Be less aggressive with the compass ----------------------------------------------------------------------- Changes: diff --git a/PC_Mainboard/Makefile b/PC_Mainboard/Makefile index 079e436..9435bbb 100644 --- a/PC_Mainboard/Makefile +++ b/PC_Mainboard/Makefile @@ -32,13 +32,13 @@ install: $(wildcard _build/*.cmxa) \ $(wildcard _build/*.cmxs) \ $(wildcard _build/*.a) - install -m 0755 _build/card_tools/send_firmware.best $(PREFIX)/bin/krobot-send-firmware - install -m 0755 _build/card_tools/dump_memory.best $(PREFIX)/bin/krobot-dump-memory - install -m 0755 _build/tools/forward_dbus.best $(PREFIX)/bin/krobot-forward-dbus + install -m 0755 _build/card_tools/krobot_send_firmware.best $(PREFIX)/bin/krobot-send-firmware + install -m 0755 _build/card_tools/krobot_dump_memory.best $(PREFIX)/bin/krobot-dump-memory + install -m 0755 _build/tools/krobot_forward_dbus.best $(PREFIX)/bin/krobot-forward-dbus install -m 0755 _build/clients/krobot_info.best $(PREFIX)/bin/krobot-info install -m 0755 _build/clients/krobot_joy_control.best $(PREFIX)/bin/krobot-joystick install -m 0755 _build/clients/krobot_controller.best $(PREFIX)/bin/krobot-controller - install -m 0755 _build/services/hard_stop.best $(PREFIX)/bin/krobot-hard-stop + install -m 0755 _build/services/krobot_hard_stop.best $(PREFIX)/bin/krobot-hard-stop install -m 0755 _build/driver/krobot_driver.best $(PREFIX)/bin/krobot-driver .PHONY: uninstall diff --git a/PC_Mainboard/_tags b/PC_Mainboard/_tags index 6eaf178..4f33d64 100644 --- a/PC_Mainboard/_tags +++ b/PC_Mainboard/_tags @@ -52,8 +52,8 @@ # | Tools | # +------------------------------------------------------------------+ -<tools/forward_dbus.ml>: syntax_camlp4o, pkg_lwt.syntax, pkg_lwt.syntax.log, pkg_obus.syntax -<tools/forward_dbus.*>: pkg_obus +<tools/krobot_forward_dbus.ml>: syntax_camlp4o, pkg_lwt.syntax, pkg_lwt.syntax.log, pkg_obus.syntax +<tools/krobot_forward_dbus.*>: pkg_obus # +------------------------------------------------------------------+ # | Tests | diff --git a/PC_Mainboard/card_tools/boardname.mli b/PC_Mainboard/card_tools/boardname.mli deleted file mode 100644 index 23b0032..0000000 --- a/PC_Mainboard/card_tools/boardname.mli +++ /dev/null @@ -1,12 +0,0 @@ -(* - * boardname.mli - * ------------- - * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> - * Licence : BSD3 - * - * This file is a part of Krobot. - *) - -val get_board_name : string -> string option - (** [get_board_name dump] recherche dans le [dump] mémoire (peut - être également un fichier .hex chargé) le nom de la carte. *) diff --git a/PC_Mainboard/card_tools/boardname.mll b/PC_Mainboard/card_tools/boardname.mll deleted file mode 100644 index 08df665..0000000 --- a/PC_Mainboard/card_tools/boardname.mll +++ /dev/null @@ -1,22 +0,0 @@ -(* - * boardname.mll - * ------------- - * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> - * Licence : BSD3 - * - * This file is a part of Krobot. - *) - - -let boardname_regex = ("Carte " | "Robot Interface" | "Battery Monitoring ") [^'\n']+ - -rule boardname = parse - | (boardname_regex as name) '\n' { Some name } - | _ { boardname lexbuf } - | eof { None } - -{ - let get_board_name str = - let lexbuf = Lexing.from_string str in - boardname lexbuf -} diff --git a/PC_Mainboard/card_tools/bootloader.ml b/PC_Mainboard/card_tools/bootloader.ml deleted file mode 100644 index 35b407e..0000000 --- a/PC_Mainboard/card_tools/bootloader.ml +++ /dev/null @@ -1,184 +0,0 @@ -(* - * bootloader.ml - * ------------- - * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> - * Licence : BSD3 - * - * This file is a part of Krobot. - *) - -open Lwt -open Lwt_io - -(* Code très inspiré de kard.ml, mais mis à part car le mode de - communication avec la carte est différent (bulk au lieu - d'interrupt). *) - -type t = { - mutable is_open : bool; - (* La carte est-elle ouverte ? *) - - handle : USB.handle; - (* Handle pour le périphérique usb *) - - kernel_active : bool; - (* Est-ce qu'un driver noyau était attaché à la carte avant qu'on - l'utilise ? *) -} - -type error = - | IncompleteWrite of int * int - | IncompleteRead of int * int - | UnexpectedReply of string * string - | WriteError of string * string - -let string_of_error = function - | IncompleteWrite (a, b) -> Printf.sprintf "%d byte(s) written instead of %d" a b - | IncompleteRead (a, b) -> Printf.sprintf "%d byte(s) read instead of %d" a b - | UnexpectedReply (a, b) -> Printf.sprintf "received unexpected reply %S instead of %S" a b - | WriteError (a, b) -> Printf.sprintf "written: %S, read back: %S" a b - -exception Error of error - -let failwith e = fail (Error e) - -let close k = - if k.is_open then begin - lwt _ = USB.release_interface k.handle 0 in - lwt _ = USB.reset_device k.handle in - (*if k.kernel_active then USB.attach_kernel_driver k.handle 0;*) - (*USB.close k.handle;*) - k.is_open <- false; - return () - end else return () - -let open_card () = - let handle = USB.open_device_with - ~vendor_id:PcInterface.usb_vid - ~product_id:PcInterface.usb_pid_bootloader - in - let kernel_active = USB.kernel_driver_active handle 0 in - if kernel_active then USB.detach_kernel_driver handle 0; - lwt _ = USB.set_configuration handle 1 in - lwt _ = USB.claim_interface handle 0 in - let k = { is_open = true; - handle = handle; - kernel_active = kernel_active } in - let _ = Lwt_sequence.add_l (fun _ -> close k) Lwt_main.exit_hooks in - return k - -let header_length = 5 - -let put_message buffer cmd length address data = - let body_length = String.length data in - assert (String.length buffer >= header_length+body_length); - let set i n = buffer.[i] <- char_of_int n in - set 0 cmd; - assert (length < 0x100); - set 1 length; - assert (address <= 0x1000000); - set 2 (address land 0xff); - set 3 ((address lsr 8) land 0xff); - set 4 ((address lsr 16) land 0xff); - String.blit data 0 buffer 5 body_length - -let send_receive_packet k send_buffer send_length receive_buffer receive_length send_delay receive_delay = - let handle = k.handle and endpoint = 1 in - lwt sent = USB.bulk_send ~handle ~endpoint ~timeout:1. send_buffer 0 send_length in - if sent <> send_length then - failwith (IncompleteWrite (sent, send_length)) - else begin - lwt received = USB.bulk_recv ~handle ~endpoint ~timeout:3. receive_buffer 0 receive_length in - if received <> receive_length then - failwith (IncompleteRead (received, receive_length)) - else - return () - end - -let get_flash k ~address ~length = - let response_length = 64 in - let increment = response_length-header_length in - assert (increment < 256); - let send_buffer = String.create header_length in - let receive_buffer = String.create response_length in - let result_buffer = String.create length in - let rec loop offset total_length = - if total_length <= 0 then - return result_buffer - else begin - let length = min increment total_length in - let response_length = length+header_length in - let address = address+offset in - put_message send_buffer PcInterface.read_flash length address ""; - lwt () = send_receive_packet k send_buffer header_length receive_buffer response_length 1. 3. in - let receive_header = String.sub receive_buffer 0 header_length in - if receive_header <> send_buffer then - failwith (UnexpectedReply (receive_header, send_buffer)) - else begin - String.blit receive_buffer header_length result_buffer offset length; - loop (offset+length) (total_length-length); - end - end - in loop 0 length - -let erase_flash k ~address ~length = - let response_length = 1 in - (* les effacements se font par blocs de 64 octets *) - let increment = 64 in - let send_buffer = String.create header_length in - let receive_buffer = String.create response_length in - let rec loop offset total_length = - if total_length <= 0 then - return () - else begin - let address = address+offset in - put_message send_buffer PcInterface.erase_flash 1 address ""; - lwt () = send_receive_packet k send_buffer header_length receive_buffer response_length 1. 5. in - if int_of_char receive_buffer.[0] <> PcInterface.erase_flash then - failwith (UnexpectedReply (receive_buffer, String.make 1 (char_of_int PcInterface.erase_flash))) - else - loop (offset+increment) (total_length-increment); - end - in loop 0 length - -let reference = String.make 16 '\255' - -let write_flash k ~address data offset length = - let send_length = 64 and receive_length = 1 in - (* les écritures se font par blocs de 16 octets *) - let increment = 16 in - let send_buffer = String.create send_length in - let receive_buffer = String.create receive_length in - let rec loop address offset total_length = - (* address: sur le PIC, offset: dans data, total_length: taille restante *) - if total_length <= 0 then - return () - else begin - let packet = String.make increment '\255' in - String.blit data offset packet 0 (min total_length increment); - if packet = reference then begin - (* le paquet n'a pas de contenu, on l'ignore *) - (* lwt () = printf "Skipping address 0x%06X...\n" address in *) - loop (address+increment) (offset+increment) (total_length-increment) - end else begin - (* lwt () = printf "Processing address 0x%06X...\n" address in *) - put_message send_buffer PcInterface.write_flash increment address packet; - lwt () = send_receive_packet k send_buffer send_length receive_buffer receive_length 0.5 1. in - if int_of_char receive_buffer.[0] <> PcInterface.write_flash then - failwith (UnexpectedReply (receive_buffer, String.make 1 (char_of_int PcInterface.erase_flash))) - else begin - lwt written = get_flash k ~address ~length:increment in - if written <> packet then - failwith (WriteError (packet, written)) - else - loop (address+increment) (offset+increment) (total_length-increment) - end - end - end - in loop address offset length - -let reset_board k = - let send_buffer = String.create 64 and receive_buffer = String.create 64 in - send_buffer.[0] <- char_of_int PcInterface.reset; - lwt () = send_receive_packet k send_buffer 1 receive_buffer 64 5. 5. in - return () diff --git a/PC_Mainboard/card_tools/dump_memory.ml b/PC_Mainboard/card_tools/dump_memory.ml deleted file mode 100644 index 5c746e0..0000000 --- a/PC_Mainboard/card_tools/dump_memory.ml +++ /dev/null @@ -1,30 +0,0 @@ -(* - * dump_memory.ml - * -------------- - * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> - * Licence : BSD3 - * - * This file is a part of Krobot. - *) - -open Printf -open Lwt -open Lwt_io - -let main = - lwt k = Bootloader.open_card () in - try_lwt - lwt data = Bootloader.get_flash k ~address:0x0 ~length:0x8000 in - let msg = match Boardname.get_board_name data with - | Some s -> sprintf "Board: %S" s - | None -> "Unable to identify board!" - in - lwt () = eprintlf "%s" msg in - (if Unix.isatty Unix.stdout then hexdump else write) stdout data >> flush stdout - with - | Bootloader.Error e -> - eprintlf "%s" (Bootloader.string_of_error e) - | e -> - eprintlf "%s" (Printexc.to_string e) - -let _ = Lwt_main.run main diff --git a/PC_Mainboard/card_tools/hexfile.ml b/PC_Mainboard/card_tools/hexfile.ml deleted file mode 100644 index a667957..0000000 --- a/PC_Mainboard/card_tools/hexfile.ml +++ /dev/null @@ -1,112 +0,0 @@ -(* - * hexfile.ml - * ---------- - * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> - * Licence : BSD3 - * - * This file is a part of Krobot. - *) - -open Lwt -open Lwt_io - -type hex_record = - | Data of int * string - | ExtendedLinearAddress of int - | EndOfFile of int - -let string_of_hexline str = - let n = String.length str in - assert (n > 0 && n mod 2 = 1 && str.[0] = ':'); - let m = n/2 in - let result = String.create m in - for i = 0 to m-1 do - let j = 2*i+1 in - result.[i] <- char_of_int (int_of_string ("0x"^(String.sub str j 2))) - done; - result - -let compute_checksum str = - let rec aux i accu = - if i < 0 then - (-accu) land 0xff - else - aux (i-1) (accu+(int_of_char str.[i])) - in aux (String.length str - 2) 0 - -let parse_line str = - let str = string_of_hexline str in - let get i = int_of_char str.[i] in - let n = String.length str in - assert (n >= 5 && compute_checksum str = int_of_char str.[n-1]); - let count = get 0 in - assert (count+5 = n); - let address = ((get 1) lsl 8) lor (get 2) in - let record_type = get 3 in - let data = String.sub str 4 count in - match record_type with - | 0x00 -> - Data (address, data) - | 0x01 -> - assert (count = 0); - EndOfFile address - | 0x04 -> - assert (count = 2 && address = 0); - let msb = int_of_char data.[0] and lsb = int_of_char data.[1] in - (* check for possible overflow *) - assert (msb land 0x80 = 0); - ExtendedLinearAddress ((msb lsl 8) lor lsb) - | _ -> assert false - -let parse_file file = - let ic = Lwt_io.open_file ~mode:input file in - let lines = Lwt_io.read_lines ic in - let lines = Lwt_stream.map parse_line lines in - lwt lines = Lwt_stream.get_while (fun _ -> true) lines in - lwt _ = Lwt_io.close ic in - return lines - -let print_record = function - | Data (address, data) -> - Printf.printf "DAT %04x" address; - String.iter (fun c -> Printf.printf " %02x" (int_of_char c)) data; - Printf.printf "\n" - | ExtendedLinearAddress address -> - Printf.printf "ELA %04x\n" address - | EndOfFile address -> - Printf.printf "EOF %04x\n" address - -let validate_and_copy hex addr_base buffer offset length = - assert (offset+length <= String.length buffer); - let min_address = addr_base+offset in - let max_address = min_address+length in - let addr_high = ref 0 in - let execute_record = function - | Data (address, data) -> - assert (address land 0xFFFF = address); - let address = !addr_high lor address in - if address < min_address || address >= max_address then - Printf.eprintf - "0x%04x is outside range, all bytes dropped\n" - address - else begin - let length = - let n = String.length data in - if address+n >= max_address then begin - Printf.eprintf - "some bytes at address 0x%04x are outside range (dropped)\n" - address; - max_address-address - end else n - in - let offset2 = address-addr_base in - String.blit data 0 buffer offset2 length; - end - | ExtendedLinearAddress address -> - assert (address land 0x8000 = 0); - addr_high := address lsl 16 - | EndOfFile address -> - assert (address = 0); - raise Exit - in - try List.iter execute_record hex with Exit -> () diff --git a/PC_Mainboard/card_tools/hexfile.mli b/PC_Mainboard/card_tools/hexfile.mli deleted file mode 100644 index c6fa563..0000000 --- a/PC_Mainboard/card_tools/hexfile.mli +++ /dev/null @@ -1,26 +0,0 @@ -(* - * hexfile.mli - * ----------- - * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> - * Licence : BSD3 - * - * This file is a part of Krobot. - *) - -type hex_record = - | Data of int * string - | ExtendedLinearAddress of int - | EndOfFile of int - -val parse_file : string -> hex_record list Lwt.t - -val print_record : hex_record -> unit - (** Prints one record on standard output. *) - -val validate_and_copy : hex_record list -> int -> string -> int -> int -> unit - (** [validate_and_copy hex addr_base buffer offset length] copies - the contents of the (parsed) [hex] file to [buffer]. [offset] - and [length] denote the valid range inside [buffer] that can be - written. [addr_base] is the address [buffer] is mapped to on the - microcontroller. Bytes outside the range are ignored (and a - warning is printed on standard error. *) diff --git a/PC_Mainboard/card_tools/krobot_boardname.mli b/PC_Mainboard/card_tools/krobot_boardname.mli new file mode 100644 index 0000000..51dc1b5 --- /dev/null +++ b/PC_Mainboard/card_tools/krobot_boardname.mli @@ -0,0 +1,12 @@ +(* + * krobot_boardname.mli + * -------------------- + * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> + * Licence : BSD3 + * + * This file is a part of Krobot. + *) + +val get_board_name : string -> string option + (** [get_board_name dump] recherche dans le [dump] mémoire (peut + être également un fichier .hex chargé) le nom de la carte. *) diff --git a/PC_Mainboard/card_tools/krobot_boardname.mll b/PC_Mainboard/card_tools/krobot_boardname.mll new file mode 100644 index 0000000..96b39b6 --- /dev/null +++ b/PC_Mainboard/card_tools/krobot_boardname.mll @@ -0,0 +1,22 @@ +(* + * krobot_boardname.mll + * -------------------- + * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> + * Licence : BSD3 + * + * This file is a part of Krobot. + *) + + +let boardname_regex = ("Carte " | "Robot Interface" | "Battery Monitoring ") [^'\n']+ + +rule boardname = parse + | (boardname_regex as name) '\n' { Some name } + | _ { boardname lexbuf } + | eof { None } + +{ + let get_board_name str = + let lexbuf = Lexing.from_string str in + boardname lexbuf +} diff --git a/PC_Mainboard/card_tools/krobot_bootloader.ml b/PC_Mainboard/card_tools/krobot_bootloader.ml new file mode 100644 index 0000000..1deb632 --- /dev/null +++ b/PC_Mainboard/card_tools/krobot_bootloader.ml @@ -0,0 +1,184 @@ +(* + * krobot_bootloader.ml + * -------------------- + * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> + * Licence : BSD3 + * + * This file is a part of Krobot. + *) + +open Lwt +open Lwt_io + +(* Code très inspiré de kard.ml, mais mis à part car le mode de + communication avec la carte est différent (bulk au lieu + d'interrupt). *) + +type t = { + mutable is_open : bool; + (* La carte est-elle ouverte ? *) + + handle : USB.handle; + (* Handle pour le périphérique usb *) + + kernel_active : bool; + (* Est-ce qu'un driver noyau était attaché à la carte avant qu'on + l'utilise ? *) +} + +type error = + | IncompleteWrite of int * int + | IncompleteRead of int * int + | UnexpectedReply of string * string + | WriteError of string * string + +let string_of_error = function + | IncompleteWrite (a, b) -> Printf.sprintf "%d byte(s) written instead of %d" a b + | IncompleteRead (a, b) -> Printf.sprintf "%d byte(s) read instead of %d" a b + | UnexpectedReply (a, b) -> Printf.sprintf "received unexpected reply %S instead of %S" a b + | WriteError (a, b) -> Printf.sprintf "written: %S, read back: %S" a b + +exception Error of error + +let failwith e = fail (Error e) + +let close k = + if k.is_open then begin + lwt _ = USB.release_interface k.handle 0 in + lwt _ = USB.reset_device k.handle in + (*if k.kernel_active then USB.attach_kernel_driver k.handle 0;*) + (*USB.close k.handle;*) + k.is_open <- false; + return () + end else return () + +let open_card () = + let handle = USB.open_device_with + ~vendor_id:PcInterface.usb_vid + ~product_id:PcInterface.usb_pid_bootloader + in + let kernel_active = USB.kernel_driver_active handle 0 in + if kernel_active then USB.detach_kernel_driver handle 0; + lwt _ = USB.set_configuration handle 1 in + lwt _ = USB.claim_interface handle 0 in + let k = { is_open = true; + handle = handle; + kernel_active = kernel_active } in + let _ = Lwt_sequence.add_l (fun _ -> close k) Lwt_main.exit_hooks in + return k + +let header_length = 5 + +let put_message buffer cmd length address data = + let body_length = String.length data in + assert (String.length buffer >= header_length+body_length); + let set i n = buffer.[i] <- char_of_int n in + set 0 cmd; + assert (length < 0x100); + set 1 length; + assert (address <= 0x1000000); + set 2 (address land 0xff); + set 3 ((address lsr 8) land 0xff); + set 4 ((address lsr 16) land 0xff); + String.blit data 0 buffer 5 body_length + +let send_receive_packet k send_buffer send_length receive_buffer receive_length send_delay receive_delay = + let handle = k.handle and endpoint = 1 in + lwt sent = USB.bulk_send ~handle ~endpoint ~timeout:1. send_buffer 0 send_length in + if sent <> send_length then + failwith (IncompleteWrite (sent, send_length)) + else begin + lwt received = USB.bulk_recv ~handle ~endpoint ~timeout:3. receive_buffer 0 receive_length in + if received <> receive_length then + failwith (IncompleteRead (received, receive_length)) + else + return () + end + +let get_flash k ~address ~length = + let response_length = 64 in + let increment = response_length-header_length in + assert (increment < 256); + let send_buffer = String.create header_length in + let receive_buffer = String.create response_length in + let result_buffer = String.create length in + let rec loop offset total_length = + if total_length <= 0 then + return result_buffer + else begin + let length = min increment total_length in + let response_length = length+header_length in + let address = address+offset in + put_message send_buffer PcInterface.read_flash length address ""; + lwt () = send_receive_packet k send_buffer header_length receive_buffer response_length 1. 3. in + let receive_header = String.sub receive_buffer 0 header_length in + if receive_header <> send_buffer then + failwith (UnexpectedReply (receive_header, send_buffer)) + else begin + String.blit receive_buffer header_length result_buffer offset length; + loop (offset+length) (total_length-length); + end + end + in loop 0 length + +let erase_flash k ~address ~length = + let response_length = 1 in + (* les effacements se font par blocs de 64 octets *) + let increment = 64 in + let send_buffer = String.create header_length in + let receive_buffer = String.create response_length in + let rec loop offset total_length = + if total_length <= 0 then + return () + else begin + let address = address+offset in + put_message send_buffer PcInterface.erase_flash 1 address ""; + lwt () = send_receive_packet k send_buffer header_length receive_buffer response_length 1. 5. in + if int_of_char receive_buffer.[0] <> PcInterface.erase_flash then + failwith (UnexpectedReply (receive_buffer, String.make 1 (char_of_int PcInterface.erase_flash))) + else + loop (offset+increment) (total_length-increment); + end + in loop 0 length + +let reference = String.make 16 '\255' + +let write_flash k ~address data offset length = + let send_length = 64 and receive_length = 1 in + (* les écritures se font par blocs de 16 octets *) + let increment = 16 in + let send_buffer = String.create send_length in + let receive_buffer = String.create receive_length in + let rec loop address offset total_length = + (* address: sur le PIC, offset: dans data, total_length: taille restante *) + if total_length <= 0 then + return () + else begin + let packet = String.make increment '\255' in + String.blit data offset packet 0 (min total_length increment); + if packet = reference then begin + (* le paquet n'a pas de contenu, on l'ignore *) + (* lwt () = printf "Skipping address 0x%06X...\n" address in *) + loop (address+increment) (offset+increment) (total_length-increment) + end else begin + (* lwt () = printf "Processing address 0x%06X...\n" address in *) + put_message send_buffer PcInterface.write_flash increment address packet; + lwt () = send_receive_packet k send_buffer send_length receive_buffer receive_length 0.5 1. in + if int_of_char receive_buffer.[0] <> PcInterface.write_flash then + failwith (UnexpectedReply (receive_buffer, String.make 1 (char_of_int PcInterface.erase_flash))) + else begin + lwt written = get_flash k ~address ~length:increment in + if written <> packet then + failwith (WriteError (packet, written)) + else + loop (address+increment) (offset+increment) (total_length-increment) + end + end + end + in loop address offset length + +let reset_board k = + let send_buffer = String.create 64 and receive_buffer = String.create 64 in + send_buffer.[0] <- char_of_int PcInterface.reset; + lwt () = send_receive_packet k send_buffer 1 receive_buffer 64 5. 5. in + return () diff --git a/PC_Mainboard/card_tools/krobot_dump_memory.ml b/PC_Mainboard/card_tools/krobot_dump_memory.ml new file mode 100644 index 0000000..91b80d1 --- /dev/null +++ b/PC_Mainboard/card_tools/krobot_dump_memory.ml @@ -0,0 +1,28 @@ +(* + * krobot_dump_memory.ml + * --------------------- + * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> + * Licence : BSD3 + * + * This file is a part of Krobot. + *) + +open Printf +open Lwt +open Lwt_io + +lwt () = + lwt k = Krobot_bootloader.open_card () in + try_lwt + lwt data = Krobot_bootloader.get_flash k ~address:0x0 ~length:0x8000 in + let msg = match Krobot_boardname.get_board_name data with + | Some s -> sprintf "Board: %S" s + | None -> "Unable to identify board!" + in + lwt () = eprintlf "%s" msg in + (if Unix.isatty Unix.stdout then hexdump else write) stdout data >> flush stdout + with + | Krobot_bootloader.Error e -> + eprintlf "%s" (Krobot_bootloader.string_of_error e) + | e -> + eprintlf "%s" (Printexc.to_string e) diff --git a/PC_Mainboard/card_tools/krobot_hexfile.ml b/PC_Mainboard/card_tools/krobot_hexfile.ml new file mode 100644 index 0000000..2d2c361 --- /dev/null +++ b/PC_Mainboard/card_tools/krobot_hexfile.ml @@ -0,0 +1,112 @@ +(* + * krobot_hexfile.ml + * ----------------- + * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> + * Licence : BSD3 + * + * This file is a part of Krobot. + *) + +open Lwt +open Lwt_io + +type hex_record = + | Data of int * string + | ExtendedLinearAddress of int + | EndOfFile of int + +let string_of_hexline str = + let n = String.length str in + assert (n > 0 && n mod 2 = 1 && str.[0] = ':'); + let m = n/2 in + let result = String.create m in + for i = 0 to m-1 do + let j = 2*i+1 in + result.[i] <- char_of_int (int_of_string ("0x"^(String.sub str j 2))) + done; + result + +let compute_checksum str = + let rec aux i accu = + if i < 0 then + (-accu) land 0xff + else + aux (i-1) (accu+(int_of_char str.[i])) + in aux (String.length str - 2) 0 + +let parse_line str = + let str = string_of_hexline str in + let get i = int_of_char str.[i] in + let n = String.length str in + assert (n >= 5 && compute_checksum str = int_of_char str.[n-1]); + let count = get 0 in + assert (count+5 = n); + let address = ((get 1) lsl 8) lor (get 2) in + let record_type = get 3 in + let data = String.sub str 4 count in + match record_type with + | 0x00 -> + Data (address, data) + | 0x01 -> + assert (count = 0); + EndOfFile address + | 0x04 -> + assert (count = 2 && address = 0); + let msb = int_of_char data.[0] and lsb = int_of_char data.[1] in + (* check for possible overflow *) + assert (msb land 0x80 = 0); + ExtendedLinearAddress ((msb lsl 8) lor lsb) + | _ -> assert false + +let parse_file file = + let ic = Lwt_io.open_file ~mode:input file in + let lines = Lwt_io.read_lines ic in + let lines = Lwt_stream.map parse_line lines in + lwt lines = Lwt_stream.get_while (fun _ -> true) lines in + lwt _ = Lwt_io.close ic in + return lines + +let print_record = function + | Data (address, data) -> + Printf.printf "DAT %04x" address; + String.iter (fun c -> Printf.printf " %02x" (int_of_char c)) data; + Printf.printf "\n" + | ExtendedLinearAddress address -> + Printf.printf "ELA %04x\n" address + | EndOfFile address -> + Printf.printf "EOF %04x\n" address + +let validate_and_copy hex addr_base buffer offset length = + assert (offset+length <= String.length buffer); + let min_address = addr_base+offset in + let max_address = min_address+length in + let addr_high = ref 0 in + let execute_record = function + | Data (address, data) -> + assert (address land 0xFFFF = address); + let address = !addr_high lor address in + if address < min_address || address >= max_address then + Printf.eprintf + "0x%04x is outside range, all bytes dropped\n" + address + else begin + let length = + let n = String.length data in + if address+n >= max_address then begin + Printf.eprintf + "some bytes at address 0x%04x are outside range (dropped)\n" + address; + max_address-address + end else n + in + let offset2 = address-addr_base in + String.blit data 0 buffer offset2 length; + end + | ExtendedLinearAddress address -> + assert (address land 0x8000 = 0); + addr_high := address lsl 16 + | EndOfFile address -> + assert (address = 0); + raise Exit + in + try List.iter execute_record hex with Exit -> () diff --git a/PC_Mainboard/card_tools/krobot_hexfile.mli b/PC_Mainboard/card_tools/krobot_hexfile.mli new file mode 100644 index 0000000..932e32e --- /dev/null +++ b/PC_Mainboard/card_tools/krobot_hexfile.mli @@ -0,0 +1,26 @@ +(* + * krobot_hexfile.mli + * ------------------ + * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> + * Licence : BSD3 + * + * This file is a part of Krobot. + *) + +type hex_record = + | Data of int * string + | ExtendedLinearAddress of int + | EndOfFile of int + +val parse_file : string -> hex_record list Lwt.t + +val print_record : hex_record -> unit + (** Prints one record on standard output. *) + +val validate_and_copy : hex_record list -> int -> string -> int -> int -> unit + (** [validate_and_copy hex addr_base buffer offset length] copies + the contents of the (parsed) [hex] file to [buffer]. [offset] + and [length] denote the valid range inside [buffer] that can be + written. [addr_base] is the address [buffer] is mapped to on the + microcontroller. Bytes outside the range are ignored (and a + warning is printed on standard error. *) diff --git a/PC_Mainboard/card_tools/krobot_send_firmware.ml b/PC_Mainboard/card_tools/krobot_send_firmware.ml new file mode 100644 index 0000000..82261c5 --- /dev/null +++ b/PC_Mainboard/card_tools/krobot_send_firmware.ml @@ -0,0 +1,69 @@ +(* + * krobot_send_firmware.ml + * ----------------------- + * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> + * Licence : BSD3 + * + * This file is a part of Krobot. + *) + +open Lwt +open Lwt_io + +let do_flash force filename = + lwt hex = Krobot_hexfile.parse_file filename in + let memory = + let buffer = String.make 0x8000 '\255' in + Krobot_hexfile.validate_and_copy hex 0x0 buffer 0 0x8000; + buffer + in + let firmware_name = Krobot_boardname.get_board_name memory in + lwt () = match firmware_name with + | Some s -> printf "Detected firmware: %S\n" s + | None -> printf "Unable to identify firmware!\n" + in + let address = 0x800 and length = 0x8000-0x800 in + lwt k = Krobot_bootloader.open_card () in + lwt () = printf "Card opened\n" in + lwt data = Krobot_bootloader.get_flash k ~address:0x0 ~length:0x8000 in + let board_name = Krobot_boardname.get_board_name data in + lwt () = match board_name with + | Some s -> printf "Detected card: %S\n" s + | None -> printf "Unable to identify card!\n" + in + lwt () = + if not force && (board_name = None || firmware_name = None || board_name <> firmware_name) then begin + lwt () = eprintf "board name and firmware name do not match, use --force\n" in + exit 1 + end else return () + in + lwt () = Krobot_bootloader.erase_flash k ~address ~length in + lwt () = printf "Flash erased\n" in + lwt () = Krobot_bootloader.write_flash k ~address memory address length in + lwt () = printf "Flashing completed\n" in + lwt () = Krobot_bootloader.reset_board k in + return () + +lwt () = + let force = ref false in + let filename = ref None in + let speclist = [ + "--force", Arg.Set force, "Force flashing even if board id and firmware id do not match"; + ] in + Arg.parse speclist + (fun s -> + match !filename with + | None -> filename := Some s + | Some _ -> raise (Arg.Bad s)) + "Send a firmware to a board in bootloader mode"; + let filename = match !filename with + | None -> Printf.eprintf "You must specify a .hex file!\n"; exit 1 + | Some s -> s + in + try_lwt + do_flash !force filename + with + | Krobot_bootloader.Error e -> + eprintl (Krobot_bootloader.string_of_error e) + | e -> + eprintl (Printexc.to_string e) diff --git a/PC_Mainboard/card_tools/send_firmware.ml b/PC_Mainboard/card_tools/send_firmware.ml deleted file mode 100644 index 321edb6..0000000 --- a/PC_Mainboard/card_tools/send_firmware.ml +++ /dev/null @@ -1,70 +0,0 @@ -(* - * send_firmware.ml - * ---------------- - * Copyright : (c) 2009, Stéphane Glondu <st...@gl...> - * Licence : BSD3 - * - * This file is a part of Krobot. - *) - -open Lwt -open Lwt_io - -let do_flash force filename = - lwt hex = Hexfile.parse_file filename in - let memory = - let buffer = String.make 0x8000 '\255' in - Hexfile.validate_and_copy hex 0x0 buffer 0 0x8000; - buffer - in - let firmware_name = Boardname.get_board_name memory in - lwt () = match firmware_name with - | Some s -> printf "Detected firmware: %S\n" s - | None -> printf "Unable to identify firmware!\n" - in - let address = 0x800 and length = 0x8000-0x800 in - lwt k = Bootloader.open_card () in - lwt () = printf "Card opened\n" in - lwt data = Bootloader.get_flash k ~address:0x0 ~length:0x8000 in - let board_name = Boardname.get_board_name data in - lwt () = match board_name with - | Some s -> printf "Detected card: %S\n" s - | None -> printf "Unable to identify card!\n" - in - lwt () = - if not force && (board_name = None || firmware_name = None || board_name <> firmware_name) then begin - lwt () = eprintf "board name and firmware name do not match, use --force\n" in - exit 1 - end else return () - in - lwt () = Bootloader.erase_flash k ~address ~length in - lwt () = printf "Flash erased\n" in - lwt () = Bootloader.write_flash k ~address memory address length in - lwt () = printf "Flashing completed\n" in - lwt () = Bootloader.reset_board k in - return () - -let _ = - let force = ref false in - let filename = ref None in - let speclist = [ - "--force", Arg.Set force, "Force flashing even if board id and firmware id do not match"; - ] in - Arg.parse speclist - (fun s -> - match !filename with - | None -> filename := Some s - | Some _ -> raise (Arg.Bad s)) - "Send a firmware to a board in bootloader mode"; - let filename = match !filename with - | None -> Printf.eprintf "You must specify a .hex file!\n"; exit 1 - | Some s -> s - in - Lwt_main.run - (try_lwt - do_flash !force filename - with - | Bootloader.Error e -> - eprintl (Bootloader.string_of_error e) - | e -> - eprintl (Printexc.to_string e)) diff --git a/PC_Mainboard/driver/krobot_driver.ml b/PC_Mainboard/driver/krobot_driver.ml index 85b8d0b..7998bdd 100644 --- a/PC_Mainboard/driver/krobot_driver.ml +++ b/PC_Mainboard/driver/krobot_driver.ml @@ -69,10 +69,10 @@ struct if data <> dev.data then begin dev.data <- data; lwt () = value dev data in - lwt () = Lwt_unix.sleep Krobot_config.update_delay in + lwt () = Lwt_unix.sleep (Krobot_config.update_delay *. 2.) in loop dev end else - lwt () = Lwt_unix.sleep Krobot_config.update_delay in + lwt () = Lwt_unix.sleep (Krobot_config.update_delay *. 2.) in loop dev let make card path = @@ -222,7 +222,7 @@ struct OL_method GripClose : unit = fun dev -> set_ax12 dev [{ aa_id = 2; aa_position = 510; aa_velocity = 100 }; - { aa_id = 3; aa_position = 465; aa_velocity = 200 }] + { aa_id = 3; aa_position = 390; aa_velocity = 200 }] let make card path = return { diff --git a/PC_Mainboard/myocamlbuild.ml b/PC_Mainboard/myocamlbuild.ml index a182489..42a97e6 100644 --- a/PC_Mainboard/myocamlbuild.ml +++ b/PC_Mainboard/myocamlbuild.ml @@ -57,8 +57,8 @@ let targets = List.filter_opt (function (true, target) -> Some target | (false, (have_lwt_unix && have_usb && have_obus, "driver/krobot_driver.best"); (* Card tools *) - (have_lwt_unix && have_usb, "card_tools/send_firmware.best"); - (have_lwt_unix && have_usb, "card_tools/dump_memory.best"); + (have_lwt_unix && have_usb, "card_tools/krobot_send_firmware.best"); + (have_lwt_unix && have_usb, "card_tools/krobot_dump_memory.best"); (* Krobot client library *) (have_lwt_unix && have_obus, "krobot.cma"); @@ -66,7 +66,7 @@ let targets = List.filter_opt (function (true, target) -> Some target | (false, (have_lwt_unix && have_obus && have_native, "krobot.cmxs"); (* Tools *) - (have_lwt_unix && have_obus, "tools/forward_dbus.best"); + (have_lwt_unix && have_obus, "tools/krobot_forward_dbus.best"); (* Clients *) (have_lwt_unix && have_obus, "clients/krobot_info.best"); @@ -75,7 +75,7 @@ let targets = List.filter_opt (function (true, target) -> Some target | (false, (have_lwt_unix && have_obus && have_sdl, "clients/krobot_joy_control.best"); (* Services *) - (have_lwt_unix && have_obus, "services/hard_stop.best"); + (have_lwt_unix && have_obus, "services/krobot_hard_stop.best"); (* Tests *) (have_lwt_unix && have_obus, "tests/double_move.best"); diff --git a/PC_Mainboard/services/hard_stop.ml b/PC_Mainboard/services/hard_stop.ml deleted file mode 100644 index 1a0bcb5..0000000 --- a/PC_Mainboard/services/hard_stop.ml +++ /dev/null @@ -1,70 +0,0 @@ -(* - * hard_stop.ml - * ------------ - * Copyright : (c) 2010, Jeremie Dimino <je...@di...> - * Licence : BSD3 - * - * This file is a part of [kro]bot. - *) - -(* Stop the robot on collisions *) - -open Lwt - -(* Duration of an inhibition: *) -let duration = 1.0 - -let foreground = ref false -let args = [ - "-n", Arg.Set foreground, "do not daemonize"; -] -let usage = Printf.sprintf "Usage: %s [-n]\n\noptions are:" (Filename.basename (Sys.argv.(0))) - -type state = OK | Stopped - -let handle_collide krobot sensors = - try_lwt - join [ - (if Krobot_util.front_collide sensors then begin - lwt () = Lwt_log.notice "front collision detected, inhibit motors" in - Krobot.inhibit_forward krobot duration - end else - return ()); - (if Krobot_util.back_collide sensors then begin - lwt () = Lwt_log.notice "back collision detected, inhibit motors" in - Krobot.inhibit_backward krobot duration - end else - return ()); - ] - with exn -> - Lwt_log.info_f "collision handling failed with: %s" (Printexc.to_string exn) - -lwt () = - Arg.parse args ignore usage; - - lwt bus = Lazy.force Krobot.bus in - (* Ensure there is only one running instance of the service: *) - lwt () = Krobot_util.single_instance bus "fr.krobot.HardStop" in - - lwt () = - if !foreground then - Lwt_log.info "starting krobot hard stopper in foreground mode" - else begin - lwt () = Lwt_log.info "starting krobot hard stopper in daemon mode" in - Lwt_daemon.daemonize (); - return () - end - in - - lwt krobot = Krobot.create () in - - (* Stop motors as soon as possible: *) - Lwt_signal.always_notify_p (handle_collide krobot) (Krobot.logic_sensors krobot); - - (* Continue the inhibition: *) - let rec loop () = - lwt () = handle_collide krobot (React.S.value (Krobot.logic_sensors krobot)) in - lwt () = Lwt_unix.sleep (duration /. 2.) in - loop () - in - loop () diff --git a/PC_Mainboard/services/krobot_hard_stop.ml b/PC_Mainboard/services/krobot_hard_stop.ml new file mode 100644 index 0000000..51b832c --- /dev/null +++ b/PC_Mainboard/services/krobot_hard_stop.ml @@ -0,0 +1,70 @@ +(* + * krobot_hard_stop.ml + * ------------------- + * Copyright : (c) 2010, Jeremie Dimino <je...@di...> + * Licence : BSD3 + * + * This file is a part of [kro]bot. + *) + +(* Stop the robot on collisions *) + +open Lwt + +(* Duration of an inhibition: *) +let duration = 1.0 + +let foreground = ref false +let args = [ + "-n", Arg.Set foreground, "do not daemonize"; +] +let usage = Printf.sprintf "Usage: %s [-n]\n\noptions are:" (Filename.basename (Sys.argv.(0))) + +type state = OK | Stopped + +let handle_collide krobot sensors = + try_lwt + join [ + (if Krobot_util.front_collide sensors then begin + lwt () = Lwt_log.notice "front collision detected, inhibit motors" in + Krobot.inhibit_forward krobot duration + end else + return ()); + (if Krobot_util.back_collide sensors then begin + lwt () = Lwt_log.notice "back collision detected, inhibit motors" in + Krobot.inhibit_backward krobot duration + end else + return ()); + ] + with exn -> + Lwt_log.info_f "collision handling failed with: %s" (Printexc.to_string exn) + +lwt () = + Arg.parse args ignore usage; + + lwt bus = Lazy.force Krobot.bus in + (* Ensure there is only one running instance of the service: *) + lwt () = Krobot_util.single_instance bus "fr.krobot.HardStop" in + + lwt () = + if !foreground then + Lwt_log.info "starting krobot hard stopper in foreground mode" + else begin + lwt () = Lwt_log.info "starting krobot hard stopper in daemon mode" in + Lwt_daemon.daemonize (); + return () + end + in + + lwt krobot = Krobot.create () in + + (* Stop motors as soon as possible: *) + Lwt_signal.always_notify_p (handle_collide krobot) (Krobot.logic_sensors krobot); + + (* Continue the inhibition: *) + let rec loop () = + lwt () = handle_collide krobot (React.S.value (Krobot.logic_sensors krobot)) in + lwt () = Lwt_unix.sleep (duration /. 2.) in + loop () + in + loop () diff --git a/PC_Mainboard/tools/forward_dbus.ml b/PC_Mainboard/tools/forward_dbus.ml deleted file mode 100644 index 8685578..0000000 --- a/PC_Mainboard/tools/forward_dbus.ml +++ /dev/null @@ -1,27 +0,0 @@ -(* - * forward_dbus.ml - * --------------- - * Copyright : (c) 2010, Jeremie Dimino <je...@di...> - * Licence : BSD3 - * - * This file is a part of [kro]bot. - *) - -open Lwt - -let rec copy ta tb = - lwt msg = OBus_transport.recv ta in - lwt () = OBus_transport.send tb msg in - copy ta tb - -lwt () = - let addresses = OBus_address.of_string Krobot_config.bus_address in - lwt (_, ta) = OBus_transport.of_addresses addresses in - let tb = - OBus_transport.make - ~send:(fun msg -> OBus_wire.write_message Lwt_io.stdout msg) - ~recv:(fun () -> OBus_wire.read_message Lwt_io.stdin) - ~shutdown:return - () - in - copy ta tb <&> copy tb ta diff --git a/PC_Mainboard/tools/krobot_forward_dbus.ml b/PC_Mainboard/tools/krobot_forward_dbus.ml new file mode 100644 index 0000000..383e3af --- /dev/null +++ b/PC_Mainboard/tools/krobot_forward_dbus.ml @@ -0,0 +1,30 @@ +(* + * krobot_forward_dbus.ml + * ---------------------- + * Copyright : (c) 2010, Jeremie Dimino <je...@di...> + * Licence : BSD3 + * + * This file is a part of [kro]bot. + *) + +open Lwt + +let rec copy ta tb = + lwt msg = OBus_transport.recv ta in + lwt () = OBus_transport.send tb msg in + copy ta tb + +lwt () = + let addresses = OBus_address.of_string Krobot_config.bus_address in + lwt (_, ta) = OBus_transport.of_addresses addresses in + let tb = + OBus_transport.make + ~send:(fun msg -> OBus_wire.write_message Lwt_io.stdout msg) + ~recv:(fun () -> OBus_wire.read_message Lwt_io.stdin) + ~shutdown:return + () + in + try_lwt + copy ta tb <&> copy tb ta + with End_of_file -> + return () hooks/post-receive -- krobot |