rpicsim 0.1.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/.yardopts +36 -0
- data/Gemfile +10 -0
- data/Introduction.md +64 -0
- data/LICENSE.txt +24 -0
- data/README.md +66 -0
- data/docs/ChangeLog.md +10 -0
- data/docs/Contributing.md +30 -0
- data/docs/Debugging.md +96 -0
- data/docs/DefiningSimulationClass.md +84 -0
- data/docs/DesignDecisions.md +48 -0
- data/docs/HowMPLABXIsFound.md +14 -0
- data/docs/IntegrationTesting.md +15 -0
- data/docs/IntroductionToRSpec.md +203 -0
- data/docs/IntroductionToRuby.md +90 -0
- data/docs/KnownIssues.md +204 -0
- data/docs/Labels.md +39 -0
- data/docs/MakingTestsRunFaster.md +29 -0
- data/docs/Manual.md +38 -0
- data/docs/PersistentExpectations.md +100 -0
- data/docs/Pins.md +143 -0
- data/docs/PreventingCallStackOverflow.md +94 -0
- data/docs/QuickStartGuide.md +85 -0
- data/docs/RSpecIntegration.md +119 -0
- data/docs/RamWatcher.md +46 -0
- data/docs/Running.md +129 -0
- data/docs/SFRs.md +71 -0
- data/docs/Stubbing.md +161 -0
- data/docs/SupportedCompilers.md +5 -0
- data/docs/SupportedDevices.md +14 -0
- data/docs/SupportedMPLABXVersions.md +12 -0
- data/docs/SupportedOperatingSystems.md +3 -0
- data/docs/UnitTesting.md +9 -0
- data/docs/Variables.md +140 -0
- data/lib/rpicsim.rb +15 -0
- data/lib/rpicsim/call_stack_info.rb +306 -0
- data/lib/rpicsim/flaws.rb +76 -0
- data/lib/rpicsim/instruction.rb +178 -0
- data/lib/rpicsim/label.rb +28 -0
- data/lib/rpicsim/memory.rb +29 -0
- data/lib/rpicsim/memory_watcher.rb +98 -0
- data/lib/rpicsim/mplab.rb +138 -0
- data/lib/rpicsim/mplab/mplab_assembly.rb +102 -0
- data/lib/rpicsim/mplab/mplab_device_info.rb +40 -0
- data/lib/rpicsim/mplab/mplab_disassembler.rb +23 -0
- data/lib/rpicsim/mplab/mplab_instruction.rb +32 -0
- data/lib/rpicsim/mplab/mplab_memory.rb +33 -0
- data/lib/rpicsim/mplab/mplab_nmmr_info.rb +21 -0
- data/lib/rpicsim/mplab/mplab_observer.rb +12 -0
- data/lib/rpicsim/mplab/mplab_pin.rb +61 -0
- data/lib/rpicsim/mplab/mplab_processor.rb +30 -0
- data/lib/rpicsim/mplab/mplab_program_file.rb +35 -0
- data/lib/rpicsim/mplab/mplab_register.rb +25 -0
- data/lib/rpicsim/mplab/mplab_sfr_info.rb +21 -0
- data/lib/rpicsim/mplab/mplab_simulator.rb +102 -0
- data/lib/rpicsim/pin.rb +61 -0
- data/lib/rpicsim/program_counter.rb +19 -0
- data/lib/rpicsim/program_file.rb +160 -0
- data/lib/rpicsim/register.rb +78 -0
- data/lib/rpicsim/rspec.rb +11 -0
- data/lib/rpicsim/rspec/be_predicate.rb +12 -0
- data/lib/rpicsim/rspec/helpers.rb +48 -0
- data/lib/rpicsim/rspec/persistent_expectations.rb +53 -0
- data/lib/rpicsim/rspec/sim_diagnostics.rb +51 -0
- data/lib/rpicsim/search.rb +20 -0
- data/lib/rpicsim/sim.rb +702 -0
- data/lib/rpicsim/stack_trace.rb +32 -0
- data/lib/rpicsim/variable.rb +236 -0
- data/lib/rpicsim/version.rb +3 -0
- metadata +114 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
module RPicSim
|
2
|
+
class StackTrace
|
3
|
+
attr_reader :entries
|
4
|
+
|
5
|
+
def initialize(entries = [])
|
6
|
+
@entries = entries
|
7
|
+
end
|
8
|
+
|
9
|
+
def output(io, padding='')
|
10
|
+
@entries.reverse_each do |entry|
|
11
|
+
output_entry(entry, io, padding)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def output_entry(entry, io, padding)
|
16
|
+
io.puts padding + entry.description
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class StackTraceEntry
|
21
|
+
attr_reader :address, :description
|
22
|
+
|
23
|
+
def initialize(address, description)
|
24
|
+
@address = address
|
25
|
+
@description = description
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
description
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
module RPicSim
|
2
|
+
# This class and its subclasses represent firmware-defined variables
|
3
|
+
# in RAM or flash.
|
4
|
+
#
|
5
|
+
# Instances of this class come in two varieties:
|
6
|
+
# - Unbound variables are just a name and an address.
|
7
|
+
# - Bound variables have a name and an address and they are attached to
|
8
|
+
# a memory object so you can actually read and write values from them.
|
9
|
+
class Variable
|
10
|
+
module ClassMethods
|
11
|
+
# @return (Integer) The size of this type of variable in memory words.
|
12
|
+
attr_reader :size
|
13
|
+
|
14
|
+
# Specifies the size of this class of variables in memory words.
|
15
|
+
# The units for this are usually bytes for RAM and more than a byte
|
16
|
+
# for flash. This should be called inside the definition of a subclass of
|
17
|
+
# {Variable}, not from anywhere else.
|
18
|
+
def size_is(size)
|
19
|
+
@size = size
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
extend ClassMethods
|
24
|
+
|
25
|
+
attr_reader :name, :address
|
26
|
+
attr_writer :memory
|
27
|
+
|
28
|
+
# Creates a new Variable object not bound to any memory yet.
|
29
|
+
# @param name [Symbol] The name of the variable.
|
30
|
+
# @param address [Integer] should be the address of the variable
|
31
|
+
def initialize(name, address)
|
32
|
+
@name = name
|
33
|
+
@address = address
|
34
|
+
end
|
35
|
+
|
36
|
+
# Creates a new Variable that is bound to the specified memory.
|
37
|
+
# @param memory [RPicSim::Memory]
|
38
|
+
def bind(memory)
|
39
|
+
bound_var = dup
|
40
|
+
bound_var.memory = memory
|
41
|
+
bound_var
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Range] The addresses of each byte that is part of this variable.
|
45
|
+
def addresses
|
46
|
+
address ... (address + self.class.size)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Reads the value of the variable from memory.
|
50
|
+
# @return [Integer]
|
51
|
+
def value
|
52
|
+
raise NoMethodError, "value not implemented"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Writes to the value to the variable's memory.
|
56
|
+
# @return [Integer]
|
57
|
+
def value=(val)
|
58
|
+
raise NoMethodError, "value= not implemented"
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
name.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
def inspect
|
66
|
+
"<%s %s 0x%x>" % [self.class, name, address]
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def check_value(value, allowed_values)
|
71
|
+
if !allowed_values.include?(value)
|
72
|
+
raise ArgumentError, "Invalid value #{value} written to #{name}."
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Represents an unsigned 8-bit variable.
|
78
|
+
class VariableU8 < Variable
|
79
|
+
size_is 1
|
80
|
+
|
81
|
+
def value
|
82
|
+
@memory.read_word(@address)
|
83
|
+
end
|
84
|
+
|
85
|
+
def value=(val)
|
86
|
+
check_value val, 0..255
|
87
|
+
@memory.write_word(@address, val)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
# Represents a signed 8-bit variable.
|
93
|
+
class VariableS8 < Variable
|
94
|
+
size_is 1
|
95
|
+
|
96
|
+
def value
|
97
|
+
val = @memory.read_word(@address)
|
98
|
+
val -= 0x100 if val >= 0x80
|
99
|
+
val
|
100
|
+
end
|
101
|
+
|
102
|
+
def value=(val)
|
103
|
+
check_value val, -0x80...0x80
|
104
|
+
@memory.write_word(@address, val & 0xFF)
|
105
|
+
@memory.write_word(@address + 1, (val >> 8) & 0xFF)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Represents an unsigned 16-bit variable.
|
110
|
+
class VariableU16 < Variable
|
111
|
+
size_is 2
|
112
|
+
|
113
|
+
def value
|
114
|
+
@memory.read_word(@address) + 256 * @memory.read_word(@address + 1)
|
115
|
+
end
|
116
|
+
|
117
|
+
def value=(val)
|
118
|
+
check_value val, 0...0x10000
|
119
|
+
@memory.write_word(@address, val & 0xFF)
|
120
|
+
@memory.write_word(@address + 1, (val >> 8) & 0xFF)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Represents a signed 16-bit variable.
|
125
|
+
class VariableS16 < Variable
|
126
|
+
size_is 2
|
127
|
+
|
128
|
+
def value
|
129
|
+
val = @memory.read_word(@address) + 256 * @memory.read_word(@address + 1)
|
130
|
+
val -= 0x10000 if val >= 0x8000
|
131
|
+
val
|
132
|
+
end
|
133
|
+
|
134
|
+
def value=(val)
|
135
|
+
check_value val, -0x8000...0x8000
|
136
|
+
@memory.write_word(@address, val & 0xFF)
|
137
|
+
@memory.write_word(@address + 1, (val >> 8) & 0xFF)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Represents an unsigned 24-bit variable.
|
142
|
+
class VariableU24 < Variable
|
143
|
+
size_is 3
|
144
|
+
|
145
|
+
def value
|
146
|
+
@memory.read_word(@address) + 0x100 * @memory.read_word(@address + 1) +
|
147
|
+
0x10000 * @memory.read_word(@address + 2)
|
148
|
+
end
|
149
|
+
|
150
|
+
def value=(val)
|
151
|
+
check_value val, 0...0x1000000
|
152
|
+
@memory.write_word(@address, val & 0xFF)
|
153
|
+
@memory.write_word(@address + 1, (val >> 8) & 0xFF)
|
154
|
+
@memory.write_word(@address + 2, (val >> 16) & 0xFF)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Represents a signed 24-bit variable.
|
159
|
+
class VariableS24 < Variable
|
160
|
+
size_is 3
|
161
|
+
|
162
|
+
def value
|
163
|
+
val = @memory.read_word(@address) + 0x100 * @memory.read_word(@address + 1) +
|
164
|
+
0x10000 * @memory.read_word(@address + 2)
|
165
|
+
val -= 0x1000000 if val >= 0x800000
|
166
|
+
val
|
167
|
+
end
|
168
|
+
|
169
|
+
def value=(val)
|
170
|
+
check_value val, -0x800000..0x800000
|
171
|
+
@memory.write_word(@address, val & 0xFF)
|
172
|
+
@memory.write_word(@address + 1, (val >> 8) & 0xFF)
|
173
|
+
@memory.write_word(@address + 2, (val >> 16) & 0xFF)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Represents an unsigned 32-bit variable.
|
178
|
+
class VariableU32 < Variable
|
179
|
+
size_is 4
|
180
|
+
|
181
|
+
def value
|
182
|
+
@memory.read_word(@address) + 0x100 * @memory.read_word(@address + 1) +
|
183
|
+
0x10000 * @memory.read_word(@address + 2) +
|
184
|
+
0x1000000 * @memory.read_word(@address + 3)
|
185
|
+
end
|
186
|
+
|
187
|
+
def value=(val)
|
188
|
+
check_value val, 0...0x100000000
|
189
|
+
@memory.write_word(@address, val & 0xFF)
|
190
|
+
@memory.write_word(@address + 1, (val >> 8) & 0xFF)
|
191
|
+
@memory.write_word(@address + 2, (val >> 16) & 0xFF)
|
192
|
+
@memory.write_word(@address + 3, (val >> 24) & 0xFF)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Represents a signed 32-bit variable.
|
197
|
+
class VariableS32 < Variable
|
198
|
+
size_is 4
|
199
|
+
|
200
|
+
def value
|
201
|
+
val = @memory.read_word(@address) + 0x100 * @memory.read_word(@address + 1) +
|
202
|
+
0x10000 * @memory.read_word(@address + 2) +
|
203
|
+
0x1000000 * @memory.read_word(@address + 3) +
|
204
|
+
0x100000000 * @memory.read_word(@address + 4)
|
205
|
+
val -= 0x100000000 if val >= 0x80000000
|
206
|
+
val
|
207
|
+
end
|
208
|
+
|
209
|
+
def value=(val)
|
210
|
+
check_value val, -0x80000000..0x80000000
|
211
|
+
@memory.write_word(@address, val & 0xFF)
|
212
|
+
@memory.write_word(@address + 1, (val >> 8) & 0xFF)
|
213
|
+
@memory.write_word(@address + 2, (val >> 16) & 0xFF)
|
214
|
+
@memory.write_word(@address + 3, (val >> 24) & 0xFF)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Represents a word-sized variable.
|
219
|
+
# The size of the word will depend on the memory the variable lives in.
|
220
|
+
class VariableWord < Variable
|
221
|
+
size_is 1
|
222
|
+
|
223
|
+
attr_writer :max_value
|
224
|
+
|
225
|
+
def value
|
226
|
+
@memory.read_word(@address)
|
227
|
+
end
|
228
|
+
|
229
|
+
def value=(val)
|
230
|
+
if @max_value
|
231
|
+
check_value val, 0..@max_value
|
232
|
+
end
|
233
|
+
@memory.write_word(@address, val)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rpicsim
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pololu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-22 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- .yardopts
|
20
|
+
- Gemfile
|
21
|
+
- Introduction.md
|
22
|
+
- LICENSE.txt
|
23
|
+
- README.md
|
24
|
+
- docs/ChangeLog.md
|
25
|
+
- docs/Contributing.md
|
26
|
+
- docs/Debugging.md
|
27
|
+
- docs/DefiningSimulationClass.md
|
28
|
+
- docs/DesignDecisions.md
|
29
|
+
- docs/HowMPLABXIsFound.md
|
30
|
+
- docs/IntegrationTesting.md
|
31
|
+
- docs/IntroductionToRSpec.md
|
32
|
+
- docs/IntroductionToRuby.md
|
33
|
+
- docs/KnownIssues.md
|
34
|
+
- docs/Labels.md
|
35
|
+
- docs/MakingTestsRunFaster.md
|
36
|
+
- docs/Manual.md
|
37
|
+
- docs/PersistentExpectations.md
|
38
|
+
- docs/Pins.md
|
39
|
+
- docs/PreventingCallStackOverflow.md
|
40
|
+
- docs/QuickStartGuide.md
|
41
|
+
- docs/RSpecIntegration.md
|
42
|
+
- docs/RamWatcher.md
|
43
|
+
- docs/Running.md
|
44
|
+
- docs/SFRs.md
|
45
|
+
- docs/Stubbing.md
|
46
|
+
- docs/SupportedCompilers.md
|
47
|
+
- docs/SupportedDevices.md
|
48
|
+
- docs/SupportedMPLABXVersions.md
|
49
|
+
- docs/SupportedOperatingSystems.md
|
50
|
+
- docs/UnitTesting.md
|
51
|
+
- docs/Variables.md
|
52
|
+
- lib/rpicsim.rb
|
53
|
+
- lib/rpicsim/call_stack_info.rb
|
54
|
+
- lib/rpicsim/flaws.rb
|
55
|
+
- lib/rpicsim/instruction.rb
|
56
|
+
- lib/rpicsim/label.rb
|
57
|
+
- lib/rpicsim/memory.rb
|
58
|
+
- lib/rpicsim/memory_watcher.rb
|
59
|
+
- lib/rpicsim/mplab.rb
|
60
|
+
- lib/rpicsim/mplab/mplab_assembly.rb
|
61
|
+
- lib/rpicsim/mplab/mplab_device_info.rb
|
62
|
+
- lib/rpicsim/mplab/mplab_disassembler.rb
|
63
|
+
- lib/rpicsim/mplab/mplab_instruction.rb
|
64
|
+
- lib/rpicsim/mplab/mplab_memory.rb
|
65
|
+
- lib/rpicsim/mplab/mplab_nmmr_info.rb
|
66
|
+
- lib/rpicsim/mplab/mplab_observer.rb
|
67
|
+
- lib/rpicsim/mplab/mplab_pin.rb
|
68
|
+
- lib/rpicsim/mplab/mplab_processor.rb
|
69
|
+
- lib/rpicsim/mplab/mplab_program_file.rb
|
70
|
+
- lib/rpicsim/mplab/mplab_register.rb
|
71
|
+
- lib/rpicsim/mplab/mplab_sfr_info.rb
|
72
|
+
- lib/rpicsim/mplab/mplab_simulator.rb
|
73
|
+
- lib/rpicsim/pin.rb
|
74
|
+
- lib/rpicsim/program_counter.rb
|
75
|
+
- lib/rpicsim/program_file.rb
|
76
|
+
- lib/rpicsim/register.rb
|
77
|
+
- lib/rpicsim/rspec.rb
|
78
|
+
- lib/rpicsim/rspec/be_predicate.rb
|
79
|
+
- lib/rpicsim/rspec/helpers.rb
|
80
|
+
- lib/rpicsim/rspec/persistent_expectations.rb
|
81
|
+
- lib/rpicsim/rspec/sim_diagnostics.rb
|
82
|
+
- lib/rpicsim/search.rb
|
83
|
+
- lib/rpicsim/sim.rb
|
84
|
+
- lib/rpicsim/stack_trace.rb
|
85
|
+
- lib/rpicsim/variable.rb
|
86
|
+
- lib/rpicsim/version.rb
|
87
|
+
homepage: https://github.com/pololu/rpicsim
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '2'
|
105
|
+
requirements:
|
106
|
+
- JRuby
|
107
|
+
- MPLAB X
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.2.1
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: RPicSim provides an interface to the MPLAB X PIC simulator that allows you to write simulator-based automated tests of PIC firmware with Ruby and RSpec.
|
113
|
+
test_files: []
|
114
|
+
has_rdoc:
|