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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +36 -0
  3. data/Gemfile +10 -0
  4. data/Introduction.md +64 -0
  5. data/LICENSE.txt +24 -0
  6. data/README.md +66 -0
  7. data/docs/ChangeLog.md +10 -0
  8. data/docs/Contributing.md +30 -0
  9. data/docs/Debugging.md +96 -0
  10. data/docs/DefiningSimulationClass.md +84 -0
  11. data/docs/DesignDecisions.md +48 -0
  12. data/docs/HowMPLABXIsFound.md +14 -0
  13. data/docs/IntegrationTesting.md +15 -0
  14. data/docs/IntroductionToRSpec.md +203 -0
  15. data/docs/IntroductionToRuby.md +90 -0
  16. data/docs/KnownIssues.md +204 -0
  17. data/docs/Labels.md +39 -0
  18. data/docs/MakingTestsRunFaster.md +29 -0
  19. data/docs/Manual.md +38 -0
  20. data/docs/PersistentExpectations.md +100 -0
  21. data/docs/Pins.md +143 -0
  22. data/docs/PreventingCallStackOverflow.md +94 -0
  23. data/docs/QuickStartGuide.md +85 -0
  24. data/docs/RSpecIntegration.md +119 -0
  25. data/docs/RamWatcher.md +46 -0
  26. data/docs/Running.md +129 -0
  27. data/docs/SFRs.md +71 -0
  28. data/docs/Stubbing.md +161 -0
  29. data/docs/SupportedCompilers.md +5 -0
  30. data/docs/SupportedDevices.md +14 -0
  31. data/docs/SupportedMPLABXVersions.md +12 -0
  32. data/docs/SupportedOperatingSystems.md +3 -0
  33. data/docs/UnitTesting.md +9 -0
  34. data/docs/Variables.md +140 -0
  35. data/lib/rpicsim.rb +15 -0
  36. data/lib/rpicsim/call_stack_info.rb +306 -0
  37. data/lib/rpicsim/flaws.rb +76 -0
  38. data/lib/rpicsim/instruction.rb +178 -0
  39. data/lib/rpicsim/label.rb +28 -0
  40. data/lib/rpicsim/memory.rb +29 -0
  41. data/lib/rpicsim/memory_watcher.rb +98 -0
  42. data/lib/rpicsim/mplab.rb +138 -0
  43. data/lib/rpicsim/mplab/mplab_assembly.rb +102 -0
  44. data/lib/rpicsim/mplab/mplab_device_info.rb +40 -0
  45. data/lib/rpicsim/mplab/mplab_disassembler.rb +23 -0
  46. data/lib/rpicsim/mplab/mplab_instruction.rb +32 -0
  47. data/lib/rpicsim/mplab/mplab_memory.rb +33 -0
  48. data/lib/rpicsim/mplab/mplab_nmmr_info.rb +21 -0
  49. data/lib/rpicsim/mplab/mplab_observer.rb +12 -0
  50. data/lib/rpicsim/mplab/mplab_pin.rb +61 -0
  51. data/lib/rpicsim/mplab/mplab_processor.rb +30 -0
  52. data/lib/rpicsim/mplab/mplab_program_file.rb +35 -0
  53. data/lib/rpicsim/mplab/mplab_register.rb +25 -0
  54. data/lib/rpicsim/mplab/mplab_sfr_info.rb +21 -0
  55. data/lib/rpicsim/mplab/mplab_simulator.rb +102 -0
  56. data/lib/rpicsim/pin.rb +61 -0
  57. data/lib/rpicsim/program_counter.rb +19 -0
  58. data/lib/rpicsim/program_file.rb +160 -0
  59. data/lib/rpicsim/register.rb +78 -0
  60. data/lib/rpicsim/rspec.rb +11 -0
  61. data/lib/rpicsim/rspec/be_predicate.rb +12 -0
  62. data/lib/rpicsim/rspec/helpers.rb +48 -0
  63. data/lib/rpicsim/rspec/persistent_expectations.rb +53 -0
  64. data/lib/rpicsim/rspec/sim_diagnostics.rb +51 -0
  65. data/lib/rpicsim/search.rb +20 -0
  66. data/lib/rpicsim/sim.rb +702 -0
  67. data/lib/rpicsim/stack_trace.rb +32 -0
  68. data/lib/rpicsim/variable.rb +236 -0
  69. data/lib/rpicsim/version.rb +3 -0
  70. 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
@@ -0,0 +1,3 @@
1
+ module RPicSim
2
+ VERSION = '0.1.0'
3
+ 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: