Skip to content

Instantly share code, notes, and snippets.

@legumbre
Created November 21, 2012 18:13
Show Gist options
  • Save legumbre/4126611 to your computer and use it in GitHub Desktop.
Save legumbre/4126611 to your computer and use it in GitHub Desktop.
i2c logger helper functions
#
# postprocesador de i2c logger
#
# funciones:
# parse_i2c_log_messages {bytes}
# pretty_print_i2c_log {messages filename}
#
# (ver ejemplo de uso al final)
# parse_i2c_log_messages {bytes}
# acepta una lista de bytes y devuelve una lista de diccionarios que almacenan la informacion de cada transferencia.
# las claves usadas para los diccionarios son 'address', 'data_length', 'data'
#
# Asume que la lista de bytes tiene la forma:
#
# |address|data_length|data0|data1|data2|...|dataN|timestart_hi|timestart_lo|imesend_hi|timend_lo|....
#
#
proc parse_i2c_log_messages {bytes} {
set messages {}; # lista donde se van a almacenar los diccionarios con los datos de cada mensaje
set byte_idx 0; # contador de posicion de byte (indice de la lista "bytes")
while {$byte_idx < [llength $bytes]} {
set message_start_idx $byte_idx; # posicion en la lista de bytes donde comienza un nuevo mensaje
set current_address [lindex $bytes $message_start_idx+0]
set current_data_length [lindex $bytes $message_start_idx+1]
set first_data_byte_idx [expr $message_start_idx+2]
set last_data_byte_idx [expr $first_data_byte_idx + $current_data_length]
set current_data [lrange $bytes $first_data_byte_idx $last_data_byte_idx-1]
# ya parseado el mensaje actual, armo el diccionario current_message con los campos de cada transferencia
# las claves del diccionario son 'address', 'data_length', 'data', etc.
set current_message [dict create]
dict set current_message address $current_address
dict set current_message data_length $current_data_length
dict set current_message data $current_data
# messages es entonces una lista donde cada elemento es un array asociativo con los datos de cada mensaje
lappend messages $current_message
# finalmente, actualizar contador de posicion de byte
set offset [expr 1 + 1 + $current_data_length + 2 + 2]; # address(1) + ndata(1) + ndata + tstart(2) + tend(2)
# puts "offset: $offset"
incr byte_idx $offset; # byte_idx = byte_idx + offset
}
puts "done! processed $byte_idx out of [llength $bytes] bytes and parsed [llength $messages] messages."
return $messages
}
# acepta una lista de diccionarios 'messages" con mensajes de i2c log y los escribe en formato amigable al archivo 'filename'
proc pretty_print_i2c_log {messages filename} {
set fd [open $filename w]; # abrir file para escritura
foreach message $messages {
puts $fd [pp_message $message]
}
close $fd; # cerrar el file (flush)
}
# pp_message recibe un diccionario con los datos de un mensaje de i2c y devuelve un string formateado
proc pp_message {message} {
return "address: [dict get $message address]\tdata: [dict get $message data]\tlength: [format %d [dict get $message data_length]] bytes"
}
# fin
## ====== Datos y ejemplo de uso ===============
# address 50, 4 data bytes, data(4), tstart, tend
# address 40, 0 data bytes, tstart, tend
# address 30, 1 data bytes, data(1), tstart, tend
# normalmente esta lista se obtiene de una o varias llamada a master_read_8, estos son datos de ejemplo
set bytes [list 0x50 0x04 0x01 0x02 0x03 0x04 0xFF 0x00 0xFF 0x10 0x40 0x00 0xFF 0x10 0xFF 0x20 0x30 0x01 0x55 0xFF 0x20 0xFF 0x30]
# parseo la lista de bytes anterior y lo almaceno en la lista de mensajes parsed_messages
set parsed_messages [parse_i2c_log_messages $bytes]
# imprimir la lista en la consola, solo para debug
puts $parsed_messages
# finalmente se escriben los mensajes parseados a un archivo, en este caso /tmp/log.txt
pretty_print_i2c_log $parsed_messages /tmp/log.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment