origen_memory_image 0.6.0 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: caf8c439a35b5f220e8274b6626673ee7525271a
4
- data.tar.gz: ec7fbf5149451f4ec2f92f4f9e9cbb4757ffd897
2
+ SHA256:
3
+ metadata.gz: 2d9b91a3a905b3801a9d96ee96fe7494baf3c201d1b3ee34107599923ff0763a
4
+ data.tar.gz: d66b83fcd77afac1ed13754871d9fab2952760f2ad5fc17b6709904ef6a48c6d
5
5
  SHA512:
6
- metadata.gz: 94959863f2afed01b3300650b793209631118c11fca988b89b30bdc162497974a53423c87c2538c84569448f98f1ed7ba77f198983c24b11e67f27fc5e0b929d
7
- data.tar.gz: feb360c36844b949e4463956ab81d69e5e0dfee76b094fee1acf149ef946cb27b3f0c79ec77748dc6003be23bbe918d7bb35fa77665a7e40a7c0eb528a7f2553
6
+ metadata.gz: f6fedde88b97b4661fb9773d6780497ba995f07114661ba3c94b5ca842c818dc59592e40758c387ce7f8361b1cf68977c40aba88c0a864a3a3ab751a9a118e0b
7
+ data.tar.gz: 7a712d8374d57ae31dd11454cc7985084988ca90e3d883205b3738bc1ac48c2e45bb89054c6a9a816efd1b57096e17220da099508a634eb915af9760a7114a8d
data/config/version.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  module OrigenMemoryImage
2
2
  MAJOR = 0
3
- MINOR = 6
4
- BUGFIX = 0
3
+ MINOR = 8
4
+ BUGFIX = 2
5
5
  DEV = nil
6
-
7
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
7
  end
@@ -6,6 +6,7 @@ module OrigenMemoryImage
6
6
  autoload :SRecord, 'origen_memory_image/s_record'
7
7
  autoload :Hex, 'origen_memory_image/hex'
8
8
  autoload :Binary, 'origen_memory_image/binary'
9
+ autoload :IntelHex, 'origen_memory_image/intel_hex'
9
10
 
10
11
  def self.new(file, options = {})
11
12
  unless options[:source] == String
@@ -20,7 +21,7 @@ module OrigenMemoryImage
20
21
  if options[:source] == String
21
22
  snippet = file.split("\n")
22
23
  else
23
- snippet = File.foreach(file.to_s).first(1)
24
+ snippet = File.foreach(file.to_s).first(10)
24
25
  end
25
26
  case
26
27
  # Always do the binary first since the others won't be able to process
@@ -31,6 +32,8 @@ module OrigenMemoryImage
31
32
  Binary
32
33
  when options[:type] == :srecord || SRecord.match?(snippet)
33
34
  SRecord
35
+ when options[:type] == :intel_hex || IntelHex.match?(snippet)
36
+ IntelHex
34
37
  when options[:type] == :hex || Hex.match?(snippet)
35
38
  Hex
36
39
  else
@@ -8,6 +8,7 @@ module OrigenMemoryImage
8
8
  else
9
9
  @file = file
10
10
  end
11
+ @ljust_partial_data = options[:ljust_partial_data]
11
12
  end
12
13
 
13
14
  # Returns the code execution start address as an int
@@ -15,6 +16,13 @@ module OrigenMemoryImage
15
16
  fail "#{self.class} has not implemented the start_address method!"
16
17
  end
17
18
 
19
+ # Returns true if a start (jump address) record exists
20
+ def has_start_record
21
+ start_address unless @start_address
22
+ @start_record_found = false if @start_record_found.nil?
23
+ @start_record_found
24
+ end
25
+
18
26
  # Returns the s-record as an array of addresses and data
19
27
  #
20
28
  # @param [hash] options, allows the selection of endianness swapping - ie the output will have the endianness changed
@@ -50,7 +58,7 @@ module OrigenMemoryImage
50
58
 
51
59
  if options[:flip_endianness] || options[:endianness_change]
52
60
  data.map do |v|
53
- [v[0], flip_endianness(v[1], 4)]
61
+ [v[0], flip_endianness(v[1], options[:data_width_in_bytes])]
54
62
  end
55
63
  else
56
64
  data
@@ -1,12 +1,12 @@
1
- require 'ptools'
2
-
3
1
  module OrigenMemoryImage
4
2
  class Binary < Base
5
3
  def self.match?(file, snippet = false)
6
4
  if snippet
7
5
  file.all? { |l| l.strip =~ /^[01]*$/ }
8
6
  else
9
- File.binary?(file)
7
+ # detect whether the data is mostly not alpha numeric
8
+ filedata = (File.read(file, 256) || '')
9
+ (filedata.gsub(/\s+/, '').gsub(/\w/, '').length.to_f / filedata.length.to_f) > 0.3
10
10
  end
11
11
  end
12
12
 
@@ -46,7 +46,11 @@ module OrigenMemoryImage
46
46
  end
47
47
  # If a partial word is left over
48
48
  if (remainder = data.length % (2 * options[:data_width_in_bytes])) > 0
49
- result << [@address, data[data.length - remainder..data.length].to_i(16)]
49
+ if @ljust_partial_data
50
+ result << [@address, data[data.length - remainder..data.length].ljust(options[:data_width_in_bytes] * 2, '0').to_i(16)]
51
+ else
52
+ result << [@address, data[data.length - remainder..data.length].to_i(16)]
53
+ end
50
54
  end
51
55
  end
52
56
  end
@@ -0,0 +1,98 @@
1
+ module OrigenMemoryImage
2
+ class IntelHex < Base
3
+ def self.match?(snippet)
4
+ snippet.all? do |line|
5
+ line.empty? || line =~ /^:[0-9A-Fa-f]{6}0[0-5]/
6
+ end
7
+ end
8
+
9
+ def start_address
10
+ @start_address ||= begin
11
+ addrs = []
12
+ lines.each do |line|
13
+ line = line.strip
14
+ if start_linear_address?(line)
15
+ addrs << decode(line)[:data].to_i(16)
16
+ end
17
+ end
18
+ addrs.last || 0
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def decode(line)
25
+ d = {}
26
+ if line =~ /^:([0-9A-Fa-f]{2})([0-9A-Fa-f]{4})(\d\d)([0-9A-Fa-f]+)([0-9A-Fa-f]{2})$/
27
+ d[:byte_count] = Regexp.last_match(1).to_i(16)
28
+ d[:address] = Regexp.last_match(2).to_i(16)
29
+ d[:record_type] = Regexp.last_match(3).to_i(16)
30
+ d[:data] = Regexp.last_match(4)
31
+ d[:checksum] = Regexp.last_match(5).to_i(16)
32
+ else
33
+ fail "Invalid line encountered in Intel Hex formatted file: #{line}"
34
+ end
35
+ d
36
+ end
37
+
38
+ def data?(line)
39
+ !!(line =~ /^:[0-9A-Fa-f]{6}00/)
40
+ end
41
+
42
+ def extended_segment_address?(line)
43
+ !!(line =~ /^:[0-9A-Fa-f]{6}02/)
44
+ end
45
+
46
+ def extended_linear_address?(line)
47
+ !!(line =~ /^:[0-9A-Fa-f]{6}04/)
48
+ end
49
+
50
+ def start_linear_address?(line)
51
+ !!(line =~ /^:[0-9A-Fa-f]{6}05/)
52
+ end
53
+
54
+ def upper_addr
55
+ @upper_addr || 0
56
+ end
57
+
58
+ def segment_address
59
+ @segment_address || 0
60
+ end
61
+
62
+ # Returns an array containing all address/data from the given s-record
63
+ # No address manipulation is performed, that is left to the caller to apply
64
+ # any scrambling as required by the target system
65
+ def extract_addr_data(options = {})
66
+ options = {
67
+ data_width_in_bytes: 4
68
+ }.merge(options)
69
+
70
+ result = []
71
+ lines.each do |line|
72
+ line = line.strip
73
+ if extended_segment_address?(line)
74
+ @segment_address = decode(line)[:data].to_i(16) * 16
75
+
76
+ elsif extended_linear_address?(line)
77
+ @upper_addr = (decode(line)[:data].to_i(16)) << 16
78
+
79
+ elsif data?(line)
80
+ d = decode(line)
81
+ addr = d[:address] + segment_address + upper_addr
82
+
83
+ data = d[:data]
84
+ data_matcher = '\w\w' * options[:data_width_in_bytes]
85
+ data.scan(/#{data_matcher}/).each do |data_packet|
86
+ result << [addr, data_packet.to_i(16)]
87
+ addr += options[:data_width_in_bytes]
88
+ end
89
+ # If a partial word is left over
90
+ if (remainder = data.length % (2 * options[:data_width_in_bytes])) > 0
91
+ result << [addr, data[data.length - remainder..data.length].to_i(16)]
92
+ end
93
+ end
94
+ end
95
+ result
96
+ end
97
+ end
98
+ end
@@ -156,9 +156,16 @@ module OrigenMemoryImage
156
156
  end
157
157
 
158
158
  def start_address
159
+ if @call_order_warn
160
+ Origen.log.warn 'Previously srec.start_address returned the lowest address when to_a was called first. Now the start record is always returned if present.'
161
+ @call_order_warn = false
162
+ end
163
+
164
+ lowest_address = nil
159
165
  @start_address ||= begin
160
166
  lines.each do |line|
161
167
  if line =~ /^S([789])(.*)/
168
+ @start_record_found = true
162
169
  type = Regexp.last_match[1]
163
170
  case type
164
171
  when '7'
@@ -169,7 +176,19 @@ module OrigenMemoryImage
169
176
  return line.slice(4, 4).to_i(16)
170
177
  end
171
178
  end
179
+ if line =~ /^S([1-3])/
180
+ type = Regexp.last_match[1].to_i(16) # S-record type, 1-3
181
+ # Set the matcher to capture x number of bytes dependent on the s-rec type
182
+ addr_matcher = '\w\w' * (1 + type)
183
+ line.strip =~ /^S\d\w\w(#{addr_matcher})(\w*)\w\w$/ # $1 = address, $2 = data
184
+ addr = Regexp.last_match[1].to_i(16)
185
+ lowest_address ||= addr
186
+ lowest_address = addr if addr < lowest_address
187
+ end
172
188
  end
189
+ # if no start_address record is found, return lowest address
190
+ @start_record_found = false
191
+ lowest_address
173
192
  end
174
193
  end
175
194
 
@@ -183,6 +202,12 @@ module OrigenMemoryImage
183
202
  data_width_in_bytes: 4
184
203
  }.merge(options)
185
204
 
205
+ # guarantee that the start_address will be the jump address if provided
206
+ if @start_address.nil?
207
+ start_address
208
+ @call_order_warn = @start_record_found ? true : false
209
+ end
210
+
186
211
  result = []
187
212
  lines.each do |line|
188
213
  # Only if the line is an s-record with data...
@@ -192,8 +217,6 @@ module OrigenMemoryImage
192
217
  addr_matcher = '\w\w' * (1 + type)
193
218
  line.strip =~ /^S\d\w\w(#{addr_matcher})(\w*)\w\w$/ # $1 = address, $2 = data
194
219
  addr = Regexp.last_match[1].to_i(16)
195
- @start_address ||= addr
196
- @start_address = addr if addr < @start_address
197
220
  data = Regexp.last_match[2]
198
221
  data_matcher = '\w\w' * options[:data_width_in_bytes]
199
222
  data.scan(/#{data_matcher}/).each do |data_packet|
@@ -202,7 +225,11 @@ module OrigenMemoryImage
202
225
  end
203
226
  # If a partial word is left over
204
227
  if (remainder = data.length % (2 * options[:data_width_in_bytes])) > 0
205
- result << [addr, data[data.length - remainder..data.length].to_i(16)]
228
+ if @ljust_partial_data
229
+ result << [addr, data[data.length - remainder..data.length].ljust(options[:data_width_in_bytes] * 2, '0').to_i(16)]
230
+ else
231
+ result << [addr, data[data.length - remainder..data.length].to_i(16)]
232
+ end
206
233
  end
207
234
  end
208
235
  end
@@ -58,6 +58,25 @@ my_srec = OrigenMemoryImage.new("source_files/test_atd.abs.S19")
58
58
  my_hex = OrigenMemoryImage.new("source_files/math.hex")
59
59
  ~~~
60
60
 
61
+ By default any partial data words are right justified. Change this behavior to left justified like this:
62
+
63
+ ~~~ruby
64
+ my_srec = OrigenMemoryImage.new("source_files/test_atd.abs.S19", ljust_partial_data: true)
65
+ my_hex = OrigenMemoryImage.new("source_files/math.hex", ljust_partial_data: true)
66
+ ~~~
67
+
68
+ Partial data example:
69
+
70
+ ~~~
71
+ 0304FE
72
+
73
+ # Default interpretation into 32-bit word:
74
+ 0x0003_04FE
75
+
76
+ # Left justified interpretation into 32-bit word:
77
+ 0x0304_FE00
78
+ ~~~
79
+
61
80
  Memory images can also be created directly from a string:
62
81
 
63
82
  ~~~ruby
@@ -72,10 +91,14 @@ my_hex = OrigenMemoryImage.new(str, source: String)
72
91
 
73
92
  Every memory image object then supports a common API.
74
93
 
75
- The <code>start_address</code> method returns the start (execution start) address:
94
+ The <code>start_address</code> method returns the start (execution start) address. If the memory image
95
+ contains an indication of the execution start address that record value will be returned. If there is
96
+ no start address record, the lowest address will be returned. The <code>has_start_record</code> method
97
+ indicates whether a start address record was found:
76
98
 
77
99
  ~~~ruby
78
- my_srec.start_address # => 0x3000_F000
100
+ my_srec.start_address # => 0x3000_F000
101
+ my_srec.has_start_record # => true
79
102
  ~~~
80
103
 
81
104
  The <code>to_a</code> method returns the file content as an array of address/data pairs,
@@ -146,6 +169,21 @@ A binary file:
146
169
  00000100000000110000010100000110
147
170
  ~~~
148
171
 
172
+ #### Intel Hex
173
+
174
+ Any valid Intel Hex file:
175
+
176
+ ~~~text
177
+ :020000040022D8
178
+ :10010000214601360121470136007EFE09D2190140
179
+ :100110002146017E17C20001FF5F16002148011928
180
+ :020000040023D7
181
+ :10012000194E79234623965778239EDA3F01B2CAA7
182
+ :100130003F0156702B5E712B722B732146013421C7
183
+ :0400000500000000F7
184
+ :00000001FF
185
+ ~~~
186
+
149
187
  ### How To Setup a Development Environment
150
188
 
151
189
  [Clone the repository from Github](https://github.com/Origen-SDK/origen_memory_image).
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen_memory_image
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-20 00:00:00.000000000 Z
11
+ date: 2021-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.2.2
27
- - !ruby/object:Gem::Dependency
28
- name: ptools
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: origen_doc_helpers
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -67,6 +53,7 @@ files:
67
53
  - lib/origen_memory_image/base.rb
68
54
  - lib/origen_memory_image/binary.rb
69
55
  - lib/origen_memory_image/hex.rb
56
+ - lib/origen_memory_image/intel_hex.rb
70
57
  - lib/origen_memory_image/s_record.rb
71
58
  - templates/web/index.md.erb
72
59
  - templates/web/layouts/_basic.html.erb
@@ -90,8 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
77
  - !ruby/object:Gem::Version
91
78
  version: 1.8.11
92
79
  requirements: []
93
- rubyforge_project:
94
- rubygems_version: 2.6.7
80
+ rubygems_version: 3.1.4
95
81
  signing_key:
96
82
  specification_version: 4
97
83
  summary: Provides a standard API for consuming memory image files in any format e.g.