rpicsim 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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