rpicsim 0.4.0 → 1.0.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 +4 -4
- data/.yardopts +3 -1
- data/Introduction.md +1 -3
- data/README.md +1 -3
- data/docs/ChangeLog.md +13 -0
- data/docs/KnownIssues.md +2 -2
- data/docs/Manual.md +0 -1
- data/docs/RSpecIntegration.md +24 -1
- data/docs/SupportedMPLABXVersions.md +2 -0
- data/lib/rpicsim.rb +6 -1
- data/lib/rpicsim/composite_memory.rb +3 -0
- data/lib/rpicsim/flaws.rb +28 -4
- data/lib/rpicsim/label.rb +7 -0
- data/lib/rpicsim/memory.rb +4 -0
- data/lib/rpicsim/memory_watcher.rb +11 -4
- data/lib/rpicsim/mplab.rb +1 -0
- data/lib/rpicsim/mplab/mplab_assembly.rb +0 -1
- data/lib/rpicsim/pin.rb +7 -0
- data/lib/rpicsim/program_counter.rb +4 -0
- data/lib/rpicsim/program_file.rb +20 -17
- data/lib/rpicsim/rspec.rb +6 -3
- data/lib/rpicsim/rspec/helpers.rb +13 -5
- data/lib/rpicsim/rspec/persistent_expectations.rb +5 -3
- data/lib/rpicsim/rspec/sim_diagnostics.rb +1 -0
- data/lib/rpicsim/sim.rb +8 -3
- data/lib/rpicsim/stack_pointer.rb +6 -0
- data/lib/rpicsim/stack_trace.rb +32 -1
- data/lib/rpicsim/storage/memory_integer.rb +1 -0
- data/lib/rpicsim/symbol_set.rb +3 -1
- data/lib/rpicsim/variable.rb +14 -0
- data/lib/rpicsim/variable_set.rb +2 -0
- data/lib/rpicsim/version.rb +4 -1
- data/lib/rpicsim/xc8_sym_file.rb +63 -11
- metadata +2 -7
- data/docs/PreventingCallStackOverflow.md +0 -92
- data/lib/rpicsim/call_stack_info.rb +0 -303
- data/lib/rpicsim/instruction.rb +0 -337
- data/lib/rpicsim/mplab/mplab_disassembler.rb +0 -20
- data/lib/rpicsim/search.rb +0 -20
data/lib/rpicsim/rspec.rb
CHANGED
@@ -5,7 +5,10 @@ require_relative 'rspec/helpers'
|
|
5
5
|
require_relative 'rspec/sim_diagnostics'
|
6
6
|
require_relative 'rspec/be_predicate'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# See {file:RSpecIntegration.md}.
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
module RPicSim::RSpec
|
11
12
|
end
|
13
|
+
|
14
|
+
|
@@ -9,10 +9,12 @@ module RPicSim
|
|
9
9
|
#
|
10
10
|
# It provides the {#start_sim} method and includes all the methods from
|
11
11
|
# {PersistentExpectations}.
|
12
|
-
#
|
13
|
-
#
|
12
|
+
#
|
13
|
+
# For more information, see {file:RSpecIntegration.md}.
|
14
|
+
#
|
15
|
+
# @api public
|
14
16
|
module Helpers
|
15
|
-
include
|
17
|
+
include PersistentExpectations
|
16
18
|
|
17
19
|
# This attribute allows you to type +sim+ in your specs instead of +@sim+ to
|
18
20
|
# get access to the {RPicSim::Sim} instance which represents the simulation.
|
@@ -20,8 +22,8 @@ module RPicSim
|
|
20
22
|
attr_reader :sim
|
21
23
|
|
22
24
|
# Starts a new simulation with the specified class, makes it
|
23
|
-
# accessible via the attribute {#sim}, and adds
|
24
|
-
# methods
|
25
|
+
# accessible via the attribute {#sim}, and adds convenient
|
26
|
+
# shortcut methods that can be used in the RSpec example.
|
25
27
|
# @param klass [Class] This should be a subclass of {RPicSim::Sim} or at least act like it.
|
26
28
|
# @param args A list of arguments to pass on to the the +new+ method of the class.
|
27
29
|
# This should usually be empty unless you have modified your class to take arguments in its
|
@@ -32,6 +34,7 @@ module RPicSim
|
|
32
34
|
sim.every_step { check_expectations }
|
33
35
|
end
|
34
36
|
|
37
|
+
# @api private
|
35
38
|
def add_shortcuts
|
36
39
|
configuration_value = ::RSpec.configuration.sim_shortcuts
|
37
40
|
case configuration_value
|
@@ -45,3 +48,8 @@ module RPicSim
|
|
45
48
|
end
|
46
49
|
end
|
47
50
|
end
|
51
|
+
|
52
|
+
RSpec.configure do |config|
|
53
|
+
config.add_setting :sim_shortcuts, default: :all
|
54
|
+
config.include RPicSim::RSpec::Helpers
|
55
|
+
end
|
@@ -13,6 +13,10 @@ module RPicSim
|
|
13
13
|
# b << 0
|
14
14
|
# check_expectations # => raises an error once b has 10 elements
|
15
15
|
# end
|
16
|
+
#
|
17
|
+
# For more information, see {file:PersistentExpectations.md}.
|
18
|
+
#
|
19
|
+
# @api public
|
16
20
|
module PersistentExpectations
|
17
21
|
# Returns the current set of persistent expectations.
|
18
22
|
# The keys are the objects under test and the values are matchers that
|
@@ -26,9 +30,7 @@ module RPicSim
|
|
26
30
|
# it raises an error.
|
27
31
|
def check_expectations
|
28
32
|
expectations.each do |subject, matcher|
|
29
|
-
if matcher
|
30
|
-
expect(subject).to matcher
|
31
|
-
end
|
33
|
+
expect(subject).to matcher if matcher
|
32
34
|
end
|
33
35
|
nil
|
34
36
|
end
|
data/lib/rpicsim/sim.rb
CHANGED
@@ -14,10 +14,13 @@ require_relative 'program_file'
|
|
14
14
|
require_relative 'stack_pointer'
|
15
15
|
require_relative 'stack_trace'
|
16
16
|
|
17
|
+
# @api public
|
17
18
|
module RPicSim
|
18
19
|
# This class represents a PIC microcontroller simulation.
|
19
20
|
# This class keeps track of the state of the simulation and provides methods for
|
20
21
|
# running the simulation, reading the state, and changing the state.
|
22
|
+
#
|
23
|
+
# @api public
|
21
24
|
class Sim
|
22
25
|
# These methods should be called while defining a subclass of {Sim}.
|
23
26
|
module ClassDefinitionMethods
|
@@ -50,7 +53,7 @@ module RPicSim
|
|
50
53
|
end
|
51
54
|
|
52
55
|
# Define a symbol.
|
53
|
-
# Normally symbols are loaded by {#use_file} or {#import_symbols}, but
|
56
|
+
# Normally symbols are loaded by {#use_file} or {#import_symbols}, but
|
54
57
|
# this method allows for adding additional symbols one at a time.
|
55
58
|
#
|
56
59
|
# See {RPicSim::ProgramFile#def_symbol} for details about the parameters
|
@@ -118,6 +121,7 @@ module RPicSim
|
|
118
121
|
|
119
122
|
# A {VariableSet} that holds information about all the variables that were defined
|
120
123
|
# with {ClassDefinitionMethods#def_var def_var}.
|
124
|
+
# @api private
|
121
125
|
attr_reader :variable_set
|
122
126
|
|
123
127
|
# The {ProgramFile} object representing the firmware.
|
@@ -213,12 +217,12 @@ module RPicSim
|
|
213
217
|
|
214
218
|
# Returns a {Variable} object corresponding to WREG. You can use this
|
215
219
|
# to read and write the value of the W register.
|
216
|
-
# @return [
|
220
|
+
# @return [Variable]
|
217
221
|
attr_reader :wreg
|
218
222
|
|
219
223
|
# Returns a {Variable} object corresponding to the stack pointer register.
|
220
224
|
# You can use this to read and write the value of the stack pointer.
|
221
|
-
# @return [
|
225
|
+
# @return [Variable]
|
222
226
|
attr_reader :stkptr
|
223
227
|
|
224
228
|
# Returns a {StackPointer} object that is like {#stkptr} but it works
|
@@ -619,6 +623,7 @@ module RPicSim
|
|
619
623
|
|
620
624
|
public
|
621
625
|
|
626
|
+
# @return [String]
|
622
627
|
def inspect
|
623
628
|
"#<#{self.class}:0x%x, #{pc_description}, stack_pointer = #{stack_pointer.value}>" % object_id
|
624
629
|
end
|
@@ -1,18 +1,23 @@
|
|
1
|
+
# @api public
|
1
2
|
module RPicSim
|
2
3
|
# Instances of this class represent the call stack pointer in a running
|
3
4
|
# simulation.
|
4
5
|
# A value of 0 means that the stack is empty, regardless of what device
|
5
6
|
# architecture you are simulating.
|
7
|
+
#
|
8
|
+
# @api public
|
6
9
|
class StackPointer
|
7
10
|
# Initializes the StackPointer object.
|
8
11
|
# This be called when the call stack is empty, because this object uses
|
9
12
|
# the initial value of stkptr to deduce how it works.
|
10
13
|
# @param stkptr The STKPTR register of the simulation.
|
14
|
+
# @api private
|
11
15
|
def initialize(stkptr)
|
12
16
|
@stkptr = stkptr
|
13
17
|
@stkptr_initial_value = @stkptr.value
|
14
18
|
end
|
15
19
|
|
20
|
+
# @return [Integer]
|
16
21
|
def value
|
17
22
|
if @stkptr_initial_value > 0
|
18
23
|
raw_value = @stkptr.value
|
@@ -26,6 +31,7 @@ module RPicSim
|
|
26
31
|
end
|
27
32
|
end
|
28
33
|
|
34
|
+
# @param value [Integer]
|
29
35
|
def value=(value)
|
30
36
|
@stkptr.value = if @stkptr_initial_value > 0
|
31
37
|
if value == 0
|
data/lib/rpicsim/stack_trace.rb
CHANGED
@@ -1,30 +1,61 @@
|
|
1
|
+
# @api public
|
1
2
|
module RPicSim
|
3
|
+
# Represents a stack trace from the simulated firmware.
|
4
|
+
#
|
5
|
+
# @api public
|
2
6
|
class StackTrace
|
7
|
+
# Array of {StackTraceEntry} objects. The last one represents where the
|
8
|
+
# program counter (PC) is. The entries before the last one approximately
|
9
|
+
# represent addresses of CALL or RCALL instructions that have not yet
|
10
|
+
# returned.
|
11
|
+
#
|
12
|
+
# @return An array of {StackTraceEntry} objects.
|
3
13
|
attr_reader :entries
|
4
14
|
|
15
|
+
# @api private
|
5
16
|
def initialize(entries = [])
|
6
17
|
@entries = entries
|
7
18
|
end
|
8
19
|
|
20
|
+
# Prints the stack trace to the specified IO object, preceding
|
21
|
+
# each line with the specified padding string.
|
22
|
+
#
|
23
|
+
# Example usage:
|
24
|
+
#
|
25
|
+
# stack_trace.output($stdout, ' ')
|
26
|
+
#
|
27
|
+
# @param io An object that behaves like a writable IO object.
|
28
|
+
# @param padding [String]
|
9
29
|
def output(io, padding = '')
|
10
30
|
@entries.reverse_each do |entry|
|
11
31
|
output_entry(entry, io, padding)
|
12
32
|
end
|
13
33
|
end
|
14
34
|
|
35
|
+
private
|
36
|
+
|
15
37
|
def output_entry(entry, io, padding)
|
16
38
|
io.puts padding + entry.description
|
17
39
|
end
|
18
40
|
end
|
19
41
|
|
42
|
+
# Represents an entry in a {StackTrace}.
|
43
|
+
#
|
44
|
+
# @api public
|
20
45
|
class StackTraceEntry
|
21
|
-
|
46
|
+
# @return [Integer]
|
47
|
+
attr_reader :address
|
48
|
+
|
49
|
+
# @return [String]
|
50
|
+
attr_reader :description
|
22
51
|
|
52
|
+
# @api private
|
23
53
|
def initialize(address, description)
|
24
54
|
@address = address
|
25
55
|
@description = description
|
26
56
|
end
|
27
57
|
|
58
|
+
# @return [String]
|
28
59
|
def to_s
|
29
60
|
description
|
30
61
|
end
|
data/lib/rpicsim/symbol_set.rb
CHANGED
data/lib/rpicsim/variable.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
+
# @api public
|
1
2
|
module RPicSim
|
3
|
+
# Instances of this class represents a variable in the memory of the simulated
|
4
|
+
# microcontroller. This class provides methods for reading, writing, and getting
|
5
|
+
# address of the variable.
|
6
|
+
#
|
7
|
+
# @api public
|
2
8
|
class Variable
|
3
9
|
# Creates a new Variable object.
|
4
10
|
# @param storage The internal storage for the variable.
|
11
|
+
# @api private
|
5
12
|
def initialize(storage)
|
6
13
|
@storage = storage
|
7
14
|
end
|
@@ -31,18 +38,25 @@ module RPicSim
|
|
31
38
|
@storage.memory_value
|
32
39
|
end
|
33
40
|
|
41
|
+
# @return [String]
|
34
42
|
def to_s
|
35
43
|
@storage.to_s
|
36
44
|
end
|
37
45
|
|
46
|
+
# The addresses in memory occupied by this variable.
|
47
|
+
# @return [Array(Integer)]
|
38
48
|
def addresses
|
39
49
|
@storage.addresses
|
40
50
|
end
|
41
51
|
|
52
|
+
# The main (lowest) address of this variable.
|
53
|
+
# @return [Integer]
|
42
54
|
def address
|
43
55
|
@storage.address
|
44
56
|
end
|
45
57
|
|
58
|
+
# The name of the variable.
|
59
|
+
# @return [Symbol]
|
46
60
|
def name
|
47
61
|
@storage.name
|
48
62
|
end
|
data/lib/rpicsim/variable_set.rb
CHANGED
data/lib/rpicsim/version.rb
CHANGED
data/lib/rpicsim/xc8_sym_file.rb
CHANGED
@@ -1,14 +1,66 @@
|
|
1
1
|
require 'scanf'
|
2
2
|
|
3
|
+
# @api public
|
3
4
|
module RPicSim
|
5
|
+
# This class can be used to load an XC8 sym file and get the information about
|
6
|
+
# the symbols in it. This is useful because the COF file produced by XC8 does
|
7
|
+
# not have enough information to identify what memory space every symbol is
|
8
|
+
# in.
|
9
|
+
#
|
10
|
+
# Example usage:
|
11
|
+
#
|
12
|
+
# class MySim < RPicSim::Sim
|
13
|
+
# use_device 'PIC18F25K50'
|
14
|
+
# use_file DistDir + 'TestXC8.hex'
|
15
|
+
# import_symbols RPicSim::Xc8SymFile.new(DistDir + 'TestXC8.sym')
|
16
|
+
#
|
17
|
+
# # ...
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# @api public
|
4
21
|
class Xc8SymFile
|
22
|
+
# Returns all the symbols.
|
23
|
+
# The return value is a hash where the keys are the names of the symbols
|
24
|
+
# (represented as Ruby symbols) and the values are the addresses of the symbols.
|
25
|
+
#
|
26
|
+
# @return [Hash]
|
5
27
|
attr_reader :symbols
|
28
|
+
|
29
|
+
# Returns all the symbols in RAM.
|
30
|
+
# The return value is a hash where the keys are the names of the symbols
|
31
|
+
# (represented as Ruby symbols) and the values are the addresses of the symbols.
|
32
|
+
#
|
33
|
+
# @return [Hash]
|
6
34
|
attr_reader :symbols_in_ram
|
35
|
+
|
36
|
+
# Returns all the symbols in EEPROM.
|
37
|
+
# The return value is a hash where the keys are the names of the symbols
|
38
|
+
# (represented as Ruby symbols) and the values are the addresses of the symbols.
|
39
|
+
#
|
40
|
+
# @return [Hash]
|
7
41
|
attr_reader :symbols_in_eeprom
|
42
|
+
|
43
|
+
# Returns all the symbols in program memory.
|
44
|
+
# The return value is a hash where the keys are the names of the symbols
|
45
|
+
# (represented as Ruby symbols) and the values are the addresses of the symbols.
|
46
|
+
#
|
47
|
+
# @return [Hash]
|
8
48
|
attr_reader :symbols_in_program_memory
|
9
49
|
|
50
|
+
# @api private
|
10
51
|
attr_reader :symbol_raw_data
|
11
52
|
|
53
|
+
# Creates a new instance of this class containing information from the
|
54
|
+
# specified file.
|
55
|
+
#
|
56
|
+
# @param filename [String]
|
57
|
+
# @param opts [Hash] Specified additional options. The options are:
|
58
|
+
# * +:user_ram_sections+: Array of strings of section names that
|
59
|
+
# should be considered to be in RAM.
|
60
|
+
# * +:user_program_memory_sections+: Array of strings of section names that
|
61
|
+
# should be considered to be in program memory.
|
62
|
+
# * +:user_eeprom_sections+: Array of strings of section names that
|
63
|
+
# should be considered to be in EEPROM.
|
12
64
|
def initialize(filename, opts = {})
|
13
65
|
@symbols = {}
|
14
66
|
@symbols_in_ram = {}
|
@@ -21,7 +73,10 @@ module RPicSim
|
|
21
73
|
@sections_in_code = %w{CODE CONST IDLOC MEDIUMCONST SMALLCONST}
|
22
74
|
@sections_in_eeprom = %w{EEDATA}
|
23
75
|
|
24
|
-
allowed_keys = [:
|
76
|
+
allowed_keys = [:user_ram_sections,
|
77
|
+
:user_program_memory_sections,
|
78
|
+
:user_eeprom_sections,
|
79
|
+
:custom_ram_sections,
|
25
80
|
:custom_code_sections,
|
26
81
|
:custom_eeprom_sections]
|
27
82
|
invalid_keys = opts.keys - allowed_keys
|
@@ -29,17 +84,14 @@ module RPicSim
|
|
29
84
|
raise "Invalid options: #{invalid_keys.inspect}"
|
30
85
|
end
|
31
86
|
|
32
|
-
|
33
|
-
|
34
|
-
|
87
|
+
@sections_in_ram += opts.fetch(:user_ram_sections, [])
|
88
|
+
@sections_in_code += opts.fetch(:user_program_memory_sections, [])
|
89
|
+
@sections_in_eeprom += opts.fetch(:user_eeprom_sections, [])
|
35
90
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
if opts[:custom_eeprom_sections]
|
41
|
-
@sections_in_eeprom += opts[:custom_eeprom_sections]
|
42
|
-
end
|
91
|
+
# Legacy options introduced in 0.4.0, but deprecated now.
|
92
|
+
@sections_in_ram += opts.fetch(:custom_ram_sections, [])
|
93
|
+
@sections_in_code += opts.fetch(:custom_code_sections, [])
|
94
|
+
@sections_in_eeprom += opts.fetch(:custom_eeprom_sections, [])
|
43
95
|
|
44
96
|
read_data
|
45
97
|
sort_data
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rpicsim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pololu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -17,10 +17,8 @@ extensions: []
|
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
19
|
- lib/rpicsim.rb
|
20
|
-
- lib/rpicsim/call_stack_info.rb
|
21
20
|
- lib/rpicsim/composite_memory.rb
|
22
21
|
- lib/rpicsim/flaws.rb
|
23
|
-
- lib/rpicsim/instruction.rb
|
24
22
|
- lib/rpicsim/label.rb
|
25
23
|
- lib/rpicsim/memory.rb
|
26
24
|
- lib/rpicsim/memory_watcher.rb
|
@@ -29,7 +27,6 @@ files:
|
|
29
27
|
- lib/rpicsim/program_counter.rb
|
30
28
|
- lib/rpicsim/program_file.rb
|
31
29
|
- lib/rpicsim/rspec.rb
|
32
|
-
- lib/rpicsim/search.rb
|
33
30
|
- lib/rpicsim/sim.rb
|
34
31
|
- lib/rpicsim/stack_pointer.rb
|
35
32
|
- lib/rpicsim/stack_trace.rb
|
@@ -40,7 +37,6 @@ files:
|
|
40
37
|
- lib/rpicsim/xc8_sym_file.rb
|
41
38
|
- lib/rpicsim/mplab/mplab_assembly.rb
|
42
39
|
- lib/rpicsim/mplab/mplab_device_info.rb
|
43
|
-
- lib/rpicsim/mplab/mplab_disassembler.rb
|
44
40
|
- lib/rpicsim/mplab/mplab_instruction.rb
|
45
41
|
- lib/rpicsim/mplab/mplab_loader.rb
|
46
42
|
- lib/rpicsim/mplab/mplab_memory.rb
|
@@ -78,7 +74,6 @@ files:
|
|
78
74
|
- docs/Memories.md
|
79
75
|
- docs/PersistentExpectations.md
|
80
76
|
- docs/Pins.md
|
81
|
-
- docs/PreventingCallStackOverflow.md
|
82
77
|
- docs/QuickStartGuide.md
|
83
78
|
- docs/RamWatcher.md
|
84
79
|
- docs/RSpecIntegration.md
|