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 +7 -0
- data/config/application.rb +87 -0
- data/config/commands.rb +107 -0
- data/config/development.rb +12 -0
- data/config/environment.rb +40 -0
- data/config/users.rb +18 -0
- data/config/version.rb +8 -0
- data/lib/origen_memory_image/base.rb +71 -0
- data/lib/origen_memory_image/hex.rb +56 -0
- data/lib/origen_memory_image/s_record.rb +212 -0
- data/lib/origen_memory_image.rb +30 -0
- data/templates/web/index.md.erb +147 -0
- data/templates/web/layouts/_basic.html.erb +16 -0
- data/templates/web/partials/_navbar.html.erb +22 -0
- data/templates/web/release_notes.md.erb +5 -0
- metadata +87 -0
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
|
data/config/commands.rb
ADDED
@@ -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,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>
|
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:
|