origen_memory_image 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|