Root/lm32/logic/sakc/tools/uploader/upload

1#!/usr/bin/env ruby
2
3require "serialport.so"
4require "optparse"
5
6port_baud = 115200
7port_path = "/dev/ttyUSB0"
8terminal_mode = false
9verbose = false
10check = false
11
12#############################################################################
13# Extend SerialPort class with bootloader communication
14class SerialPort
15    BOOT_SIG = "**soc-lm32/bootloader**"
16
17    def put_uint32(i)
18        putc( (i >> 24) & 0xff )
19        putc( (i >> 16) & 0xff )
20        putc( (i >> 8) & 0xff )
21        putc( (i >> 0) & 0xff )
22    end
23
24    def download(addr, size)
25        a = Array.new(size)
26        putc 'd'
27        put_uint32 addr
28        put_uint32 size
29        size.times do |i|
30            a[i] = getc
31        end
32        return a
33    end
34
35    def upload(addr, data)
36        putc 'u'
37        put_uint32 addr
38        put_uint32 data.length
39        data.each do |c|
40            putc c
41        end
42    end
43
44    def find_bootloader(max_tries = 32)
45        old_timeout = read_timeout
46        read_timeout = 500
47        count = 0;
48        begin
49            count = count + 1
50            if (count == max_tries) then
51                raise "Bootloader (#{BOOT_SIG}) not not found"
52            end
53            putc '\r'
54            l = gets
55        end while l.nil? or not l.index( BOOT_SIG )
56        read_timeout = old_timeout
57    end
58end
59
60#############################################################################
61# Main
62
63opts = OptionParser.new do |o|
64    o.banner = "Usage: upload [options] <file.srec>"
65
66    o.on( "-b", "--baud BAUDRATE", Integer,
67            "Serial port baudrate (default: #{port_baud})" ) do |baud|
68        port_baud = baud
69    end
70
71    o.on( "-s", "--serial SERIALPORT",
72             "Path to serial port (default: #{port_path})" ) do |port|
73        port_path = port
74    end
75
76    o.on( "-v", "--verbose",
77            "Be verbose and show serial I/O" ) do
78        verbose = true
79    end
80
81    o.on( "-t", "--terminal",
82            "Switch to terminal mode after upload" ) do
83        terminal_mode = true
84    end
85
86    o.on( "-c", "--check",
87            "Check RAM after upload and verify everything is correct" ) do
88        check = true
89    end
90
91    o.on_tail( "-h", "--help", "Display this help message" ) do
92        puts o
93        exit 0
94    end
95end
96
97# Check arguments, open serial port and file
98begin
99    opts.parse!(ARGV)
100
101    raise "SREC file argument missing" if ARGV.length != 1;
102
103    file_path = ARGV[0]
104
105    uploadFile = File.open( file_path, "r" )
106    raise "Could not SREC file." if not uploadFile;
107
108    fileSize = File.size( file_path )
109
110    port = SerialPort.new(port_path, port_baud, 8, 1, SerialPort::NONE)
111    raise "Could not open serial port." if not port;
112
113rescue => e
114    STDERR.puts "\nERROR: #{e.message}"
115    STDERR.puts
116    STDERR.puts opts
117    STDERR.puts
118    exit 1
119end
120
121begin
122    STDOUT.sync = true
123
124    print "Looking for soc-lm32 bootloader..."
125    port.find_bootloader
126    puts "found."
127    
128    data = Array.new(0x2000).map do |e| e = 0x23 end
129    port.upload(0x40000000, data );
130
131# ist_data = port.download(0x40000000, 0x2000)
132#p ist_data
133
134    # read SREC file
135    startAddress = nil
136
137    print "Uploading SREC file..."
138    uploadFile.each_line do |line|
139        line.chomp!
140        if line[0..1] == "S7" then
141            startAddress = line[4..11].hex
142        end
143        if line[0..1] == "S3" then
144            count = line[2..3].hex
145            addr = line[4..11].hex
146            dat = line[12..-3]
147            cksum = line[-2..-1].hex
148            
149            count = count - 5
150            data = Array.new( count )
151            count.times do |i|
152                data[i] = ( dat[ (2*i) .. (2*i+1) ] ).hex
153            end
154            port.upload(addr, data)
155            if verbose then
156                print " [0x%08x] " % addr
157                data.each do |e| print " %02x" % e; end
158                puts
159            else
160                print "."
161            end
162        end
163    end
164    puts "done."
165    
166    if check then
167        print "verifieing RAM content..."
168        uploadFile.seek(0)
169
170        uploadFile.each_line do |line|
171            printf "."
172            line.chomp!
173            if line[0..1] == "S3" then
174                count = line[2..3].hex
175                addr = line[4..11].hex
176                dat = line[12..-3]
177                chsum = line[-2..-1].hex
178                
179                count = count/2 - 1
180                soll_data = Array.new( count )
181                count.times do |i|
182                    soll_data[i] = ( dat[ (2*i) .. (2*i+1) ] ).hex
183                end
184                ist_data = port.download(addr, count)
185
186                count.times do |i|
187                    if soll_data[i] != ist_data[i] then
188                        puts "0x%08x: 0x%02x <-> 0x%02x" % [addr+i, soll_data[i], ist_data[i]]
189                    end
190                end
191
192            end
193        end
194        puts "done."
195    end
196
197    if not startAddress.nil? then
198        puts "Jumping to start address 0x%08x." % startAddress
199        port.putc 'g'
200        port.put_uint32 startAddress
201    end
202
203
204    if terminal_mode
205        puts "------ entering terminal mode ------"
206        while true do
207            a = select( [port, STDIN], nil, nil );
208
209            STDOUT.putc(port.getc) if a[0].include?( port )
210            port.putc(STDIN.getc) if a[0].include?( STDIN )
211        end
212    end
213   
214ensure
215    uploadFile.close unless uploadFile.nil?
216    port.close unless port.nil?
217end
218

Archive Download this file

Branches:
master



interactive