origen_memory_image 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d364a5cedbccf382fae2a6bf7732604387fbdaf1
4
+ data.tar.gz: 87baaf7587ea2ee10562844104638ccc1bc46252
5
+ SHA512:
6
+ metadata.gz: d6873cb75247b6fbc0924706c982f6b0d7edf980b8137d791e48c7a3344336254f85b5e352a6ced1170c9b3a112614cc47a0375d6d9dcfdf0e3496cba3a7d218
7
+ data.tar.gz: c4afd730adea6589dce1bb53cf243283c39a66b6257681db1888c4e84274abdd3704453b74de010b647ba97b9acec4ef31d12d26041e9b1f10c952f606bbc1c8
@@ -0,0 +1,87 @@
1
+ class OrigenMemoryImageApplication < Origen::Application
2
+
3
+ # To share resources with the apps that import this plugin uncomment the following attribute:
4
+ #config.shared = {
5
+ # Add the dir/file of patterns that needs to be shared
6
+ # patterns: "pattern/shared",
7
+ # Add the file which includes all commands that needs the be shared with the app that imports
8
+ # this plugin in :command_launcher attribute
9
+ # command_launcher: "config/shared_commands.rb",
10
+ # Shared templates go in the :templates attribute
11
+ # templates: "templates/shared_templates",
12
+ # Shared programs go in the :programs attributes
13
+ # programs: "programs/shared"
14
+ #}
15
+
16
+ # This information is used in headers and email templates, set it specific
17
+ # to your application
18
+ config.name = "Origen Memory Image"
19
+ config.initials = "OrigenMemoryImage"
20
+ config.rc_url = "git@github.com:Origen-SDK/origen_memory_image.git"
21
+ config.release_externally = true
22
+
23
+ config.web_directory = "git@github.com:Origen-SDK/Origen-SDK.github.io.git/memory_image"
24
+ config.web_domain = "http://origen-sdk.org/memory_image"
25
+
26
+ # When false Origen will be less strict about checking for some common coding errors,
27
+ # it is recommended that you leave this to true for better feedback and easier debug.
28
+ # This will be the default setting in Origen v3.
29
+ config.strict_errors = true
30
+
31
+ # See: http://origen.freescale.net/origen/latest/guides/utilities/lint/
32
+ config.lint_test = {
33
+ # Require the lint tests to pass before allowing a release to proceed
34
+ run_on_tag: true,
35
+ # Auto correct violations where possible whenever 'origen lint' is run
36
+ auto_correct: true,
37
+ # Limit the testing for large legacy applications
38
+ #level: :easy,
39
+ # Run on these directories/files by default
40
+ #files: ["lib", "config/application.rb"],
41
+ }
42
+
43
+ config.semantically_version = true
44
+
45
+ # By default all generated output will end up in ./output.
46
+ # Here you can specify an alternative directory entirely, or make it dynamic such that
47
+ # the output ends up in a setup specific directory.
48
+ #config.output_directory do
49
+ # "#{Origen.root}/output/#{$dut.class}"
50
+ #end
51
+
52
+ # Similary for the reference files, generally you want to setup the reference directory
53
+ # structure to mirror that of your output directory structure.
54
+ #config.reference_directory do
55
+ # "#{Origen.root}/.ref/#{$dut.class}"
56
+ #end
57
+
58
+ # Run the tests before deploying to generate test coverage numbers
59
+ def before_deploy_site
60
+ Dir.chdir Origen.root do
61
+ #system "origen examples -c"
62
+ system "origen specs -c"
63
+ dir = "#{Origen.root}/web/output/coverage"
64
+ FileUtils.remove_dir(dir, true) if File.exists?(dir)
65
+ system "mv #{Origen.root}/coverage #{dir}"
66
+ end
67
+ end
68
+
69
+ # This will automatically deploy your documentation after every tag
70
+ def after_release_email(tag, note, type, selector, options)
71
+ command = "origen web compile --remote --api"
72
+ Dir.chdir Origen.root do
73
+ system command
74
+ end
75
+ end
76
+
77
+ # Ensure that all tests pass before allowing a release to continue
78
+ def validate_release
79
+ if !system("origen specs") #|| !system("origen examples")
80
+ puts "Sorry but you can't release with failing tests, please fix them and try again."
81
+ exit 1
82
+ else
83
+ puts "All tests passing, proceeding with release process!"
84
+ end
85
+ end
86
+
87
+ end
@@ -0,0 +1,107 @@
1
+ # This file should be used to extend the origen command line tool with tasks
2
+ # specific to your application.
3
+ # The comments below should help to get started and you can also refer to
4
+ # lib/origen/commands.rb in your Origen core workspace for more examples and
5
+ # inspiration.
6
+ #
7
+ # Also see the official docs on adding commands:
8
+ # http://origen.freescale.net/origen/latest/guides/custom/commands/
9
+
10
+ # Map any command aliases here, for example to allow origen -x to refer to a
11
+ # command called execute you would add a reference as shown below:
12
+ aliases ={
13
+ # "-x" => "execute",
14
+ }
15
+
16
+ # The requested command is passed in here as @command, this checks it against
17
+ # the above alias table and should not be removed.
18
+ @command = aliases[@command] || @command
19
+
20
+ # Smome helper methods to enable test coverage, these will eventually be
21
+ # added to Origen Core, but they need to be here for now
22
+ def path_to_coverage_report
23
+ require 'pathname'
24
+ Pathname.new("#{Origen.root}/coverage/index.html").relative_path_from(Pathname.pwd)
25
+ end
26
+
27
+ def enable_coverage(name, merge=true)
28
+ if ARGV.delete("-c") || ARGV.delete("--coverage")
29
+ require 'simplecov'
30
+ SimpleCov.start do
31
+ command_name name
32
+ add_filter "DO_NOT_HAND_MODIFY" # Exclude all imports
33
+
34
+ at_exit do
35
+ SimpleCov.result.format!
36
+ puts ""
37
+ puts "To view coverage report:"
38
+ puts " firefox #{path_to_coverage_report} &"
39
+ puts ""
40
+ end
41
+ end
42
+ yield
43
+ else
44
+ yield
45
+ end
46
+ end
47
+
48
+ # Now branch to the specific task code
49
+ case @command
50
+
51
+ # Run the unit tests
52
+ when "specs"
53
+ enable_coverage("specs") do
54
+ ARGV.unshift "spec"
55
+ require "rspec"
56
+ # For some unidentified reason Rspec does not autorun on this version
57
+ if RSpec::Core::Version::STRING && RSpec::Core::Version::STRING == "2.11.1"
58
+ RSpec::Core::Runner.run ARGV
59
+ else
60
+ require "rspec/autorun"
61
+ end
62
+ end
63
+ exit 0 # This will never be hit on a fail, RSpec will automatically exit 1
64
+
65
+ # Run the example-based (diff) tests
66
+ #when "examples"
67
+ # Origen.load_application
68
+ # status = 0
69
+ # enable_coverage("examples") do
70
+ #
71
+ # # Compiler tests
72
+ # ARGV = %w(templates/example.txt.erb -t debug -r approved)
73
+ # load "origen/commands/compile.rb"
74
+ # # Pattern generator tests
75
+ # #ARGV = %w(some_pattern -t debug -r approved)
76
+ # #load "#{Origen.top}/lib/origen/commands/generate.rb"
77
+ #
78
+ # if Origen.app.stats.changed_files == 0 &&
79
+ # Origen.app.stats.new_files == 0 &&
80
+ # Origen.app.stats.changed_patterns == 0 &&
81
+ # Origen.app.stats.new_patterns == 0
82
+ #
83
+ # Origen.app.stats.report_pass
84
+ # else
85
+ # Origen.app.stats.report_fail
86
+ # status = 1
87
+ # end
88
+ # puts ""
89
+ # end
90
+ # exit status # Exit with a 1 on the event of a failure per std unix result codes
91
+
92
+ # Always leave an else clause to allow control to fall back through to the
93
+ # Origen command handler.
94
+ # You probably want to also add the command details to the help shown via
95
+ # origen -h, you can do this be assigning the required text to @application_commands
96
+ # before handing control back to Origen. Un-comment the example below to get started.
97
+ else
98
+ @application_commands = <<-EOT
99
+ specs Run the specs (tests), -c will enable coverage
100
+ EOT
101
+ # examples Run the examples (tests), -c will enable coverage
102
+
103
+ # Uncomment the following and update the path with the file
104
+ # that handles the commands that are shared from this plugin
105
+ #require "#{Origen.app_root}/config/shared_commands"
106
+
107
+ end
@@ -0,0 +1,12 @@
1
+ # This file is similar to environment.rb and will be loaded
2
+ # automatically at the start of each invocation of Origen.
3
+ #
4
+ # However the major difference is that it will not be loaded
5
+ # if the application is imported by a 3rd party app - in that
6
+ # case only environment.rb is loaded.
7
+ #
8
+ # Therefore this file should be used to load anything you need
9
+ # to setup a development environment for this app, normally
10
+ # this would be used to load some dummy classes to instantiate
11
+ # your objects so that they can be tested and/or interacted with
12
+ # in the console.
@@ -0,0 +1,40 @@
1
+ # This file will be required by Origen before your target is loaded, you
2
+ # can use this to require all of your files, which is the easiest way
3
+ # to get started. As your experience grows you may wish to require only the
4
+ # minimum files required to allow the target to be initialized and let
5
+ # each class require its own dependencies.
6
+ #
7
+ # It is recommended that you keep all of your application logic in lib/
8
+ # The lib directory has already been added to the search path and so any files
9
+ # in there can be referenced from here with a relative path.
10
+ #
11
+ # Note that pattern files do not need to be referenced from here and these
12
+ # will be located automatically by origen.
13
+ #
14
+ # Examples
15
+ # --------
16
+ # This says load the file "lib/pioneer.rb" the first time anyone makes a
17
+ # reference to the class name 'Pioneer'.
18
+ #autoload :Pioneer, "pioneer"
19
+ #
20
+ # This is generally preferable to using require which will load the file
21
+ # regardless of whether it is needed by the current target or not:
22
+ #require "pioneer"
23
+ #
24
+ # Sometimes you have to use require however:-
25
+ # 1. When defining a test program interface:
26
+ #require "interfaces/j750"
27
+ # 2. If you want to extend a class defined by an imported plugin, in
28
+ # this case your must use required and supply a full path (to distinguish
29
+ # it from the one in the parent application):
30
+ #require "#{Origen.root}/c90_top_level/p2"
31
+
32
+ # Plugins should not use a wildcard import of the lib directory to help
33
+ # prevent long start up times, only require what is necessary to boot and
34
+ # use autoload for everything else.
35
+ module OrigenMemoryImage
36
+ autoload :Base, "origen_memory_image/base"
37
+ autoload :SRecord, "origen_memory_image/s_record"
38
+ autoload :Hex, "origen_memory_image/hex"
39
+ end
40
+ require "origen_memory_image"
data/config/users.rb ADDED
@@ -0,0 +1,18 @@
1
+ # This file defines the users associated with your project, it is basically the
2
+ # mailing list for release notes.
3
+ #
4
+ # You can split your users into "admin" and "user" groups, the main difference
5
+ # between the two is that admin users will get all tag emails, users will get
6
+ # emails on external/official releases only.
7
+ #
8
+ # Users are also prohibited from running the "origen tag" task, but this is
9
+ # really just to prevent a casual user from executing it inadvertently and is
10
+ # not intended to be a serious security gate.
11
+ module Origen
12
+ module Users
13
+ def users
14
+ @users ||= [
15
+ ]
16
+ end
17
+ end
18
+ end
data/config/version.rb ADDED
@@ -0,0 +1,8 @@
1
+ module OrigenMemoryImage
2
+ MAJOR = 0
3
+ MINOR = 5
4
+ BUGFIX = 0
5
+ DEV = nil
6
+
7
+ VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
+ end
@@ -0,0 +1,71 @@
1
+ module OrigenMemoryImage
2
+ class Base
3
+ attr_reader :file, :source
4
+
5
+ def initialize(file, options = {})
6
+ if options[:source] == String
7
+ @source = file
8
+ else
9
+ @file = file
10
+ end
11
+ end
12
+
13
+ # Returns the code execution start address as an int
14
+ def start_address
15
+ fail "#{self.class} has not implemented the start_address method!"
16
+ end
17
+
18
+ # Returns the s-record as an array of addresses and data
19
+ #
20
+ # @param [hash] options, allows the selection of endianness swapping - ie the output will have the endianness changed
21
+ #
22
+ # The output is a 2D array, with each element being an array with element zero being the
23
+ # address of the data and element one being one word of data
24
+ # like this [[ADDR0, DATA0], [ADDR1, DATA1], [ADDR2, DATA2]...]
25
+ #
26
+ # The block header data and end of block value are not interpreted in any way and
27
+ # the checksum bits are disregarded
28
+ def to_a(options = {})
29
+ options = {
30
+ flip_endianness: false,
31
+ data_width_in_bytes: 4
32
+ }.merge(options)
33
+ data = extract_addr_data(options)
34
+ if options[:flip_endianness] || options[:endianness_change]
35
+ data.map do |v|
36
+ [v[0], flip_endianness(v[1], 4)]
37
+ end
38
+ else
39
+ data
40
+ end
41
+ end
42
+ alias_method :to_array, :to_a
43
+
44
+ # Reverse the endianness of the given data value, the width of it in bytes must
45
+ # be supplied as the second argument
46
+ #
47
+ # @example
48
+ # flip_endianness(0x12345678, 4) # => 0x78563412
49
+ def flip_endianness(data, width_in_bytes)
50
+ v = 0
51
+ width_in_bytes.times do |i|
52
+ # data[7:0] => data[15:8]
53
+ start = 8 * i
54
+ v += data[(start + 7)..start] << ((width_in_bytes - i - 1) * 8)
55
+ end
56
+ v
57
+ end
58
+
59
+ def file_name
60
+ file || 'From source string'
61
+ end
62
+
63
+ def lines
64
+ if file
65
+ File.readlines(file)
66
+ else
67
+ source.split("\n")
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,56 @@
1
+ module OrigenMemoryImage
2
+ class Hex < Base
3
+ def self.match?(snippet)
4
+ snippet.any? do |line|
5
+ # Match a line like:
6
+ # @180000F0
7
+ line =~ /^@[0-9a-fA-F]+\s?$/
8
+ end
9
+ end
10
+
11
+ # The first in the file will be taken as the start address
12
+ def start_address
13
+ @start_address ||= begin
14
+ lines.each do |line|
15
+ if line =~ /^@([0-9a-fA-F]+)\s?$/
16
+ return Regexp.last_match[1].to_i(16)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # Returns an array containing all address/data from the given s-record
25
+ # No address manipulation is performed, that is left to the caller to apply
26
+ # any scrambling as required by the target system
27
+ def extract_addr_data(options = {})
28
+ options = {
29
+ data_width_in_bytes: 4
30
+ }.merge(options)
31
+
32
+ result = []
33
+ lines.each do |line|
34
+ # Only if the line is an s-record with data...
35
+ if line =~ /^@([0-9a-fA-F]+)\s?$/
36
+ @address = Regexp.last_match[1].to_i(16)
37
+ elsif line =~ /^[0-9A-F]/
38
+ unless @address
39
+ fail "Hex data found before an @address line in #{file_name}"
40
+ end
41
+ data = line.strip.gsub(/\s/, '')
42
+ data_matcher = '\w\w' * options[:data_width_in_bytes]
43
+ data.scan(/#{data_matcher}/).each do |data_packet|
44
+ result << [@address, data_packet.to_i(16)]
45
+ @address += options[:data_width_in_bytes]
46
+ end
47
+ # If a partial word is left over
48
+ if (remainder = data.length % (2 * options[:data_width_in_bytes])) > 0
49
+ result << [@address, data[data.length - remainder..data.length].to_i(16)]
50
+ end
51
+ end
52
+ end
53
+ result
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,212 @@
1
+ module OrigenMemoryImage
2
+ # An S-record file consists of a sequence of specially formatted ASCII character strings. An S-record will
3
+ # be less than or equal to 78 bytes in length.
4
+ # The order of S-records within a file is of no significance and no particular order may be assumed.
5
+ #
6
+ # The general format of an S-record follows:
7
+ #
8
+ # +-------------------//------------------//-----------------------+
9
+ # | type | count | address | data | checksum |
10
+ # +-------------------//------------------//-----------------------+
11
+ #
12
+ # type
13
+ # : A char[2] field. These characters describe the type of record (S0, S1, S2, S3, S5, S7, S8, or S9).
14
+ #
15
+ # count
16
+ # : A char[2] field. These characters when paired and interpreted as a hexadecimal value, display
17
+ # the count of remaining character pairs in the record.
18
+ #
19
+ # address
20
+ # : A char[4,6, or 8] field. These characters grouped and interpreted as a hexadecimal value,
21
+ # display the address at which the data field is to be loaded into memory. The length of the field depends
22
+ # on the number of bytes necessary to hold the address. A 2-byte address uses 4 characters, a 3-byte
23
+ # address uses 6 characters, and a 4-byte address uses 8 characters.
24
+ #
25
+ # data
26
+ # : A char [0-64] field. These characters when paired and interpreted as hexadecimal values represent
27
+ # the memory loadable data or descriptive information.
28
+ #
29
+ # checksum
30
+ # : A char[2] field. These characters when paired and interpreted as a hexadecimal value display
31
+ # the least significant byte of the ones complement of the sum of the byte values represented by the pairs
32
+ # of characters making up the count, the address, and the data fields.
33
+ #
34
+ # Each record is terminated with a line feed. If any additional or different record terminator(s) or delay
35
+ # characters are needed during transmission to the target system it is the responsibility of the
36
+ # transmitting program to provide them.
37
+ #
38
+ # #### S0 Record
39
+ #
40
+ # The type of record is 'S0' (0x5330). The address field is unused and will be filled with zeros
41
+ # (0x0000). The header information within the data field is divided into the following subfields.
42
+ #
43
+ # * mname is char[20] and is the module name.
44
+ # * ver is char[2] and is the version number.
45
+ # * rev is char[2] and is the revision number.
46
+ # * description is char[0-36] and is a text comment.
47
+ #
48
+ # Each of the subfields is composed of ASCII bytes whose associated characters, when paired, represent one
49
+ # byte hexadecimal values in the case of the version and revision numbers, or represent the hexadecimal
50
+ # values of the ASCII characters comprising the module name and description.
51
+ #
52
+ # #### S1 Record
53
+ #
54
+ # The type of record field is 'S1' (0x5331). The address field is intrepreted as a 2-byte
55
+ # address. The data field is composed of memory loadable data.
56
+ #
57
+ # #### S2 Record
58
+ #
59
+ # The type of record field is 'S2' (0x5332). The address field is intrepreted as a 3-byte
60
+ # address. The data field is composed of memory loadable data.
61
+ #
62
+ # #### S3 Record
63
+ #
64
+ # The type of record field is 'S3' (0x5333). The address field is intrepreted as a 4-byte
65
+ # address. The data field is composed of memory loadable data.
66
+ #
67
+ # #### S5 Record
68
+ #
69
+ # The type of record field is 'S5' (0x5335). The address field is intrepreted as a 2-byte value
70
+ # and contains the count of S1, S2, and S3 records previously transmitted. There is no data field.
71
+ #
72
+ # #### S7 Record
73
+ #
74
+ # The type of record field is 'S7' (0x5337). The address field contains the starting execution
75
+ # address and is intrepreted as 4-byte address. There is no data field.
76
+ #
77
+ # #### S8 Record
78
+ #
79
+ # The type of record field is 'S8' (0x5338). The address field contains the starting execution
80
+ # address and is intrepreted as 3-byte address. There is no data field.
81
+ #
82
+ # #### S9 Record
83
+ #
84
+ # The type of record field is 'S9' (0x5339). The address field contains the starting execution
85
+ # address and is intrepreted as 2-byte address. There is no data field.
86
+ #
87
+ # ### Example
88
+ #
89
+ # Shown below is a typical S-record format file.
90
+ #
91
+ # S00600004844521B
92
+ # S1130000285F245F2212226A000424290008237C2A
93
+ # S11300100002000800082629001853812341001813
94
+ # S113002041E900084E42234300182342000824A952
95
+ # S107003000144ED492
96
+ # S5030004F8
97
+ # S9030000FC
98
+ #
99
+ # The file consists of one S0 record, four S1 records, one S5 record and an S9 record.
100
+ #
101
+ # The S0 record is comprised as follows:
102
+ #
103
+ # * S0 S-record type S0, indicating it is a header record.
104
+ # * 06 Hexadecimal 06 (decimal 6), indicating that six character pairs (or ASCII bytes) follow.
105
+ # * 00 00 Four character 2-byte address field, zeroes in this example.
106
+ # * 48 44 52 ASCII H, D, and R - "HDR".
107
+ # * 1B The checksum.
108
+ #
109
+ # The first S1 record is comprised as follows:
110
+ #
111
+ # * S1 S-record type S1, indicating it is a data record to be loaded at a 2-byte address.
112
+ # * 13 Hexadecimal 13 (decimal 19), indicating that nineteen character pairs, representing a 2 byte address,
113
+ # * 16 bytes of binary data, and a 1 byte checksum, follow.
114
+ # * 00 00 Four character 2-byte address field; hexidecimal address 0x0000, where the data which follows is to
115
+ # be loaded.
116
+ # * 28 5F 24 5F 22 12 22 6A 00 04 24 29 00 08 23 7C Sixteen character pairs representing the actual binary
117
+ # data.
118
+ # * 2A The checksum.
119
+ # * The second and third S1 records each contain 0x13 (19) character pairs and are ended with checksums of 13
120
+ # and 52, respectively. The fourth S1 record contains 07 character pairs and has a checksum of 92.
121
+ #
122
+ # The S5 record is comprised as follows:
123
+ #
124
+ # * S5 S-record type S5, indicating it is a count record indicating the number of S1 records
125
+ # * 03 Hexadecimal 03 (decimal 3), indicating that three character pairs follow.
126
+ # * 00 04 Hexadecimal 0004 (decimal 4), indicating that there are four data records previous to this record.
127
+ # * F8 The checksum.
128
+ #
129
+ # The S9 record is comprised as follows:
130
+ #
131
+ # * S9 S-record type S9, indicating it is a termination record.
132
+ # * 03 Hexadecimal 03 (decimal 3), indicating that three character pairs follow.
133
+ # * 00 00 The address field, hexadecimal 0 (decimal 0) indicating the starting execution address.
134
+ # * FC The checksum.
135
+ #
136
+ # ### Additional Notes
137
+ #
138
+ # There isn't any evidence that Motorola ever has made use of the header information within the data field
139
+ # of the S0 record, as described above. This must have been used by some third party vendors.
140
+ # This is the only place that a 78-byte limit on total record length or 64-byte limit on data length is
141
+ # documented. These values shouldn't be trusted for the general case.
142
+ #
143
+ # The count field can have values in the range of 0x3 (2 bytes of address + 1 byte checksum = 3, a not
144
+ # very useful record) to 0xff; this is the count of remaining character pairs, including checksum.
145
+ # If you write code to convert S-Records, you should always assume that a record can be as long as 514
146
+ # (decimal) characters in length (255 * 2 = 510, plus 4 characters for the type and count fields), plus
147
+ # any terminating character(s).
148
+ #
149
+ # That is, in establishing an input buffer in C, you would declare it to be
150
+ # an array of 515 chars, thus leaving room for the terminating null character.
151
+ class SRecord < Base
152
+ def self.match?(snippet)
153
+ snippet.all? do |line|
154
+ line.empty? || line =~ /^S[01235789]/
155
+ end
156
+ end
157
+
158
+ def start_address
159
+ @start_address ||= begin
160
+ lines.each do |line|
161
+ if line =~ /^S([789])(.*)/
162
+ type = Regexp.last_match[1]
163
+ case type
164
+ when '7'
165
+ return line.slice(4, 8).to_i(16)
166
+ when '8'
167
+ return line.slice(4, 6).to_i(16)
168
+ when '9'
169
+ return line.slice(4, 4).to_i(16)
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ private
177
+
178
+ # Returns an array containing all address/data from the given s-record
179
+ # No address manipulation is performed, that is left to the caller to apply
180
+ # any scrambling as required by the target system
181
+ def extract_addr_data(options = {})
182
+ options = {
183
+ data_width_in_bytes: 4
184
+ }.merge(options)
185
+
186
+ result = []
187
+ lines.each do |line|
188
+ # Only if the line is an s-record with data...
189
+ if line =~ /^S([1-3])/
190
+ type = Regexp.last_match[1].to_i(16) # S-record type, 1-3
191
+ # Set the matcher to capture x number of bytes dependent on the s-rec type
192
+ addr_matcher = '\w\w' * (1 + type)
193
+ line.strip =~ /^S\d\w\w(#{addr_matcher})(\w*)\w\w$/ # $1 = address, $2 = data
194
+ addr = Regexp.last_match[1].to_i(16)
195
+ @start_address ||= addr
196
+ @start_address = addr if addr < @start_address
197
+ data = Regexp.last_match[2]
198
+ data_matcher = '\w\w' * options[:data_width_in_bytes]
199
+ data.scan(/#{data_matcher}/).each do |data_packet|
200
+ result << [addr, data_packet.to_i(16)]
201
+ addr += options[:data_width_in_bytes]
202
+ end
203
+ # If a partial word is left over
204
+ if (remainder = data.length % (2 * options[:data_width_in_bytes])) > 0
205
+ result << [addr, data[data.length - remainder..data.length].to_i(16)]
206
+ end
207
+ end
208
+ end
209
+ result
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,30 @@
1
+ require 'origen'
2
+ require_relative '../config/application.rb'
3
+ require_relative '../config/environment.rb'
4
+
5
+ module OrigenMemoryImage
6
+ def self.new(file, options = {})
7
+ unless options[:source] == String
8
+ file = Origen.file_handler.clean_path_to(file)
9
+ end
10
+ find_type(file, options).new(file, options)
11
+ end
12
+
13
+ # Returns the class of the image manager for the given file
14
+ def self.find_type(file, options = {})
15
+ # Read first 10 lines
16
+ if options[:source] == String
17
+ snippet = file.split("\n")
18
+ else
19
+ snippet = File.foreach(file.to_s).first(1)
20
+ end
21
+ case
22
+ when options[:type] == :srecord || SRecord.match?(snippet)
23
+ SRecord
24
+ when options[:type] == :hex || Hex.match?(snippet)
25
+ Hex
26
+ else
27
+ fail "Unknown format for image file: #{file}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,147 @@
1
+ % render "layouts/basic.html" do
2
+
3
+ %# HTML tags can be embedded in mark down files if you want to do specific custom
4
+ %# formatting like this, but in most cases that is not required.
5
+ <h1><%= Origen.config.name %> <span style="font-size: 14px">(<%= Origen.app.version %>)</span></h1>
6
+
7
+ ### Purpose
8
+
9
+ This plugin provides a common API for easily reading memory image files in any format
10
+ so that their contained data can then be used in Origen:
11
+
12
+ ~~~ruby
13
+ # Read in an s-record
14
+ srec = OrigenMemoryImage.new("srecs/test_atd.abs.S19")
15
+
16
+ # Write it to the DUT, or otherwise work with it, however you like
17
+ srec.to_a.each do |addr, data|
18
+ $dut.write_memory data, address: addr
19
+ end
20
+ ~~~
21
+
22
+ ### How To Import
23
+
24
+ ##### To use in an application:
25
+
26
+ Add the following to your application's <code>Gemfile</code>:
27
+
28
+ ~~~ruby
29
+ gem 'origen_memory_image', '<%= Origen.app.version %>'
30
+ ~~~
31
+
32
+ ##### To use in a plugin:
33
+
34
+ Add the following to your plugin's gemspec:
35
+
36
+ ~~~ruby
37
+ spec.add_runtime_dependency 'origen_memory_image', '~> <%= Origen.app.version.major %>', '>= <%= Origen.app.version %>'
38
+ ~~~
39
+
40
+ and require the gem in your code:
41
+
42
+ ~~~ruby
43
+ require 'origen_memory_image'
44
+ ~~~
45
+
46
+
47
+ ### How To Use
48
+
49
+ Create a memory map object that points to a specific source file, note that
50
+ you do not need to supply the format.
51
+ Also note that the format is detected by looking at the file content and the naming
52
+ and extension of the file has no relevance (so it can be called anything).
53
+
54
+ The path to the file can be absolute or relative to <code>Origen.root</code>:
55
+
56
+ ~~~ruby
57
+ my_srec = OrigenMemoryImage.new("source_files/test_atd.abs.S19")
58
+ my_hex = OrigenMemoryImage.new("source_files/math.hex")
59
+ ~~~
60
+
61
+ Memory images can also be created directly from a string:
62
+
63
+ ~~~ruby
64
+ str = <<-END
65
+ @2D100E00
66
+ 0D 15 0F 13 0E 14 10 12
67
+ 00 00 04 17 04 03 05 06
68
+ END
69
+
70
+ my_hex = OrigenMemoryImage.new(str, source: String)
71
+ ~~~
72
+
73
+ Every memory image object then supports a common API.
74
+
75
+ The <code>start_address</code> method returns the start (execution start) address:
76
+
77
+ ~~~ruby
78
+ my_srec.start_address # => 0x3000_F000
79
+ ~~~
80
+
81
+ The <code>to_a</code> method returns the file content as an array of address/data pairs,
82
+ this method supports options to set the data width and to flip the data endianness:
83
+
84
+ ~~~ruby
85
+ my_srec.to_a # => [[0x3000_F000, 0x11223344], [0x3000_F004, 0x55667788], ...]
86
+
87
+ my_srec.to_a(flip_endianness: true) # => [[0x3000_F000, 0x44332211], [0x3000_F004, 0x88776655], ...]
88
+
89
+ my_srec.to_a(data_width_in_bytes: 2) # => [[0x3000_F000, 0x1122], [0x3000_F002, 0x3344], [0x3000_F004, 0x5566], ...]
90
+ ~~~
91
+
92
+ Such an array can be iterated on like this to separate the address and data:
93
+
94
+ ~~~ruby
95
+ my_srec.to_a.each do |address, data|
96
+ # Process as required
97
+ end
98
+ ~~~
99
+
100
+ ### Currently Supported Formats
101
+
102
+ #### S-Records
103
+
104
+ Any valid S-record:
105
+
106
+ ~~~text
107
+ S017000068656C6C6F5F776F726C645F6576622E73726563D6
108
+ S3153F00002018F09FE518F09FE518F09FE518F09FE55B
109
+ S3153F00003018F09FE500F020E314F09FE514F09FE5EC
110
+ S3113F000270F406003F102100407800003FDC
111
+ S3153F0005B05FF0FF301B4908605FF0FF301A49086063
112
+ S3093F0006F0704700000A
113
+ S7053F000410A7
114
+ ~~~
115
+
116
+ #### Hex Files
117
+
118
+ The data lines can be grouped into any size:
119
+
120
+ ~~~text
121
+ @18000000
122
+ 1E E0 02 1C 22 40 1B E0 02 1C 22 43 18 E0 02 1C
123
+ 5A 78 0A 43 03 E0 03 4B F7 21 5A 78 0A 40 00 20
124
+ 22 E0 84 42 22 D3 1F E0 84 42 1F D9 1C E0 84 42
125
+ @180000E0
126
+ 002B20D1 03E0012A 01D1002B 1BD00223
127
+ 2340022A 02D1002B 15D103E0 032A01D1
128
+ @180001F0
129
+ 780000187C0000188200001888000018
130
+ ~~~
131
+
132
+ ### How To Setup a Development Environment
133
+
134
+ [Clone the repository from Github](https://github.com/Origen-SDK/origen_memory_image).
135
+
136
+ Follow the instructions here if you want to make a 3rd party app
137
+ workspace use your development copy of the <%= Origen.app.config.initials %> plugin:
138
+ [Setting up a Plugin Development Environment](http://origen-sdk.org/origen/latest/guides/plugins)
139
+
140
+ This plugin also contains a test suite, makes sure this passes before committing
141
+ any changes!
142
+
143
+ ~~~text
144
+ origen specs
145
+ ~~~
146
+
147
+ % end
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: <%= options[:title] || Origen.config.name %>
3
+ analytics: UA-64455560-1
4
+ ---
5
+ <%= render "templates/web/partials/navbar.html", tab: options[:tab] %>
6
+
7
+ <div class="row">
8
+ %# The markdown attribute is important if you are going to include content written
9
+ %# in markdown, without this is will be included verbatim
10
+ <div class="span12" markdown="1">
11
+ <%= yield %>
12
+
13
+ <%= disqus_comments %>
14
+
15
+ </div>
16
+ </div>
@@ -0,0 +1,22 @@
1
+ <nav class="navbar navbar-inverse navbar-fixed-top">
2
+ <div class="container">
3
+ <div class="navbar-header">
4
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
5
+ <span class="sr-only">Toggle navigation</span>
6
+ <span class="icon-bar"></span>
7
+ <span class="icon-bar"></span>
8
+ <span class="icon-bar"></span>
9
+ </button>
10
+ <a class="navbar-brand" href="<%= path "/" %>">Home</a>
11
+ </div>
12
+ <div id="navbar" class="collapse navbar-collapse">
13
+ <ul class="nav navbar-nav">
14
+ <li class="<%= options[:tab] == :api ? 'active' : '' %>"><a href="<%= path "/api/" %>">API</a></li>
15
+ <li class="<%= options[:tab] == :coverage ? 'active' : '' %>"><a href="<%= path "/coverage" %>">Coverage</a></li>
16
+ <li class="<%= options[:tab] == :release ? 'active' : '' %>"><a href="<%= path "/release_notes" %>">Release Notes</a></li>
17
+ <li><a href="https://github.com/Origen-SDK/origen_memory_image">Github</a></li>
18
+ </ul>
19
+ <%= import "origen/web/logo.html" %>
20
+ </div><!--/.nav-collapse -->
21
+ </div>
22
+ </nav>
@@ -0,0 +1,5 @@
1
+ % render "layouts/basic.html", tab: :release do
2
+
3
+ <%= render "#{Origen.root}/doc/history" %>
4
+
5
+ % end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: origen_memory_image
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Stephen McGinty
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: origen
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: origen_doc_helpers
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
41
+ description:
42
+ email:
43
+ - stephen.f.mcginty@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - config/application.rb
49
+ - config/commands.rb
50
+ - config/development.rb
51
+ - config/environment.rb
52
+ - config/users.rb
53
+ - config/version.rb
54
+ - lib/origen_memory_image.rb
55
+ - lib/origen_memory_image/base.rb
56
+ - lib/origen_memory_image/hex.rb
57
+ - lib/origen_memory_image/s_record.rb
58
+ - templates/web/index.md.erb
59
+ - templates/web/layouts/_basic.html.erb
60
+ - templates/web/partials/_navbar.html.erb
61
+ - templates/web/release_notes.md.erb
62
+ homepage: http://origen-sdk.org/memory_image
63
+ licenses: []
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 1.9.3
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 1.8.11
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.2.2
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Provides a standard API for consuming memory image files in any format e.g.
85
+ s-record, hex
86
+ test_files: []
87
+ has_rdoc: