From ee5a468417fb6810a5bbe4d46617618a9ddb588a Mon Sep 17 00:00:00 2001 From: NĂ©lio Laranjeiro Date: Thu, 7 May 2009 10:07:49 +0200 Subject: * digital/avr/modules/trace: (See #67) * Adapted the trace module to: * Find the last trace in order to start the new one, trace_i = trace_i-1 + 1 * A quarter of the flash is completely erased on the trace init to be used in the future. * Removed the start code useless from now. * tools/trace: * Update the python scripts to use the new trace implementation. --- digital/avr/modules/flash/flash.c | 74 +++----------- digital/avr/modules/flash/flash.h | 24 ++--- .../modules/trace/test/test_target/test-trace.c | 112 +++++++++++---------- digital/avr/modules/trace/trace.c | 102 ++++++++++--------- digital/avr/modules/utils/utils.h | 6 ++ tools/trace/tinter/thost.py | 77 +++++++------- tools/trace/tinter/tinter.py | 31 +++++- tools/trace/tinter/utils.py | 15 +-- tools/trace/trace.py | 11 +- 9 files changed, 225 insertions(+), 227 deletions(-) diff --git a/digital/avr/modules/flash/flash.c b/digital/avr/modules/flash/flash.c index dffc6d82..7b563bc6 100644 --- a/digital/avr/modules/flash/flash.c +++ b/digital/avr/modules/flash/flash.c @@ -27,6 +27,9 @@ #include "modules/spi/spi.h" #include "modules/utils/utils.h" +#define FLASH_LOG_PAGE_SIZE 0x80000 +#define FLASH_LOG_BUFFER_SIZE 128 + /** Flash access. * The flash contains an address of 21 bits in a range from 0x0-0x1fffff. * This function shall access the memory directly by the SPI. @@ -139,28 +142,6 @@ flash_init (void) return 1; } -/** Find the first writable sector. - * \param addr the address to start the research. - * \return the address of the next sector. - */ -uint32_t -flash_first_sector (void) -{ - uint8_t rsp = 0; - uint32_t addr; - - /* Search for the next address to start writing. */ - for (addr = 0; - (rsp != 0xFF) && (addr < FLASH_ADDRESS_HIGH); - addr += FLASH_PAGE_SIZE) - { - rsp = flash_read (addr); - } - - return addr < (FLASH_ADDRESS_HIGH + 1) ? - addr - FLASH_PAGE_SIZE : FLASH_ADDRESS_ERROR; -} - /** Write in the flash byte provided in parameter. * \param data the buffer to store the data. */ @@ -240,11 +221,11 @@ flash_write_array (uint32_t addr, uint8_t *data, uint32_t length) } } -uint8_t +int8_t flash_log (uint8_t size, uint8_t *args) { - uint8_t buf[128+1]; - uint8_t status = 0x0; + uint8_t buf[FLASH_LOG_BUFFER_SIZE+1]; + int8_t error = 0x0; uint32_t addr = 0; if (size >= 4) @@ -254,37 +235,8 @@ flash_log (uint8_t size, uint8_t *args) switch (args[0]) { case FLASH_CMD_INIT: - status = flash_init (); - if (status) - { - uint32_t res; - uint32_t ended = 0; - for (addr = 0; addr < FLASH_ADDRESS_HIGH; addr += FLASH_PAGE_SIZE) - { - flash_read_array (addr, (uint8_t *) &res, 4); - if (res == 0xFFFFFFFF) - { - ended = addr; - proto_send3b ('e', addr >> 16, addr >> 8, addr); - /* The sector is empty. */ - break; - } - } - - for (addr = FLASH_PAGE (ended - FLASH_PAGE_SIZE); - addr != ended; - addr = FLASH_PAGE (addr - FLASH_PAGE_SIZE)) - { - uint32_t res; - flash_read_array (addr, (uint8_t *) &res, 4); - if (res == FLASH_LOG_CODE_READ) - { - proto_send3b ('i', addr >> 16, addr >> 8, addr); - break; - } - } - } - proto_send1b ('s', status); + error = !flash_init (); + proto_send1b ('s', error ? 0 : 1); break; case FLASH_CMD_READ: if ((size == 5) @@ -292,17 +244,19 @@ flash_log (uint8_t size, uint8_t *args) { flash_read_array (addr, buf, args[4]); proto_send ('r', args[4], buf); - status = 0x1; + error = 0; } else if (size == 4) { proto_send1b ('r', flash_read (addr)); - status = 0x1; + error = 0; } + else + error = 2; break; default: - status = 0x0; + return 3; } - return status; + return error; } diff --git a/digital/avr/modules/flash/flash.h b/digital/avr/modules/flash/flash.h index 9f92259a..d1fec1f0 100644 --- a/digital/avr/modules/flash/flash.h +++ b/digital/avr/modules/flash/flash.h @@ -27,15 +27,12 @@ #include "common.h" #include "io.h" -#define FLASH_ADDRESS_HIGH 0x1FFFFF +#define FLASH_SIZE 0x200000 +#define FLASH_ADDRESS_HIGH (FLASH_SIZE - 1) #define FLASH_ADDRESS_ERROR 0xFFFFFF #define FLASH_ADDRESS_INC(val) \ ((val) + 1) & FLASH_ADDRESS_HIGH -#define FLASH_PAGE_SIZE 0x1000 -#define FLASH_PAGE_MASK (FLASH_ADDRESS_HIGH & ~(FLASH_PAGE_SIZE-1)) -#define FLASH_PAGE(val) ((val) & FLASH_PAGE_MASK) - #define FLASH_ERASE_FULL 0x60 #define FLASH_ERASE_4K 0x20 #define FLASH_ERASE_32K 0x52 @@ -53,9 +50,6 @@ #define FLASH_TBP_US 10 -#define FLASH_LOG_CODE 0xF33FF22F -#define FLASH_LOG_CODE_READ 0x2FF23FF3 - enum { FLASH_CMD_INIT, @@ -114,13 +108,6 @@ flash_status_aai (void) uint8_t flash_init (void); -/** Find the first writable sector. - * \param addr the address to start the research. - * \return the address of the next sector. - */ -uint32_t -flash_first_sector (void); - /** Write in the flash byte provided in parameter. * \param data the buffer to store the data. */ @@ -154,9 +141,12 @@ flash_write_array (uint32_t addr, uint8_t *data, uint32_t length); /** Process the logs * \param size the number of arguments. * \param an array of arguments. - * \return true on success. + * \return - 0 on success, + * - 1 flash not initialised + * - 2 flash read error. + * - 3 command not found. */ -uint8_t +int8_t flash_log (uint8_t size, uint8_t *args); #endif /* flash_h */ diff --git a/digital/avr/modules/trace/test/test_target/test-trace.c b/digital/avr/modules/trace/test/test_target/test-trace.c index 4dbbebf4..7938103b 100644 --- a/digital/avr/modules/trace/test/test_target/test-trace.c +++ b/digital/avr/modules/trace/test/test_target/test-trace.c @@ -33,49 +33,48 @@ #include "modules/utils/byte.h" #include "modules/uart/uart.h" -void -flash_dump_full (void) -{ - uint8_t buffer [BUFFER_SIZE]; - uint32_t i; - uint8_t state; - - /* Initialise the flash memory to read .*/ - state = flash_init (); - proto_send1b ('s', state); - - if (state) - { - for (i = 0; i < FLASH_ADDRESS_HIGH + 1; - i += sizeof (buffer)) - { - flash_read_array (i, buffer, sizeof (buffer)); - proto_send ('r', sizeof(buffer), buffer); - } - } -} +#include "events.h" void -flash_dump_sector (uint32_t addr) +flood (void) { - uint8_t buffer [BUFFER_SIZE]; - uint32_t i; - uint8_t state; + uint32_t addr; + uint32_t count; + + uint32_t speed; + uint32_t position; + uint16_t acc; + uint16_t arg1; + uint16_t arg2; + uint32_t arg3; + + /* Initialise the trace module. */ + trace_init (); - /* Initialise the flash memory to read .*/ - state = flash_init (); - proto_send1b ('s', state); + /* Get the start page address of the trace module. */ + addr = trace_addr_current (); + proto_send3b ('a', addr >> 16, addr >> 8, addr); - if (state) + /* Flood the flash memory with traces. */ + /* A little more than 3 memory sectors, a sector is 4 kbytes. */ + for (count = 0; count < 2000; count ++) { - for (i = FLASH_PAGE (addr); i < FLASH_PAGE (addr) + FLASH_PAGE_SIZE; - i += sizeof (buffer)) - { - flash_read_array (i, buffer, sizeof (buffer)); - proto_send ('r', sizeof(buffer), buffer); - } + /* Right motor. */ + speed = 1; + position = 2; + acc = 3; + arg1 = 1; + arg2 = 2; + arg3 = 3; + TRACE (TRACE_ASSERV__RIGHT_MOTOR, speed, position, acc); + TRACE (TRACE_ASSERV__LEFT_MOTOR, speed, position, acc); + TRACE (TRACE_IA__IA_CMD, arg1, arg2, arg3); } + + /* Print the end of the address. */ + addr = trace_addr_current (); + proto_send3b ('a', addr >> 16, addr >> 8, addr); } void @@ -84,6 +83,7 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) /* May be unused. */ uint32_t addr = v8_to_v32 (0, args[0], args[1], args[2]); uint8_t buf[16]; + uint8_t error = 0; #define c(cmd, size) (cmd << 8 | size) switch (c (cmd, size)) { @@ -95,10 +95,10 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) /* Erase full */ flash_erase (FLASH_ERASE_FULL, 0); break; - case c ('e', 3): - /* Erase 4k: - * - 3b: address. */ - flash_erase (FLASH_ERASE_4K, addr); + case c ('e', 4): + /* Erase the flash from the address addr and with the hexa code to + * erase.*/ + flash_erase (args[3], addr); break; case c ('i', 0): /* Initialise the trace module. */ @@ -107,14 +107,6 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) addr = trace_addr_current (); proto_send3b ('a', addr >> 16, addr >> 8, addr); break; - case c ('d', 0): - /* Dump full memory. */ - flash_dump_full (); - break; - case c ('d', 3): - /* Dump a full sector. */ - flash_dump_sector (addr); - break; case c ('t', 2): /* Trace data: * - 1b: id. @@ -131,20 +123,32 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) * - 3b: address. * - 1b: number of bytes. */ if (args[3] > sizeof (buf)) - { - proto_send0 ('?'); - return; - } + { + proto_send0 ('?'); + return; + } else { flash_read_array (addr, buf, args[3]); proto_send ('r', args[3], buf); } break; + case c ('f', 0): + /* Flood the memory with 3 sectors. + */ + flood (); + break; default: - /* Error */ - proto_send0 ('?'); - return; + if (cmd == 'l') + { + error = flash_log (size, args); + } + else if (error || (cmd != 'l')) + { + /* Error */ + proto_send0 ('?'); + return; + } } /* Acknowledge what has been done */ proto_send (cmd, size, args); diff --git a/digital/avr/modules/trace/trace.c b/digital/avr/modules/trace/trace.c index e904c2fa..37288ee1 100644 --- a/digital/avr/modules/trace/trace.c +++ b/digital/avr/modules/trace/trace.c @@ -23,51 +23,33 @@ * * }}} */ #include "common.h" +#include "modules/utils/utils.h" #include "modules/utils/byte.h" +#include "modules/proto/proto.h" #include "modules/flash/flash.h" #include "trace.h" -#define TRACE_CODE_START FLASH_LOG_CODE - #define TRACE_ARGS_MAX 6 #define TRACE_MAX_ARGS (TRACE_ARGS_MAX * TRACE_ARGS_MAX) +#define TRACE_BLOCK_SIZE_BYTES 65536 +#define TRACE_PAGE 0x80000 +#define TRACE_PAGE_BLOCKS (TRACE_PAGE / TRACE_BLOCK_SIZE_BYTES) +#define TRACE_PAGE_PAGE_NB (FLASH_SIZE / TRACE_PAGE) + struct trace_t { - /** Flash status. */ +/** Flash status. */ trace_status_t status; /** Flash start address */ const uint32_t addr_start; /** Flash address. */ uint32_t addr; - /** Flash next sector */ - uint32_t next_sector; }; typedef struct trace_t trace_t; static trace_t trace_global; -/** Erase the next sector on the Flash memory. - */ -static void -trace_erase_next_sector (void) -{ - /* If the flash is enable and the start sector is not reached yet erase - * the sector. */ - if (trace_global.status - && (flash_read (trace_global.next_sector) != 0xFF)) - { - if (trace_global.next_sector != trace_global.addr_start) - { - /* Flash page size is equal to 4k. */ - flash_erase (FLASH_ERASE_4K, trace_global.next_sector); - } - else - /* Disable the flash. */ - trace_global.status = TRACE_STATUS_OFF; - } -} - void trace_print_arg_1(uint8_t arg) { @@ -90,31 +72,62 @@ trace_print_arg_4(uint32_t arg) trace_print (arg); } +static inline void +trace_erase_page (uint32_t addr) +{ + uint8_t i; + while (flash_is_busy ()); + for (i = 0; i < TRACE_PAGE_BLOCKS; i++) + { + flash_erase (FLASH_ERASE_64K, addr); + addr += TRACE_BLOCK_SIZE_BYTES; + } +} uint8_t trace_init (void) { int8_t i; + uint8_t new_trace_val = 0x0; + uint32_t new_trace_addr = 0; + trace_global.status = flash_init (); /* Get the first sector to write. */ if (trace_global.status) { - trace_global.addr = flash_first_sector(); - *((uint32_t *) &trace_global.addr_start) = - FLASH_PAGE(trace_global.addr); - trace_global.next_sector = - FLASH_PAGE (trace_global.addr + FLASH_PAGE_SIZE); - - /* If the next sector is the first one in the memory erase it. */ - trace_erase_next_sector (); + uint8_t val = 0; + /* Find the possible traces. */ + for (i = 0; i < TRACE_PAGE_PAGE_NB; i++) + { + val = flash_read (i * TRACE_PAGE); + if (lesseq_mod8(new_trace_val, val)) + { + proto_send0 ('e'); + new_trace_val = val; + new_trace_addr = i * TRACE_PAGE; + } + } + new_trace_addr &= FLASH_ADDRESS_HIGH; - /* Store the start code. */ - for (i = 4; i; i--) + /* Flash not empty */ + if (!((new_trace_val == 0x0) && (new_trace_addr == 0))) { - flash_write (trace_global.addr, v32_to_v8(TRACE_CODE_START, i-1)); - trace_global.addr = FLASH_ADDRESS_INC(trace_global.addr); + proto_send0 ('h'); + new_trace_addr = (new_trace_addr + TRACE_PAGE) + & FLASH_ADDRESS_HIGH; + + /* Erase it. */ + trace_erase_page (new_trace_addr); } + new_trace_val ++; + proto_send1b ('v', new_trace_val); + *((uint32_t*) &trace_global.addr_start) = new_trace_addr; + + /* Store the trace val. */ + flash_write (new_trace_addr, new_trace_val); + trace_global.addr = new_trace_addr + 1; + return TRACE_STATUS_ON; } return TRACE_STATUS_OFF; @@ -126,16 +139,11 @@ trace_print (uint8_t arg) /* Store the arg on flash */ if (trace_global.status) { - uint32_t curr_sector; flash_write (trace_global.addr, arg); - trace_global.addr = FLASH_ADDRESS_INC(trace_global.addr); - - /* Compute the next sector address. */ - curr_sector = trace_global.next_sector; - trace_global.next_sector = FLASH_PAGE (trace_global.addr + - FLASH_PAGE_SIZE); - if (curr_sector != trace_global.next_sector) - trace_erase_next_sector (); + trace_global.addr ++; + + if (trace_global.addr == (trace_global.addr_start + TRACE_PAGE)) + trace_global.status = TRACE_STATUS_OFF; } } diff --git a/digital/avr/modules/utils/utils.h b/digital/avr/modules/utils/utils.h index e4e4c10b..a54ee4ed 100644 --- a/digital/avr/modules/utils/utils.h +++ b/digital/avr/modules/utils/utils.h @@ -79,4 +79,10 @@ utils_delay_ms (double ms) /** Count the number of element in an array. */ #define UTILS_COUNT(a) (sizeof (a) / sizeof ((a)[0])) +static inline uint8_t +lesseq_mod8 (uint8_t a, uint8_t b) +{ + return ((int8_t) (a - b)) <= 0; +} + #endif /* utils_h */ diff --git a/tools/trace/tinter/thost.py b/tools/trace/tinter/thost.py index bbbdf0d0..885fbbb3 100644 --- a/tools/trace/tinter/thost.py +++ b/tools/trace/tinter/thost.py @@ -1,9 +1,11 @@ import serial import time +import sys from proto import * from utils import * FLASH_MEMORY_HIGH = 0x1fffff +FLASH_PAGE = 0x80000 FLASH_BUFFER_SIZE = 128 FLASH_CMD_INIT = 0 FLASH_CMD_READ = 1 @@ -19,54 +21,59 @@ class THost: def __init__(self): self.__proto = Proto (serial.Serial ('/dev/ttyACM0'), time.time, 0.1) self.__memory = list() - self.__status = False - self.__addr_init = 0 - self.__addr_end = 0 + self.__traces = [] def __dump_callback (self, *memory): """Callback call on each data reception""" for i in range(len (memory)): self.__memory.append (memory[i]) + sys.stderr.write (".") - def __flash_status (self, status): - """Get the flash status.""" - print "Flash activate : ", status - self.__status = status + def __trace_present (self, val): + """Get the trace value and the first byte following.""" + self.__traces.append (val) - def __flash_log_init (self, *addr): - """Get the flash log start address.""" - # Don't request the code start - addr = reverse_tupple (addr) - self.__addr_init = get_size (addr, 3) + def trace_list (self): + """Read the flash memory and return the addresses of the traces + present with the trace value in a array.""" + self.__proto.register ('r', 'B', self.__trace_present) + self.__proto.send ('l', 'b', FLASH_CMD_INIT) + self.__proto.send ('l', 4*'b', FLASH_CMD_READ, 0x0, 0x0, 0x0) + self.__proto.send ('l', 4*'b', FLASH_CMD_READ, 0x8, 0x0, 0x0) + self.__proto.send ('l', 4*'b', FLASH_CMD_READ, 0x10, 0x0, 0x0) + self.__proto.send ('l', 4*'b', FLASH_CMD_READ, 0x18, 0x0, 0x0) + self.__proto.wait (lambda: True) - def __flash_log_end (self, *addr): - """Get the flash log end address.""" - addr = reverse_tupple (addr) - self.__addr_end = get_size (addr, 3) + return self.__traces - def dump_memory(self): + def dump_memory(self, val): """Dump the flash memory.""" # Initialise the flash access. - self.__proto.register ('r', FLASH_BUFFER_SIZE * 'B', self.__dump_callback) - self.__proto.register ('s', 'b', self.__flash_status) - self.__proto.register ('i', 3*'B', self.__flash_log_init) - self.__proto.register ('e', 3*'B', self.__flash_log_end) - print "Callback registered" - print "Initialise the Flash memory" - self.__proto.send ('l', 'b', FLASH_CMD_INIT) - self.__proto.wait (lambda: True) + self.__proto.register ('r', FLASH_BUFFER_SIZE * 'B', + self.__dump_callback) + self.__proto.register ('r', 'B', self.__trace_present) - if self.__status == True: - print "Dumping from " + str (self.__addr_init) + " to " + str (self.__addr_end) - - i = self.__addr_init - while i != self.__addr_end: - self.__proto.send ('l', 'bI', FLASH_CMD_READ, (i << 8) | FLASH_BUFFER_SIZE) - i = flash_memory_addr (i + FLASH_BUFFER_SIZE) + i = 0 + self.__traces.append (0x100) + while self.__traces[0] != val and i < FLASH_MEMORY_HIGH: + self.__traces = [] + addr = i >> 16 + self.__proto.send ('l', 4*'b', FLASH_CMD_READ, addr, 0, 0) self.__proto.wait (lambda: True) - else: - self.__memory = None + i += FLASH_PAGE + i -= FLASH_PAGE + + start_addr = i + end_addr = start_addr + FLASH_PAGE + print "Dump memory from address : " + hex(start_addr) + " to " + \ + hex(end_addr) + + for i in range (start_addr, end_addr, FLASH_BUFFER_SIZE): + self.__proto.send ('l', 'bI', FLASH_CMD_READ, (i << 8) | \ + FLASH_BUFFER_SIZE) + self.__proto.wait (lambda: True) + sys.stderr.write ("\nDump ended\n") def get_trace (self): """Return the traces dumped from the flash memory.""" - return reverse_tupple (self.__memory[4:len (self.__memory)]) + return self.__memory[1:] diff --git a/tools/trace/tinter/tinter.py b/tools/trace/tinter/tinter.py index 28197fd2..855f97da 100644 --- a/tools/trace/tinter/tinter.py +++ b/tools/trace/tinter/tinter.py @@ -25,6 +25,7 @@ class TInter: def __event_print (self, events, memory): if len(memory) > 0: cmd = get_size (memory, 2) + memory = memory[2:] if cmd < len(events): e = events[cmd] string = e.string_get() @@ -32,6 +33,7 @@ class TInter: p = e.param_get(i) size = p.length() val = get_size (memory, size) + memory = memory[size:] string = string.replace('%d', str(val), 1) if self.__file == None: @@ -43,12 +45,13 @@ class TInter: else: return None - def trace_print (self): - events = self.__events_get () + def __dump (self, val): + print "Dump trace ", val host = THost() - host.dump_memory() + host.dump_memory (val) memory = host.get_trace () + events = self.__events_get () if self.__outfile != None: self.__file = open (self.__outfile, 'w') self.__file.write ('APBTeam v1.0 Log interpretor\n') @@ -58,3 +61,25 @@ class TInter: if self.__file != None: self.__file.close () + + def available_traces (self): + host = THost() + traces = host.trace_list() + print "Traces available " + for i in traces: + print i + + def trace_print (self, trace_num = None): + events = self.__events_get () + host = THost() + + if trace_num: + traces = host.trace_list() + if traces.count (trace_num) >= 1: + self.__dump (trace_num) + else: + print "Trace not available." + else: + traces = host.trace_list() + val = max(traces) + self.__dump (val) diff --git a/tools/trace/tinter/utils.py b/tools/trace/tinter/utils.py index dd01eb5c..ee75559a 100644 --- a/tools/trace/tinter/utils.py +++ b/tools/trace/tinter/utils.py @@ -1,15 +1,10 @@ def get_size (mem, size): + table = mem[0:size] if size == 1: - return mem.pop() + return table[0] elif size == 2: - return ((mem.pop() << 8) | mem.pop()) + return ((table[0] << 8) | table[1]) elif size == 3: - return ((mem.pop() << 16) | (mem.pop() << 8) | mem.pop()) + return ((table[0] << 16) | (table[1] << 8) | table[2]) elif size == 4: - return ((mem.pop() << 24) | (mem.pop() << 16) | (mem.pop() << 8) | mem.pop()) - -def reverse_tupple (tupple): - mem = [] - for i in tupple: - mem = [i] + mem - return mem + return ((table[0] << 24) | (table[1] << 16) | (table[2] << 8) | table[3]) diff --git a/tools/trace/trace.py b/tools/trace/trace.py index 6850a4cd..b41ef9ef 100644 --- a/tools/trace/trace.py +++ b/tools/trace/trace.py @@ -17,6 +17,10 @@ parser.add_option("-i", "--infile", dest="infile", help="Read the data from the file") parser.add_option("-t", "--type", dest="type", help="create to create the enumeration, inter to read the log from the flash.") +parser.add_option("-l", "--list", dest="list_trace", action="store_true", + help="List the number of the traces.") +parser.add_option("-n", "--num", type="int", dest="trace", + help="Dump the trace num provided, only used in inter mode.") [options, args] = parser.parse_args() @@ -25,6 +29,11 @@ if options.type == 'create': cre.create () elif options.type == "inter": inter = TInter (options.infile, options.outfile) - inter.trace_print() + if options.list_trace: + inter.available_traces () + elif options.trace: + inter.trace_print (options.trace) + else: + inter.trace_print() else: print "see the help\n python trace --help" -- cgit v1.2.3