rpicsim 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a7dd67ae71f9052d9fa174cace952aa468a0001d
4
- data.tar.gz: 72a07a6240931d85054651627a017677924d1a9e
3
+ metadata.gz: 5b6af21f7563390039da12c8b89f5680a02cb986
4
+ data.tar.gz: 1b76b192dcbea43027d5279cebc2f4949c42377d
5
5
  SHA512:
6
- metadata.gz: 94d406a34b8dc47900a487a306a3071ec2a441b039e6696c4f3c422cb2d92c27c0b200d13ea80e537df9b73dab4657db9edcf102d94fa3a7b516d39aa5128c55
7
- data.tar.gz: 7c332af37e3563c1b12249c1fa690ca07f297dbb56175403b7b2d3c333fc3fdddd95825919ce40cafe90c1f1eb533a11842e61276a0b5652d765d26431637d73
6
+ metadata.gz: ac3c2f02ad9039fc16940f436cc35bffe710c028e084f52f23c4b4c81d4d4ead4b982af6032529b4259e2ef39e21d130fecead04486d70b3cdd7cbdc95ee936f
7
+ data.tar.gz: fedd8d6089a28a1e7395beb446e7a7467778c69c696e3a6e7fffa5eb2910cf15cf370b51f268e49e379b8f33116c88197e1b571ac7778b58b6495c28615c4ff7
data/.yardopts CHANGED
@@ -1,6 +1,9 @@
1
+ lib/rpicsim.rb
2
+ lib/rpicsim/mplab.rb
1
3
  lib/rpicsim/**/*.rb
2
4
  --readme Introduction.md
3
5
  --load docs/plugin/plugin.rb
6
+ --api public
4
7
  -
5
8
  docs/Manual.md
6
9
  docs/ChangeLog.md
@@ -18,7 +21,6 @@ docs/Manual.md
18
21
  docs/Variables.md
19
22
  docs/Memories.md
20
23
  docs/RamWatcher.md
21
- docs/PreventingCallStackOverflow.md
22
24
 
23
25
  docs/IntroductionToRSpec.md
24
26
  docs/UnitTesting.md
data/Introduction.md CHANGED
@@ -44,14 +44,12 @@ RPicSim has features that allow you to:
44
44
  * Monitor all writes to RAM.
45
45
  * Run assertions at every step of a simulation.
46
46
 
47
- For some applications, RPicSim can also analyze the firmware and verify that the call stack will never overflow.
48
-
49
47
  RPicSim is distributed as a Ruby gem named `rpicsim`. To install RPicSim, run:
50
48
 
51
49
  jgem install rpicsim
52
50
 
53
51
 
54
- RPicSim has been tested with MPLAB X v1.85, v1.90, v1.95, v2.00, v2.05, and v2.10.
52
+ RPicSim has been tested with MPLAB X v1.85, v1.90, v1.95, v2.00, v2.05, v2.10, v2.15, and v2.20.
55
53
  However, it uses a lot of undocumented and internal features of the Microchip Java libraries, so it will probably need to be updated as new versions of MPLAB X are released.
56
54
 
57
55
  RPicSim is not intended to replace formal specifications, code reviews, and rigorous testing of your firmware on actual hardware.
data/README.md CHANGED
@@ -46,14 +46,12 @@ RPicSim has features that allow you to:
46
46
  * Monitor all writes to RAM.
47
47
  * Run assertions at every step of a simulation.
48
48
 
49
- For some applications, RPicSim can also analyze the firmware and verify that the call stack will never overflow.
50
-
51
49
  RPicSim is distributed as a Ruby gem named `rpicsim`. To install RPicSim, run:
52
50
 
53
51
  jgem install rpicsim
54
52
 
55
53
 
56
- RPicSim has been tested with MPLAB X v1.85, v1.90, v1.95, v2.00, v2.05, and v2.10.
54
+ RPicSim has been tested with MPLAB X v1.85, v1.90, v1.95, v2.00, v2.05, v2.10, v2.15, and v2.20.
57
55
  However, it uses a lot of undocumented and internal features of the Microchip Java libraries, so it will probably need to be updated as new versions of MPLAB X are released.
58
56
 
59
57
  RPicSim is not intended to replace formal specifications, code reviews, and rigorous testing of your firmware on actual hardware.
data/docs/ChangeLog.md CHANGED
@@ -1,6 +1,17 @@
1
1
  Change log
2
2
  ====
3
3
 
4
+ 1.0.0
5
+ ----
6
+ Released on 2014-09-17.
7
+
8
+ - Major improvements to the documentation. Mainly, the public API of RPicSim has been defined, and everything not in the public API is now hidden from the documentation. Doing this allows us to follow [Semantic Versioning](http://semver.org/spec/v2.0.0.html) from now on.
9
+ - MemoryWatcher: Adds WREG and BSR to the default list of registers to ignore.
10
+ - Removed all disassembly and static analysis features, since they could be better implemented in a different gem that doesn't depend on any Microchip code:
11
+ - Removed RPicSim::ProgramFile#instruction
12
+ - Removed RPicSim::CallStackInfo
13
+ - Removed RPicSim::Instruction
14
+
4
15
  0.4.0
5
16
  ----
6
17
  Released on 2014-07-30.
@@ -15,6 +26,8 @@ Released on 2014-07-30.
15
26
  - Adds the {RPicSim::Xc8SymFile} class, which can load symbols from a SYM file produced by the XC8 compiler and then be passed to {RPicSim::Sim::ClassDefinitionMethods#import_symbols import_symbols}. This was necessary because the COF files produced by XC8 are difficult to interpret and do not always allow us to tell what memory space a given symbol is for.
16
27
  - {RPicSim::Sim::ClassMethods#label #label} and {RPicSim::Sim::ClassMethods#labels #labels} methods are now available on both instances of a simulation class or on a simulation class itself.
17
28
 
29
+ MPLAB X v2.15 and v2.20 were released after RPicSim 0.4.0, but the changes in those versions of MPLAB X were minor enough that RPicSim 0.4.0 should work with them.
30
+
18
31
  0.3.0
19
32
  ----
20
33
  Released on 2014-06-20.
data/docs/KnownIssues.md CHANGED
@@ -112,11 +112,11 @@ Pins report the wrong output state if TRISx is cleared again
112
112
  ----
113
113
  _Type: MPLAB X bug_
114
114
 
115
- _MPLAB X versions affected: all tested versions_
115
+ _MPLAB X versions affected: 1.85 through 2.10_
116
116
 
117
117
  Even if you set up the pin properly (working around all the issues above) and get {RPicSim::Pin#driving_high?} to return true, a `bcf` instruction on the pin's TRISx bit (or probably any write to the TRISx register) will cause the pin to start reporting the wrong output state.
118
118
 
119
- This issue is tested in `spec/integration/pin_spec.rb`.
119
+ This issue is tested in `spec/integration/pin_spec.rb`, and was fixed in MPLAB X v2.15.
120
120
 
121
121
 
122
122
  RAM watcher is useless because all of RAM seems to change on every step
data/docs/Manual.md CHANGED
@@ -20,7 +20,6 @@ This is the table of contents for the RPicSim manual.
20
20
  * {file:Variables.md}
21
21
  * {file:Memories.md}
22
22
  * {file:RamWatcher.md RAM watcher}
23
- * {file:PreventingCallStackOverflow.md Preventing call stack overflow}
24
23
  * Testing firmware with RPicSim and RSpec
25
24
  * {file:IntroductionToRSpec.md Introduction to RSpec}
26
25
  * {file:UnitTesting.md Unit testing}
@@ -13,7 +13,30 @@ To enable the RSpec integration, simply put this line in your `spec_helper.rb`:
13
13
  !!!ruby
14
14
  require 'rpicsim/rspec'
15
15
 
16
- The features that this gives you are documented below.
16
+ That gives you all the features that are documented below.
17
+
18
+ ### Fine-grained configuration
19
+
20
+ Alternatively, if you just want a subset of the features described here, you can use any combination of the snippets below:
21
+
22
+ # Persistent expectations that can be stored and checked later
23
+ require 'rpicsim/rspec/persistent_expectations'
24
+ RSpec.configure { |c| c.include RPicSim::RSpec::PersistentExpectations }
25
+
26
+ <!-- separate -->
27
+
28
+ # Helper methods, including persistent expectations
29
+ require 'rpicsim/rspec/helpers'
30
+
31
+ <!-- separate -->
32
+
33
+ # Show debug info from sim if a spec fails
34
+ require 'rpicsim/rspec/sim_diagnostics'
35
+
36
+ <!-- separate -->
37
+
38
+ # Better error messages for RSpec 2.x
39
+ require 'rpicsim/rspec/be_predicate'
17
40
 
18
41
 
19
42
  Helper methods
@@ -8,6 +8,8 @@ RPicSim uses code in MPLAB X to actually perform the PIC simulation. Therefore,
8
8
  - 2.00
9
9
  - 2.05
10
10
  - 2.10
11
+ - 2.15
12
+ - 2.20
11
13
 
12
14
  The different versions of MPLAB X have different problems that affect the simulation. For more information, see the {file:KnownIssues.md Known issues page}.
13
15
 
data/lib/rpicsim.rb CHANGED
@@ -1,4 +1,9 @@
1
1
  require_relative 'rpicsim/version'
2
2
  require_relative 'rpicsim/sim'
3
- require_relative 'rpicsim/call_stack_info'
4
3
  require_relative 'rpicsim/xc8_sym_file'
4
+
5
+ # Top-level module for the RPicSim gem.
6
+ #
7
+ # @api public
8
+ module RPicSim
9
+ end
@@ -1,8 +1,11 @@
1
+ # @api public
1
2
  module RPicSim
2
3
  # This class wraps two or more memory objects and
3
4
  # provides an interface that is also like {RPicSim::Memory}.
4
5
  # Any reads or writes from the composite memory will go to the first
5
6
  # component memory for which the address is valid.
7
+ #
8
+ # @api private
6
9
  class CompositeMemory
7
10
  # Creates a new instance.
8
11
  # The memory objects given must support the following methods:
data/lib/rpicsim/flaws.rb CHANGED
@@ -1,11 +1,18 @@
1
+ # @api public
1
2
  module RPicSim
3
+ # This module stores knowledge about flaw in RPicSim, usually due to bugs or
4
+ # limitation of the MPLAB X classes we are using. See {file:KnownIssues.md}
5
+ # for more details.
6
+ #
7
+ # @api public
2
8
  module Flaws
3
- # Represents a flaw in RPicSim, usually due to bugs or limitation of the
4
- # MPLAB X classes we are using. Stores the name of the flaw and knowledge
5
- # about what versions of MPLAB X it affects and how.
9
+ # Represents a flaw in RPicSim, usually dues to bugs in the MPLAB X classes
10
+ # we are using. Stores the name of the flaw and knowledge about what
11
+ # versions of MPLAB X it affects and how.
6
12
  class Flaw
7
13
  # Creates a new flaw with the specified name.
8
14
  # @param name [Symbol] The name of this flaw.
15
+ # @api private
9
16
  def initialize(name)
10
17
  @versions = {}
11
18
  end
@@ -15,7 +22,7 @@ module RPicSim
15
22
  # might be a more complicated thing if there is more than one effect the
16
23
  # the flaw can have.
17
24
  #
18
- # @param version [String] A version of MPLAB X, e.g. "1.95".
25
+ # @param version [String] A version of MPLAB X, e.g. +'1.95'+.
19
26
  # @return effect
20
27
  def effect(version)
21
28
  if @versions.key? version
@@ -26,6 +33,7 @@ module RPicSim
26
33
  end
27
34
 
28
35
  # Records the effect this flaw has on a given version of MPLAB X.
36
+ # @api private
29
37
  def affects_version(version, effect)
30
38
  @versions[version] = effect
31
39
  end
@@ -33,21 +41,37 @@ module RPicSim
33
41
  # Records the effect that this flaw probably has in other versions of
34
42
  # MPLAB X that have not been tested. This allows us to record our guesses
35
43
  # about how the next version of MPLAB X will behave.
44
+ # @api private
36
45
  def probably_affects_other_versions(effect)
37
46
  @probable_affect_for_other_versions = effect
38
47
  end
39
48
  end
40
49
 
41
50
  @flaw_hash = {}
51
+
52
+ # Returns the {Flaw} with the specified name.
53
+ # @param name [Symbol] The name of the flaw. The names are listed in +flaws.rb+.
54
+ # @return [Flaw]
42
55
  def self.[](name)
43
56
  @flaw_hash[name].effect Mplab.version
44
57
  end
45
58
 
59
+ # @api private
46
60
  def self.add(name)
47
61
  @flaw_hash[name] = flaw = Flaw.new(name)
48
62
  yield flaw
49
63
  end
50
64
 
65
+ add(:writing_tris_affects_output) do |flaw|
66
+ flaw.affects_version '1.85', true
67
+ flaw.affects_version '1.90', true
68
+ flaw.affects_version '1.95', true
69
+ flaw.affects_version '2.00', true
70
+ flaw.affects_version '2.05', true
71
+ flaw.affects_version '2.10', true
72
+ flaw.probably_affects_other_versions false
73
+ end
74
+
51
75
  add(:fr_memory_attach_useless) do |flaw|
52
76
  flaw.affects_version '1.85', false
53
77
  flaw.affects_version '1.90', false
data/lib/rpicsim/label.rb CHANGED
@@ -1,5 +1,7 @@
1
+ # @api public
1
2
  module RPicSim
2
3
  # A very simple class that represents a label in firmware.
4
+ # @api public
3
5
  class Label
4
6
  # The name of the label from the firmware.
5
7
  # @return (Symbol)
@@ -10,17 +12,22 @@ module RPicSim
10
12
  attr_reader :address
11
13
 
12
14
  # Makes a new label with the specified name and address.
15
+ # @api private
13
16
  def initialize(name, address)
14
17
  @name = name
15
18
  @address = address
16
19
  end
17
20
 
18
21
  # Returns the address of the label.
22
+ #
23
+ # @return [Integer]
19
24
  def to_i
20
25
  address
21
26
  end
22
27
 
23
28
  # Returns a nice string representation of the label.
29
+ #
30
+ # @return [String]
24
31
  def to_s
25
32
  '<Label %s address=0x%x>' % [name, address]
26
33
  end
@@ -1,3 +1,4 @@
1
+ # @api public
1
2
  module RPicSim
2
3
  # This object allows read and write access to the data currently
3
4
  # stored in a memory space of the simulated device.
@@ -20,8 +21,11 @@ module RPicSim
20
21
  # +read_word+ and +write_word+.
21
22
  #
22
23
  # For more information, see {file:Memories.md}.
24
+ #
25
+ # @api public
23
26
  class Memory
24
27
  # @param mplab_memory [Mplab::Memory]
28
+ # @api private
25
29
  def initialize(mplab_memory)
26
30
  @mplab_memory = mplab_memory
27
31
  end
@@ -1,5 +1,6 @@
1
1
  require 'set'
2
2
 
3
+ # @api public
3
4
  module RPicSim
4
5
  # This class can attach to an MPLAB X memory class and watch for changes in it, and
5
6
  # report those changes as a hash associating variable names to new values. This is
@@ -9,9 +10,15 @@ module RPicSim
9
10
  # This class does not analyze the current instruction being executed; it uses the
10
11
  # Attach method of the MPLAB X memory classes. This means that it doesn't work properly
11
12
  # in some versions of MPLAB X. See {file:docs/Flaws.textile}.
13
+ #
14
+ # @api public
12
15
  class MemoryWatcher
16
+ # Allows you to read or write the list of variable names whose changes will
17
+ # be ignored. By default, this includes registers like WREG and STATUS that
18
+ # change a lot.
19
+ #
20
+ # @return [Array(Symbol)]
13
21
  attr_accessor :var_names_ignored
14
- attr_accessor :var_names_ignored_on_first_step
15
22
 
16
23
  # Creates a new instance.
17
24
  # @param sim [Sim]
@@ -61,6 +68,8 @@ module RPicSim
61
68
  @vars_written.clear
62
69
  end
63
70
 
71
+ private
72
+
64
73
  def handle_change(address_ranges)
65
74
  addresses = address_ranges.flat_map(&:to_a)
66
75
  vars = addresses.map { |a| @vars_by_address[a] || a }
@@ -71,8 +80,6 @@ module RPicSim
71
80
  @vars_written.merge vars
72
81
  end
73
82
 
74
- private
75
-
76
83
  def remove_vars(vars, var_names_to_remove)
77
84
  vars.reject! do |key, val|
78
85
  name = key.is_a?(Integer) ? key : key.name
@@ -84,7 +91,7 @@ module RPicSim
84
91
  # The datasheet says the PCLATH is not affected by pushing or popping the stack, but
85
92
  # we still get spurious events for it when a return instruction is executed.
86
93
 
87
- [:PCL, :PCLATH, :STATUS]
94
+ [:PCL, :PCLATH, :WREG, :STATUS, :BSR]
88
95
  end
89
96
  end
90
97
  end
data/lib/rpicsim/mplab.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require_relative 'mplab/mplab_loader'
2
2
 
3
+ # @api private
3
4
  module RPicSim::Mplab
4
5
  MplabLoader.instance.load
5
6
 
@@ -1,6 +1,5 @@
1
1
  require_relative 'mplab_device_info'
2
2
  require_relative 'mplab_simulator'
3
- require_relative 'mplab_disassembler'
4
3
 
5
4
  module RPicSim::Mplab
6
5
  # This class wraps objects belonging to the abstract Java class
data/lib/rpicsim/pin.rb CHANGED
@@ -1,10 +1,14 @@
1
+ # @api public
1
2
  module RPicSim
2
3
  # This class represents an external pin of the simulated device.
3
4
  # It provides methods for reading the pin's output value and setting
4
5
  # its input value.
6
+ #
7
+ # @api public
5
8
  class Pin
6
9
  # Initializes a new Pin object to wrap the given MplabPin.
7
10
  # @param mplab_pin [Mplab::MplabPin]
11
+ # @api private
8
12
  def initialize(mplab_pin)
9
13
  raise ArgumentError, 'mplab_pin is nil' if mplab_pin.nil?
10
14
  @mplab_pin = mplab_pin
@@ -46,14 +50,17 @@ module RPicSim
46
50
 
47
51
  # Returns an array of all the pin's names from the datasheet, like
48
52
  # "RA4" or "TX".
53
+ # @return [String]
49
54
  def names
50
55
  @mplab_pin.names
51
56
  end
52
57
 
58
+ # @return [String]
53
59
  def to_s
54
60
  @mplab_pin.name
55
61
  end
56
62
 
63
+ # @return [String]
57
64
  def inspect
58
65
  '#<%s %s>' % [self.class, to_s]
59
66
  end
@@ -1,16 +1,20 @@
1
+ # @api public
1
2
  module RPicSim
2
3
  # Instances of this class represent the program counter in a
3
4
  # simulated microcontroller.
5
+ # @api public
4
6
  class ProgramCounter
5
7
  # @param processor [Mplab::Processor]
6
8
  def initialize(processor)
7
9
  @processor = processor
8
10
  end
9
11
 
12
+ # @return [Integer]
10
13
  def value
11
14
  @processor.get_pc
12
15
  end
13
16
 
17
+ # @param val [Integer]
14
18
  def value=(val)
15
19
  @processor.set_pc(val)
16
20
  end
@@ -1,19 +1,27 @@
1
1
  require_relative 'mplab'
2
2
  require_relative 'label'
3
- require_relative 'instruction'
4
3
  require_relative 'symbol_set'
5
4
 
6
5
  # TODO: When symbols have the same address, think about how to choose the more
7
6
  # interesting one in a stack trace (fewer underscores?)
8
7
 
8
+ # @api public
9
9
  module RPicSim
10
10
  # Represents a PIC program file (e.g. COF or HEX).
11
11
  # Keeps track of all the symbols loaded from that file and also allows you
12
12
  # to add symbols in various ways.
13
+ #
14
+ # @api public
13
15
  class ProgramFile
16
+ # @return [String]
14
17
  attr_reader :filename
18
+
19
+ # The name of the device the file is for (e.g. "PIC10F322").
20
+ #
21
+ # @return [String]
15
22
  attr_reader :device
16
23
 
24
+ # @api private
17
25
  attr_reader :address_increment
18
26
 
19
27
  # @param filename [String] The path to the program file.
@@ -28,8 +36,6 @@ module RPicSim
28
36
  @assembly.load_file(filename)
29
37
  @address_increment = @assembly.device_info.code_address_increment
30
38
 
31
- @instructions = []
32
-
33
39
  @labels = {}
34
40
 
35
41
  @symbol_set = SymbolSet.new
@@ -90,6 +96,8 @@ module RPicSim
90
96
  #
91
97
  # Warning: This is a persistent hash that will automatically be updated when
92
98
  # new symbols are defined.
99
+ #
100
+ # @return [Hash]
93
101
  def symbols
94
102
  @symbol_set.symbols
95
103
  end
@@ -100,6 +108,8 @@ module RPicSim
100
108
  #
101
109
  # Warning: This is a persistent hash that will automatically be updated when
102
110
  # new symbols are defined.
111
+ #
112
+ # @return [Hash]
103
113
  def symbols_in_ram
104
114
  @symbol_set.symbols_in_memory(:ram)
105
115
  end
@@ -110,6 +120,8 @@ module RPicSim
110
120
  #
111
121
  # Warning: This is a persistent hash that will automatically be updated when
112
122
  # new symbols are defined.
123
+ #
124
+ # @return [Hash]
113
125
  def symbols_in_program_memory
114
126
  @symbol_set.symbols_in_memory(:program_memory)
115
127
  end
@@ -120,17 +132,21 @@ module RPicSim
120
132
  #
121
133
  # Warning: This is a persistent hash that will automatically be updated when
122
134
  # new symbols are defined.
135
+ #
136
+ # @return [Hash]
123
137
  def symbols_in_eeprom
124
138
  @symbol_set.symbols_in_memory(:eeprom)
125
139
  end
126
140
 
127
141
  # Returns a hash associating program memory label names (as symbols) to their addresses.
128
- # @return (Hash)
142
+ #
143
+ # @return [Hash]
129
144
  attr_reader :labels
130
145
 
131
146
  # Returns a {Label} object if a program label by that name is found.
132
147
  # The name is specified in the code that defined the label. If you are using a C compiler,
133
148
  # you will probably need to prefix the name with an underscore.
149
+ #
134
150
  # @return [Label]
135
151
  def label(name)
136
152
  name = name.to_sym
@@ -159,14 +175,6 @@ module RPicSim
159
175
  desc
160
176
  end
161
177
 
162
- # Gets an {Instruction} object representing the PIC instruction at the given
163
- # address in program memory.
164
- # @param address [Integer]
165
- # @return [Instruction]
166
- def instruction(address)
167
- @instructions[address] ||= make_instruction(address)
168
- end
169
-
170
178
  private
171
179
 
172
180
  def message_for_label_not_found(name)
@@ -181,10 +189,5 @@ module RPicSim
181
189
  end
182
190
  message
183
191
  end
184
-
185
- def make_instruction(address)
186
- mplab_instruction = @assembly.disassembler.disassemble(address)
187
- Instruction.new(mplab_instruction, address, @address_increment, self)
188
- end
189
192
  end
190
193
  end