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.
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
- RSpec.configure do |config|
9
- config.add_setting :sim_shortcuts, default: :all
10
- config.include RPicSim::RSpec::Helpers
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
- # See {file:RSpecIntegration.md} for more information about RPicSim's
13
- # integration with RSpec.
12
+ #
13
+ # For more information, see {file:RSpecIntegration.md}.
14
+ #
15
+ # @api public
14
16
  module Helpers
15
- include RPicSim::RSpec::PersistentExpectations
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 convenience
24
- # methods using {#add_shortcuts}.
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
@@ -1,6 +1,7 @@
1
1
  # If an example fails, store some diagnostic information about the state of the
2
2
  # simulation so we can print it later.
3
3
 
4
+ # @api private
4
5
  module RPicSim::RSpec::SimDiagnostics
5
6
  def self.store_diagnostics(example, sim)
6
7
  if sim.respond_to? :cycle_count
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 you can
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 [Register]
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 [Register]
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
@@ -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
- attr_reader :address, :description
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
@@ -1,3 +1,4 @@
1
+ # @api private
1
2
  module RPicSim::Storage
2
3
  # This class and its subclasses represent integers stored in RAM.
3
4
  class MemoryInteger
@@ -1,6 +1,8 @@
1
+ # @api public
1
2
  module RPicSim
2
3
  # This class is used internally by {Sim} to manage the symbols from the
3
- # simulated firmware's symbol table..
4
+ # simulated firmware's symbol table.
5
+ # @api private
4
6
  class SymbolSet
5
7
  def initialize
6
8
  @memory_types = []
@@ -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
@@ -1,8 +1,10 @@
1
1
  require_relative 'storage/memory_integer'
2
2
  require_relative 'variable'
3
3
 
4
+ # @api public
4
5
  module RPicSim
5
6
  # This class is used internally by {Sim} to manage user-defined variables.
7
+ # @api private
6
8
  class VariableSet
7
9
  attr_writer :address_increment
8
10
 
@@ -1,3 +1,6 @@
1
+ # @api public
1
2
  module RPicSim
2
- VERSION = '0.4.0'
3
+ # The version number of this gem, as a string.
4
+ # @return [String]
5
+ VERSION = '1.0.0'
3
6
  end
@@ -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 = [:custom_ram_sections,
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
- if opts[:custom_ram_sections]
33
- @sections_in_ram += opts[:custom_ram_sections]
34
- end
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
- if opts[:custom_code_sections]
37
- @sections_in_code += opts[:custom_code_sections]
38
- end
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.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-07-30 00:00:00.000000000 Z
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