rpicsim 0.3.0 → 0.4.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 +4 -4
- data/docs/ChangeLog.md +22 -1
- data/docs/KnownIssues.md +12 -0
- data/docs/Labels.md +1 -1
- data/lib/rpicsim.rb +1 -0
- data/lib/rpicsim/memory.rb +38 -1
- data/lib/rpicsim/mplab/mplab_program_file.rb +10 -4
- data/lib/rpicsim/program_file.rb +90 -23
- data/lib/rpicsim/rspec/sim_diagnostics.rb +1 -1
- data/lib/rpicsim/sim.rb +48 -5
- data/lib/rpicsim/symbol_set.rb +51 -0
- data/lib/rpicsim/version.rb +1 -1
- data/lib/rpicsim/xc8_sym_file.rb +79 -0
- metadata +48 -46
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7dd67ae71f9052d9fa174cace952aa468a0001d
|
|
4
|
+
data.tar.gz: 72a07a6240931d85054651627a017677924d1a9e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94d406a34b8dc47900a487a306a3071ec2a441b039e6696c4f3c422cb2d92c27c0b200d13ea80e537df9b73dab4657db9edcf102d94fa3a7b516d39aa5128c55
|
|
7
|
+
data.tar.gz: 7c332af37e3563c1b12249c1fa690ca07f297dbb56175403b7b2d3c333fc3fdddd95825919ce40cafe90c1f1eb533a11842e61276a0b5652d765d26431637d73
|
data/docs/ChangeLog.md
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
Change log
|
|
2
2
|
====
|
|
3
3
|
|
|
4
|
+
0.4.0
|
|
5
|
+
----
|
|
6
|
+
Released on 2014-07-30.
|
|
7
|
+
|
|
8
|
+
- Adds {RPicSim::Memory#read_bytes} and {RPicSim::Memory#write_bytes}.
|
|
9
|
+
- Adds {RPicSim::Sim#stack_memory}.
|
|
10
|
+
- Fixes a bug in the RSpec 3.x support that was breaking the informative error messages when an example fails.
|
|
11
|
+
- Adds the ability to define symbols used in your simulation from sources other than a the COF file.
|
|
12
|
+
- Adds {RPicSim::Sim::ClassDefinitionMethods#import_symbols}, which calls {RPicSim::ProgramFile#import_symbols}
|
|
13
|
+
- Adds {RPicSim::Sim::ClassDefinitionMethods#def_symbol}, which calls {RPicSim::ProgramFile#def_symbol}
|
|
14
|
+
- Adds {RPicSim::ProgramFile#symbols} so you can more easily debug symbol-related problems and get access to symbols even if RPicSim does not recognize what type they are.
|
|
15
|
+
- 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
|
+
- {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
|
+
|
|
18
|
+
0.3.0
|
|
19
|
+
----
|
|
20
|
+
Released on 2014-06-20.
|
|
21
|
+
|
|
22
|
+
- Adds support for RSpec 3.x. This release was tested with RSpec 2.14.1, 2.99.0, and 3.0.0.
|
|
23
|
+
- Adds support for MPLAB X 2.10.
|
|
24
|
+
|
|
4
25
|
0.2.5
|
|
5
26
|
----
|
|
6
27
|
Released on 2014-05-02.
|
|
@@ -40,4 +61,4 @@ Released on 2014-03-07.
|
|
|
40
61
|
Released on 2014-02-12.
|
|
41
62
|
This is the initial release.
|
|
42
63
|
There are still some major things missing from this version that need to be added before we release 1.0.0.
|
|
43
|
-
Until 1.0.0 is released, we will not worry about backwards compatibility or writing complete change logs.
|
|
64
|
+
Until 1.0.0 is released, we will not worry about backwards compatibility or writing complete change logs.
|
data/docs/KnownIssues.md
CHANGED
|
@@ -197,3 +197,15 @@ Variables from XC8 are not correctly identified
|
|
|
197
197
|
|
|
198
198
|
RAM variables in programs using the XC8 compiler are often misidentified as being in program memory, and you need to get their address using {RPicSim::ProgramFile#symbols_in_program_memory}.
|
|
199
199
|
Some variables are not be identified at all, and you would have to write code to get their addresses from the SYM file.
|
|
200
|
+
|
|
201
|
+
Cannot read the top byte of PIC18 flash memory
|
|
202
|
+
----
|
|
203
|
+
|
|
204
|
+
_Type: MPLAB X bug_
|
|
205
|
+
|
|
206
|
+
_MPLAB X versions affected: all tested verions_
|
|
207
|
+
|
|
208
|
+
Attempting to read from the top (last) byte of program memory will cause an exception because the top address is not considered to be valid.
|
|
209
|
+
For example, you cannot use `program_memory.read_byte(0x7FFF)` on a PIC18F25K50 simulation.
|
|
210
|
+
One workaround is to use `read_word` instead.
|
|
211
|
+
This seems to only affect PIC18 devices.
|
data/docs/Labels.md
CHANGED
|
@@ -27,7 +27,7 @@ Therefore, to get the address of a C function named `foo`, you might have to acc
|
|
|
27
27
|
If RPicSim cannot find the label you want to use, you might troubleshoot it by printing out a list of all the known labels:
|
|
28
28
|
|
|
29
29
|
!!!ruby
|
|
30
|
-
p sim.
|
|
30
|
+
p sim.labels.keys
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
Using a Label object
|
data/lib/rpicsim.rb
CHANGED
data/lib/rpicsim/memory.rb
CHANGED
|
@@ -7,7 +7,7 @@ module RPicSim
|
|
|
7
7
|
# The behavior of +read_word+ and +write_word+ differs depending on
|
|
8
8
|
# what kind of Memory is being used, as shown in the table below:
|
|
9
9
|
#
|
|
10
|
-
# Memory type Address type Read/write chunk
|
|
10
|
+
# Memory type Address type Read/write chunk for word methods
|
|
11
11
|
# RAM and EEPROM: Byte address 1 byte (8 bits)
|
|
12
12
|
# PIC18 program memory: Byte address 1 word (16 bits)
|
|
13
13
|
# Non-PIC18 program memory: Word address 1 word (12 or 14 bits)
|
|
@@ -26,24 +26,61 @@ module RPicSim
|
|
|
26
26
|
@mplab_memory = mplab_memory
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
# Reads the byte in memory at the specified address.
|
|
30
|
+
#
|
|
31
|
+
# @param address [Integer]
|
|
32
|
+
# @return [Integer]
|
|
29
33
|
def read_byte(address)
|
|
30
34
|
@mplab_memory.read_byte(address)
|
|
31
35
|
end
|
|
32
36
|
|
|
37
|
+
# Writes the given integer to the byte in memory at the specified address.
|
|
38
|
+
#
|
|
39
|
+
# @param address [Integer]
|
|
40
|
+
# @param value [Integer]
|
|
33
41
|
def write_byte(address, value)
|
|
34
42
|
@mplab_memory.write_byte(address, value)
|
|
35
43
|
end
|
|
36
44
|
|
|
45
|
+
# Reads the word in memory at the specified address.
|
|
46
|
+
# @param address [Integer]
|
|
47
|
+
# @return [Integer]
|
|
37
48
|
def read_word(address)
|
|
38
49
|
@mplab_memory.read_word(address)
|
|
39
50
|
end
|
|
40
51
|
|
|
52
|
+
# Writes the given integer to the word in memory at the specified address.
|
|
53
|
+
# @param address [Integer]
|
|
54
|
+
# @param value [Integer]
|
|
41
55
|
def write_word(address, value)
|
|
42
56
|
@mplab_memory.write_word(address, value)
|
|
43
57
|
end
|
|
44
58
|
|
|
59
|
+
# Returns true if the specified address is valid.
|
|
60
|
+
# @param address [Integer]
|
|
61
|
+
# @return true or false
|
|
45
62
|
def valid_address?(address)
|
|
46
63
|
@mplab_memory.valid_address?(address)
|
|
47
64
|
end
|
|
65
|
+
|
|
66
|
+
# Reads a series of bytes from the simulated memory using +read_byte+ and
|
|
67
|
+
# returns them as an array.
|
|
68
|
+
#
|
|
69
|
+
# @param address [Integer] The address of the first byte to read.
|
|
70
|
+
# @param size [Integer] The number of bytes to read.
|
|
71
|
+
# @return [Array(Integer)]
|
|
72
|
+
def read_bytes(address, size)
|
|
73
|
+
size.times.map { |i| read_byte(address + i) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Writes a series of bytes to the simulated memory.
|
|
77
|
+
#
|
|
78
|
+
# @param address [Integer]
|
|
79
|
+
# @param bytes Array of integers or a string.
|
|
80
|
+
def write_bytes(address, bytes)
|
|
81
|
+
bytes = bytes.bytes if bytes.is_a?(String)
|
|
82
|
+
bytes.each_with_index { |b, i| write_byte(address + i, b) }
|
|
83
|
+
nil
|
|
84
|
+
end
|
|
48
85
|
end
|
|
49
86
|
end
|
|
@@ -16,6 +16,10 @@ module RPicSim::Mplab
|
|
|
16
16
|
@program_file.Load
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
def symbols
|
|
20
|
+
@symbols ||= Hash[raw_symbols.map { |s| [s.m_Symbol.to_sym, s.address] }]
|
|
21
|
+
end
|
|
22
|
+
|
|
19
23
|
def symbols_in_ram
|
|
20
24
|
@symbols_in_ram ||= Hash[
|
|
21
25
|
grouped_symbols[:ram]
|
|
@@ -41,7 +45,7 @@ module RPicSim::Mplab
|
|
|
41
45
|
|
|
42
46
|
def grouped_symbols
|
|
43
47
|
@grouped_symbols ||= begin
|
|
44
|
-
hash =
|
|
48
|
+
hash = raw_symbols.group_by(&method(:memory_type))
|
|
45
49
|
hash.default = []
|
|
46
50
|
hash
|
|
47
51
|
end
|
|
@@ -71,7 +75,9 @@ module RPicSim::Mplab
|
|
|
71
75
|
# 111 XC8 program memory variable (array of uint32_t) (but sometimes it is in RAM instead)
|
|
72
76
|
# 366 XC8 program memory variable (array of pointers)
|
|
73
77
|
#
|
|
74
|
-
#
|
|
78
|
+
# The numbers above are not very well tested and probably incomplete. This
|
|
79
|
+
# is OK because for XC8 programs people should use the HEX and SYM file
|
|
80
|
+
# instead of the COF file.
|
|
75
81
|
def memory_type(symbol)
|
|
76
82
|
case symbol.m_lType
|
|
77
83
|
when 0, 2, 8, 12, 40, 44, 108
|
|
@@ -89,10 +95,10 @@ module RPicSim::Mplab
|
|
|
89
95
|
# Just put this line in your simulation class definition temporarily:
|
|
90
96
|
# pp program_file.instance_variable_get(:@mplab_program_file).send(:symbol_dump).sort
|
|
91
97
|
def symbol_dump
|
|
92
|
-
|
|
98
|
+
raw_symbols.map { |s| [s.m_Symbol, s.m_lType, s.address, memory_type(s)] }
|
|
93
99
|
end
|
|
94
100
|
|
|
95
|
-
def
|
|
101
|
+
def raw_symbols
|
|
96
102
|
@program_file.getSymbolTable.getSymbols(0, 0)
|
|
97
103
|
end
|
|
98
104
|
end
|
data/lib/rpicsim/program_file.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
require_relative 'mplab'
|
|
2
2
|
require_relative 'label'
|
|
3
3
|
require_relative 'instruction'
|
|
4
|
+
require_relative 'symbol_set'
|
|
4
5
|
|
|
5
|
-
# TODO:
|
|
6
|
-
#
|
|
7
|
-
# think about how to choose the more interesting one in a stack trace (fewer underscores?)
|
|
6
|
+
# TODO: When symbols have the same address, think about how to choose the more
|
|
7
|
+
# interesting one in a stack trace (fewer underscores?)
|
|
8
8
|
|
|
9
9
|
module RPicSim
|
|
10
10
|
# Represents a PIC program file (e.g. COF or HEX).
|
|
11
|
+
# Keeps track of all the symbols loaded from that file and also allows you
|
|
12
|
+
# to add symbols in various ways.
|
|
11
13
|
class ProgramFile
|
|
12
14
|
attr_reader :filename
|
|
13
15
|
attr_reader :device
|
|
@@ -27,39 +29,104 @@ module RPicSim
|
|
|
27
29
|
@address_increment = @assembly.device_info.code_address_increment
|
|
28
30
|
|
|
29
31
|
@instructions = []
|
|
32
|
+
|
|
33
|
+
@labels = {}
|
|
34
|
+
|
|
35
|
+
@symbol_set = SymbolSet.new
|
|
36
|
+
@symbol_set.def_memory_type :ram
|
|
37
|
+
@symbol_set.def_memory_type :program_memory
|
|
38
|
+
@symbol_set.def_memory_type :eeprom
|
|
39
|
+
|
|
40
|
+
@symbol_set.on_symbol_definition do |name, address, memory_type|
|
|
41
|
+
if memory_type == :program_memory
|
|
42
|
+
labels[name] = Label.new(name, address)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
import_symbols @mplab_program_file
|
|
30
47
|
end
|
|
31
48
|
|
|
32
|
-
#
|
|
33
|
-
#
|
|
49
|
+
# Imports symbols from an additional symbol source.
|
|
50
|
+
#
|
|
51
|
+
# The +symbol_source+ parameter should be an object that responds to some
|
|
52
|
+
# subset of these methods: +#symbols+, +#symbols_in_ram+,
|
|
53
|
+
# +#symbols_in_program_memory+, +#symbols_in_eeprom+. The methods should
|
|
54
|
+
# take no arguments and return a hash where the keys are symbol names
|
|
55
|
+
# (represented as Ruby symbols) and the values are addresses (as
|
|
56
|
+
# integers).
|
|
57
|
+
def import_symbols(symbol_source)
|
|
58
|
+
if symbol_source.respond_to?(:symbols)
|
|
59
|
+
@symbol_set.def_symbols symbol_source.symbols
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if symbol_source.respond_to?(:symbols_in_ram)
|
|
63
|
+
@symbol_set.def_symbols symbol_source.symbols_in_ram, :ram
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if symbol_source.respond_to?(:symbols_in_program_memory)
|
|
67
|
+
@symbol_set.def_symbols symbol_source.symbols_in_program_memory, :program_memory
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if symbol_source.respond_to?(:symbols_in_eeprom)
|
|
71
|
+
@symbol_set.def_symbols symbol_source.symbols_in_eeprom, :eeprom
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Defines a new symbol.
|
|
76
|
+
#
|
|
77
|
+
# @param name [Symbol] The name of the symbol.
|
|
78
|
+
# @param address [Integer] The address of the symbol.
|
|
79
|
+
# @param memory_type [Symbol] (optional) The type of memory the symbol
|
|
80
|
+
# belongs to. This should either by +:ram+, +:program_memory+, or
|
|
81
|
+
# +:eeprom+.
|
|
82
|
+
def def_symbol(name, address, memory_type = nil)
|
|
83
|
+
@symbol_set.def_symbol name, address, memory_type
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Returns all the symbols known to the simulation.
|
|
87
|
+
#
|
|
88
|
+
# The return value is a hash where the keys are the names of the symbols
|
|
89
|
+
# (represented as Ruby symbols) and the values are the addresses of the symbols.
|
|
90
|
+
#
|
|
91
|
+
# Warning: This is a persistent hash that will automatically be updated when
|
|
92
|
+
# new symbols are defined.
|
|
93
|
+
def symbols
|
|
94
|
+
@symbol_set.symbols
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Returns all the symbols in RAM.
|
|
98
|
+
# The return value is a hash where the keys are the names of the symbols
|
|
99
|
+
# (represented as Ruby symbols) and the values are the addresses of the symbols.
|
|
100
|
+
#
|
|
101
|
+
# Warning: This is a persistent hash that will automatically be updated when
|
|
102
|
+
# new symbols are defined.
|
|
34
103
|
def symbols_in_ram
|
|
35
|
-
@
|
|
104
|
+
@symbol_set.symbols_in_memory(:ram)
|
|
36
105
|
end
|
|
37
106
|
|
|
38
|
-
# Returns
|
|
39
|
-
#
|
|
40
|
-
#
|
|
107
|
+
# Returns all the symbols in program memory.
|
|
108
|
+
# The return value is a hash where the keys are the names of the symbols
|
|
109
|
+
# (represented as Ruby symbols) and the values are the addresses of the symbols.
|
|
110
|
+
#
|
|
111
|
+
# Warning: This is a persistent hash that will automatically be updated when
|
|
112
|
+
# new symbols are defined.
|
|
41
113
|
def symbols_in_program_memory
|
|
42
|
-
@
|
|
114
|
+
@symbol_set.symbols_in_memory(:program_memory)
|
|
43
115
|
end
|
|
44
116
|
|
|
45
|
-
# Returns
|
|
46
|
-
#
|
|
47
|
-
#
|
|
117
|
+
# Returns all the symbols in EEPROM.
|
|
118
|
+
# The return value is a hash where the keys are the names of the symbols
|
|
119
|
+
# (represented as Ruby symbols) and the values are the addresses of the symbols.
|
|
120
|
+
#
|
|
121
|
+
# Warning: This is a persistent hash that will automatically be updated when
|
|
122
|
+
# new symbols are defined.
|
|
48
123
|
def symbols_in_eeprom
|
|
49
|
-
@
|
|
124
|
+
@symbol_set.symbols_in_memory(:eeprom)
|
|
50
125
|
end
|
|
51
126
|
|
|
52
127
|
# Returns a hash associating program memory label names (as symbols) to their addresses.
|
|
53
128
|
# @return (Hash)
|
|
54
|
-
|
|
55
|
-
@labels ||= begin
|
|
56
|
-
hash = {}
|
|
57
|
-
symbols_in_program_memory.each do |name, address|
|
|
58
|
-
hash[name] = Label.new(name, address)
|
|
59
|
-
end
|
|
60
|
-
hash
|
|
61
|
-
end
|
|
62
|
-
end
|
|
129
|
+
attr_reader :labels
|
|
63
130
|
|
|
64
131
|
# Returns a {Label} object if a program label by that name is found.
|
|
65
132
|
# The name is specified in the code that defined the label. If you are using a C compiler,
|
data/lib/rpicsim/sim.rb
CHANGED
|
@@ -29,7 +29,8 @@ module RPicSim
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Specifies the path to the firmware file. The file can be a HEX or COF file, but
|
|
32
|
-
# COF is recommended so that you can access label addresses and other
|
|
32
|
+
# COF is recommended so that you can access symbol/label addresses and other
|
|
33
|
+
# debugging information.
|
|
33
34
|
# You must call {#use_device} before calling this.
|
|
34
35
|
def use_file(filename)
|
|
35
36
|
raise "The device needs to be specified before filename (e.g. 'use_device \"PIC10F322\"')" unless @device
|
|
@@ -37,6 +38,27 @@ module RPicSim
|
|
|
37
38
|
load_program_file
|
|
38
39
|
end
|
|
39
40
|
|
|
41
|
+
# Specifies additional symbols to use in the simulation. Symbols might be
|
|
42
|
+
# loaded from the program file when you call {#use_file}, but if those
|
|
43
|
+
# symbols are not sufficient then you can call this method to incorporate
|
|
44
|
+
# another source of symbols.
|
|
45
|
+
#
|
|
46
|
+
# See {RPicSim::ProgramFile#import_symbols} for details on what the parameter
|
|
47
|
+
# should be.
|
|
48
|
+
def import_symbols(symbol_source)
|
|
49
|
+
program_file.import_symbols(symbol_source)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Define a symbol.
|
|
53
|
+
# Normally symbols are loaded by {#use_file} or {#import_symbols}, but you can
|
|
54
|
+
# this method allows for adding additional symbols one at a time.
|
|
55
|
+
#
|
|
56
|
+
# See {RPicSim::ProgramFile#def_symbol} for details about the parameters
|
|
57
|
+
# this method takes.
|
|
58
|
+
def def_symbol(name, address, memory_type = nil)
|
|
59
|
+
program_file.def_symbol name, address, memory_type
|
|
60
|
+
end
|
|
61
|
+
|
|
40
62
|
# Define a pin alias.
|
|
41
63
|
#
|
|
42
64
|
# @param our_name [Symbol] Specifies what you would like to
|
|
@@ -98,12 +120,22 @@ module RPicSim
|
|
|
98
120
|
# with {ClassDefinitionMethods#def_var def_var}.
|
|
99
121
|
attr_reader :variable_set
|
|
100
122
|
|
|
101
|
-
# A hash that associates label names as symbols to {Label} objects.
|
|
102
|
-
attr_reader :labels
|
|
103
|
-
|
|
104
123
|
# The {ProgramFile} object representing the firmware.
|
|
105
124
|
attr_reader :program_file
|
|
106
125
|
|
|
126
|
+
# Returns a hash that associates label names as Ruby symbols to {Label} objects.
|
|
127
|
+
def labels
|
|
128
|
+
program_file.labels
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Returns a {Label} object if a program label by that name is found.
|
|
132
|
+
# The name is specified in the code that defined the label. If you are using a C compiler,
|
|
133
|
+
# you will probably need to prefix the name with an underscore.
|
|
134
|
+
# @return [Label]
|
|
135
|
+
def label(name)
|
|
136
|
+
program_file.label(name)
|
|
137
|
+
end
|
|
138
|
+
|
|
107
139
|
private
|
|
108
140
|
|
|
109
141
|
# This gets called when a new subclass of PicSim is created.
|
|
@@ -117,7 +149,6 @@ module RPicSim
|
|
|
117
149
|
|
|
118
150
|
def load_program_file
|
|
119
151
|
@program_file = ProgramFile.new(@filename, @device)
|
|
120
|
-
@labels = program_file.labels
|
|
121
152
|
|
|
122
153
|
@variable_set = VariableSet.new
|
|
123
154
|
@variable_set.address_increment = program_file.address_increment
|
|
@@ -143,6 +174,7 @@ module RPicSim
|
|
|
143
174
|
:every_step,
|
|
144
175
|
:goto,
|
|
145
176
|
:label,
|
|
177
|
+
:labels,
|
|
146
178
|
:location_address,
|
|
147
179
|
:new_ram_watcher,
|
|
148
180
|
:pc,
|
|
@@ -158,6 +190,7 @@ module RPicSim
|
|
|
158
190
|
:run_to_cycle_count,
|
|
159
191
|
:reg,
|
|
160
192
|
:stack_contents,
|
|
193
|
+
:stack_memory,
|
|
161
194
|
:stack_push,
|
|
162
195
|
:stack_trace,
|
|
163
196
|
:step,
|
|
@@ -212,6 +245,11 @@ module RPicSim
|
|
|
212
245
|
# @return [Memory]
|
|
213
246
|
attr_reader :eeprom
|
|
214
247
|
|
|
248
|
+
# Returns a {Memory} object that allows direct reading and writing of the
|
|
249
|
+
# bytes in the simulated hardware call stack.
|
|
250
|
+
# @return [Memory]
|
|
251
|
+
attr_reader :stack_memory
|
|
252
|
+
|
|
215
253
|
# Returns a string like "PIC10F322" specifying the PIC device number.
|
|
216
254
|
# @return [String]
|
|
217
255
|
def device
|
|
@@ -336,6 +374,11 @@ module RPicSim
|
|
|
336
374
|
program_file.label(name)
|
|
337
375
|
end
|
|
338
376
|
|
|
377
|
+
# Returns a hash that associates label names as Ruby symbols to {Label} objects.
|
|
378
|
+
def labels
|
|
379
|
+
program_file.labels
|
|
380
|
+
end
|
|
381
|
+
|
|
339
382
|
# Returns the number of instruction cycles simulated in this simulation.
|
|
340
383
|
# @return [Integer]
|
|
341
384
|
def cycle_count
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module RPicSim
|
|
2
|
+
# This class is used internally by {Sim} to manage the symbols from the
|
|
3
|
+
# simulated firmware's symbol table..
|
|
4
|
+
class SymbolSet
|
|
5
|
+
def initialize
|
|
6
|
+
@memory_types = []
|
|
7
|
+
@symbols = {}
|
|
8
|
+
@symbols_for_memory = {}
|
|
9
|
+
@callbacks = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def def_memory_type(name)
|
|
13
|
+
name = name.to_sym
|
|
14
|
+
@memory_types << name
|
|
15
|
+
@symbols_for_memory[name] = {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def def_symbol(name, address, memory_type = nil)
|
|
19
|
+
name = name.to_sym
|
|
20
|
+
address = address.to_i
|
|
21
|
+
if memory_type
|
|
22
|
+
hash = @symbols_for_memory[memory_type.to_sym]
|
|
23
|
+
raise "Invalid memory type: #{memory_type}." if !hash
|
|
24
|
+
hash[name] = address
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@symbols[name] = address
|
|
28
|
+
|
|
29
|
+
@callbacks.each do |callback|
|
|
30
|
+
callback.call name, address, memory_type
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def def_symbols(symbols, memory_type = nil)
|
|
35
|
+
symbols.each do |name, address|
|
|
36
|
+
def_symbol name, address, memory_type
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
attr_reader :symbols
|
|
41
|
+
|
|
42
|
+
def symbols_in_memory(memory_type)
|
|
43
|
+
@symbols_for_memory[memory_type.to_sym]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def on_symbol_definition(&proc)
|
|
47
|
+
raise 'Block required' if !proc
|
|
48
|
+
@callbacks << proc
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/rpicsim/version.rb
CHANGED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'scanf'
|
|
2
|
+
|
|
3
|
+
module RPicSim
|
|
4
|
+
class Xc8SymFile
|
|
5
|
+
attr_reader :symbols
|
|
6
|
+
attr_reader :symbols_in_ram
|
|
7
|
+
attr_reader :symbols_in_eeprom
|
|
8
|
+
attr_reader :symbols_in_program_memory
|
|
9
|
+
|
|
10
|
+
attr_reader :symbol_raw_data
|
|
11
|
+
|
|
12
|
+
def initialize(filename, opts = {})
|
|
13
|
+
@symbols = {}
|
|
14
|
+
@symbols_in_ram = {}
|
|
15
|
+
@symbols_in_eeprom = {}
|
|
16
|
+
@symbols_in_program_memory = {}
|
|
17
|
+
|
|
18
|
+
@filename = filename
|
|
19
|
+
@sections_in_ram = %w{ABS BIGRAM COMRAM RAM SFR FARRAM
|
|
20
|
+
BANK0 BANK1 BANK2 BANK3 BANK4 BANK5 BANK6 BANK7}
|
|
21
|
+
@sections_in_code = %w{CODE CONST IDLOC MEDIUMCONST SMALLCONST}
|
|
22
|
+
@sections_in_eeprom = %w{EEDATA}
|
|
23
|
+
|
|
24
|
+
allowed_keys = [:custom_ram_sections,
|
|
25
|
+
:custom_code_sections,
|
|
26
|
+
:custom_eeprom_sections]
|
|
27
|
+
invalid_keys = opts.keys - allowed_keys
|
|
28
|
+
if !invalid_keys.empty?
|
|
29
|
+
raise "Invalid options: #{invalid_keys.inspect}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if opts[:custom_ram_sections]
|
|
33
|
+
@sections_in_ram += opts[:custom_ram_sections]
|
|
34
|
+
end
|
|
35
|
+
|
|
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
|
|
43
|
+
|
|
44
|
+
read_data
|
|
45
|
+
sort_data
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def read_data
|
|
51
|
+
@symbol_raw_data = {}
|
|
52
|
+
File.foreach(@filename) do |line|
|
|
53
|
+
entry = line.scanf('%s %x %x %s %x')
|
|
54
|
+
break if entry[0].start_with? '%'
|
|
55
|
+
key = entry[0].to_sym
|
|
56
|
+
entry[0] = key
|
|
57
|
+
@symbol_raw_data[key] = entry
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def sort_data
|
|
62
|
+
@symbol_raw_data.values.each do |name, address, _, section, _|
|
|
63
|
+
@symbols[name] = address
|
|
64
|
+
|
|
65
|
+
if @sections_in_ram.include?(section)
|
|
66
|
+
@symbols_in_ram[name] = address
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
if @sections_in_code.include?(section)
|
|
70
|
+
@symbols_in_program_memory[name] = address
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if @sections_in_eeprom.include?(section)
|
|
74
|
+
@symbols_in_eeprom[name] = address
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
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
|
+
version: 0.4.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-
|
|
11
|
+
date: 2014-07-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description:
|
|
14
14
|
email:
|
|
@@ -16,11 +16,52 @@ executables: []
|
|
|
16
16
|
extensions: []
|
|
17
17
|
extra_rdoc_files: []
|
|
18
18
|
files:
|
|
19
|
-
- .
|
|
20
|
-
-
|
|
19
|
+
- lib/rpicsim.rb
|
|
20
|
+
- lib/rpicsim/call_stack_info.rb
|
|
21
|
+
- lib/rpicsim/composite_memory.rb
|
|
22
|
+
- lib/rpicsim/flaws.rb
|
|
23
|
+
- lib/rpicsim/instruction.rb
|
|
24
|
+
- lib/rpicsim/label.rb
|
|
25
|
+
- lib/rpicsim/memory.rb
|
|
26
|
+
- lib/rpicsim/memory_watcher.rb
|
|
27
|
+
- lib/rpicsim/mplab.rb
|
|
28
|
+
- lib/rpicsim/pin.rb
|
|
29
|
+
- lib/rpicsim/program_counter.rb
|
|
30
|
+
- lib/rpicsim/program_file.rb
|
|
31
|
+
- lib/rpicsim/rspec.rb
|
|
32
|
+
- lib/rpicsim/search.rb
|
|
33
|
+
- lib/rpicsim/sim.rb
|
|
34
|
+
- lib/rpicsim/stack_pointer.rb
|
|
35
|
+
- lib/rpicsim/stack_trace.rb
|
|
36
|
+
- lib/rpicsim/symbol_set.rb
|
|
37
|
+
- lib/rpicsim/variable.rb
|
|
38
|
+
- lib/rpicsim/variable_set.rb
|
|
39
|
+
- lib/rpicsim/version.rb
|
|
40
|
+
- lib/rpicsim/xc8_sym_file.rb
|
|
41
|
+
- lib/rpicsim/mplab/mplab_assembly.rb
|
|
42
|
+
- lib/rpicsim/mplab/mplab_device_info.rb
|
|
43
|
+
- lib/rpicsim/mplab/mplab_disassembler.rb
|
|
44
|
+
- lib/rpicsim/mplab/mplab_instruction.rb
|
|
45
|
+
- lib/rpicsim/mplab/mplab_loader.rb
|
|
46
|
+
- lib/rpicsim/mplab/mplab_memory.rb
|
|
47
|
+
- lib/rpicsim/mplab/mplab_nmmr_info.rb
|
|
48
|
+
- lib/rpicsim/mplab/mplab_observer.rb
|
|
49
|
+
- lib/rpicsim/mplab/mplab_pin.rb
|
|
50
|
+
- lib/rpicsim/mplab/mplab_processor.rb
|
|
51
|
+
- lib/rpicsim/mplab/mplab_program_file.rb
|
|
52
|
+
- lib/rpicsim/mplab/mplab_register.rb
|
|
53
|
+
- lib/rpicsim/mplab/mplab_sfr_info.rb
|
|
54
|
+
- lib/rpicsim/mplab/mplab_simulator.rb
|
|
55
|
+
- lib/rpicsim/rspec/be_predicate.rb
|
|
56
|
+
- lib/rpicsim/rspec/helpers.rb
|
|
57
|
+
- lib/rpicsim/rspec/persistent_expectations.rb
|
|
58
|
+
- lib/rpicsim/rspec/sim_diagnostics.rb
|
|
59
|
+
- lib/rpicsim/storage/memory_integer.rb
|
|
60
|
+
- lib/rpicsim/storage/register.rb
|
|
21
61
|
- Introduction.md
|
|
22
62
|
- LICENSE.txt
|
|
23
63
|
- README.md
|
|
64
|
+
- Gemfile
|
|
24
65
|
- docs/ChangeLog.md
|
|
25
66
|
- docs/Contributing.md
|
|
26
67
|
- docs/Debugging.md
|
|
@@ -39,8 +80,8 @@ files:
|
|
|
39
80
|
- docs/Pins.md
|
|
40
81
|
- docs/PreventingCallStackOverflow.md
|
|
41
82
|
- docs/QuickStartGuide.md
|
|
42
|
-
- docs/RSpecIntegration.md
|
|
43
83
|
- docs/RamWatcher.md
|
|
84
|
+
- docs/RSpecIntegration.md
|
|
44
85
|
- docs/Running.md
|
|
45
86
|
- docs/Stubbing.md
|
|
46
87
|
- docs/SupportedCompilers.md
|
|
@@ -49,46 +90,7 @@ files:
|
|
|
49
90
|
- docs/SupportedOperatingSystems.md
|
|
50
91
|
- docs/UnitTesting.md
|
|
51
92
|
- docs/Variables.md
|
|
52
|
-
-
|
|
53
|
-
- lib/rpicsim/call_stack_info.rb
|
|
54
|
-
- lib/rpicsim/composite_memory.rb
|
|
55
|
-
- lib/rpicsim/flaws.rb
|
|
56
|
-
- lib/rpicsim/instruction.rb
|
|
57
|
-
- lib/rpicsim/label.rb
|
|
58
|
-
- lib/rpicsim/memory.rb
|
|
59
|
-
- lib/rpicsim/memory_watcher.rb
|
|
60
|
-
- lib/rpicsim/mplab.rb
|
|
61
|
-
- lib/rpicsim/mplab/mplab_assembly.rb
|
|
62
|
-
- lib/rpicsim/mplab/mplab_device_info.rb
|
|
63
|
-
- lib/rpicsim/mplab/mplab_disassembler.rb
|
|
64
|
-
- lib/rpicsim/mplab/mplab_instruction.rb
|
|
65
|
-
- lib/rpicsim/mplab/mplab_loader.rb
|
|
66
|
-
- lib/rpicsim/mplab/mplab_memory.rb
|
|
67
|
-
- lib/rpicsim/mplab/mplab_nmmr_info.rb
|
|
68
|
-
- lib/rpicsim/mplab/mplab_observer.rb
|
|
69
|
-
- lib/rpicsim/mplab/mplab_pin.rb
|
|
70
|
-
- lib/rpicsim/mplab/mplab_processor.rb
|
|
71
|
-
- lib/rpicsim/mplab/mplab_program_file.rb
|
|
72
|
-
- lib/rpicsim/mplab/mplab_register.rb
|
|
73
|
-
- lib/rpicsim/mplab/mplab_sfr_info.rb
|
|
74
|
-
- lib/rpicsim/mplab/mplab_simulator.rb
|
|
75
|
-
- lib/rpicsim/pin.rb
|
|
76
|
-
- lib/rpicsim/program_counter.rb
|
|
77
|
-
- lib/rpicsim/program_file.rb
|
|
78
|
-
- lib/rpicsim/rspec.rb
|
|
79
|
-
- lib/rpicsim/rspec/be_predicate.rb
|
|
80
|
-
- lib/rpicsim/rspec/helpers.rb
|
|
81
|
-
- lib/rpicsim/rspec/persistent_expectations.rb
|
|
82
|
-
- lib/rpicsim/rspec/sim_diagnostics.rb
|
|
83
|
-
- lib/rpicsim/search.rb
|
|
84
|
-
- lib/rpicsim/sim.rb
|
|
85
|
-
- lib/rpicsim/stack_pointer.rb
|
|
86
|
-
- lib/rpicsim/stack_trace.rb
|
|
87
|
-
- lib/rpicsim/storage/memory_integer.rb
|
|
88
|
-
- lib/rpicsim/storage/register.rb
|
|
89
|
-
- lib/rpicsim/variable.rb
|
|
90
|
-
- lib/rpicsim/variable_set.rb
|
|
91
|
-
- lib/rpicsim/version.rb
|
|
93
|
+
- .yardopts
|
|
92
94
|
homepage: https://github.com/pololu/rpicsim
|
|
93
95
|
licenses:
|
|
94
96
|
- MIT
|
|
@@ -111,7 +113,7 @@ requirements:
|
|
|
111
113
|
- JRuby
|
|
112
114
|
- MPLAB X
|
|
113
115
|
rubyforge_project:
|
|
114
|
-
rubygems_version: 2.
|
|
116
|
+
rubygems_version: 2.1.9
|
|
115
117
|
signing_key:
|
|
116
118
|
specification_version: 4
|
|
117
119
|
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.
|