rpicsim 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +36 -0
- data/Gemfile +10 -0
- data/Introduction.md +64 -0
- data/LICENSE.txt +24 -0
- data/README.md +66 -0
- data/docs/ChangeLog.md +10 -0
- data/docs/Contributing.md +30 -0
- data/docs/Debugging.md +96 -0
- data/docs/DefiningSimulationClass.md +84 -0
- data/docs/DesignDecisions.md +48 -0
- data/docs/HowMPLABXIsFound.md +14 -0
- data/docs/IntegrationTesting.md +15 -0
- data/docs/IntroductionToRSpec.md +203 -0
- data/docs/IntroductionToRuby.md +90 -0
- data/docs/KnownIssues.md +204 -0
- data/docs/Labels.md +39 -0
- data/docs/MakingTestsRunFaster.md +29 -0
- data/docs/Manual.md +38 -0
- data/docs/PersistentExpectations.md +100 -0
- data/docs/Pins.md +143 -0
- data/docs/PreventingCallStackOverflow.md +94 -0
- data/docs/QuickStartGuide.md +85 -0
- data/docs/RSpecIntegration.md +119 -0
- data/docs/RamWatcher.md +46 -0
- data/docs/Running.md +129 -0
- data/docs/SFRs.md +71 -0
- data/docs/Stubbing.md +161 -0
- data/docs/SupportedCompilers.md +5 -0
- data/docs/SupportedDevices.md +14 -0
- data/docs/SupportedMPLABXVersions.md +12 -0
- data/docs/SupportedOperatingSystems.md +3 -0
- data/docs/UnitTesting.md +9 -0
- data/docs/Variables.md +140 -0
- data/lib/rpicsim.rb +15 -0
- data/lib/rpicsim/call_stack_info.rb +306 -0
- data/lib/rpicsim/flaws.rb +76 -0
- data/lib/rpicsim/instruction.rb +178 -0
- data/lib/rpicsim/label.rb +28 -0
- data/lib/rpicsim/memory.rb +29 -0
- data/lib/rpicsim/memory_watcher.rb +98 -0
- data/lib/rpicsim/mplab.rb +138 -0
- data/lib/rpicsim/mplab/mplab_assembly.rb +102 -0
- data/lib/rpicsim/mplab/mplab_device_info.rb +40 -0
- data/lib/rpicsim/mplab/mplab_disassembler.rb +23 -0
- data/lib/rpicsim/mplab/mplab_instruction.rb +32 -0
- data/lib/rpicsim/mplab/mplab_memory.rb +33 -0
- data/lib/rpicsim/mplab/mplab_nmmr_info.rb +21 -0
- data/lib/rpicsim/mplab/mplab_observer.rb +12 -0
- data/lib/rpicsim/mplab/mplab_pin.rb +61 -0
- data/lib/rpicsim/mplab/mplab_processor.rb +30 -0
- data/lib/rpicsim/mplab/mplab_program_file.rb +35 -0
- data/lib/rpicsim/mplab/mplab_register.rb +25 -0
- data/lib/rpicsim/mplab/mplab_sfr_info.rb +21 -0
- data/lib/rpicsim/mplab/mplab_simulator.rb +102 -0
- data/lib/rpicsim/pin.rb +61 -0
- data/lib/rpicsim/program_counter.rb +19 -0
- data/lib/rpicsim/program_file.rb +160 -0
- data/lib/rpicsim/register.rb +78 -0
- data/lib/rpicsim/rspec.rb +11 -0
- data/lib/rpicsim/rspec/be_predicate.rb +12 -0
- data/lib/rpicsim/rspec/helpers.rb +48 -0
- data/lib/rpicsim/rspec/persistent_expectations.rb +53 -0
- data/lib/rpicsim/rspec/sim_diagnostics.rb +51 -0
- data/lib/rpicsim/search.rb +20 -0
- data/lib/rpicsim/sim.rb +702 -0
- data/lib/rpicsim/stack_trace.rb +32 -0
- data/lib/rpicsim/variable.rb +236 -0
- data/lib/rpicsim/version.rb +3 -0
- metadata +114 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
How MPLAB X is found
|
2
|
+
====
|
3
|
+
|
4
|
+
RPicSim uses many Java classes from MPLAB X.
|
5
|
+
This section describes how it finds those classes at run time.
|
6
|
+
The code that controls this can be found in `lib/rpicsim/mplab_x.rb` in the source code of RPicSim.
|
7
|
+
|
8
|
+
The primary thing that RPicSim needs to do is figure out what directory MPLAB X has been installed in.
|
9
|
+
If the `RPICSIM_MPLABX` environment variable is set, it will assume that environment variable contains the path to the MPLAB X directory.
|
10
|
+
The environment variable is useful because it allows you to copy the files from one version of MPLAB X to some alternative place on your computer and use that version of MPLAB X for your simulations while you continue to use other versions of MPLAB X for your actual firmware development.
|
11
|
+
|
12
|
+
If the environment variable is not present, RPicSim will look for the MPLAB X directory in a few standard places and choose the first one that exists.
|
13
|
+
|
14
|
+
After RPicSim finds the MPLAB X directory, it will look in various subdirectories for JAR files and add all of them to the Java classpath so that the Java classes in those JAR files can be used.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Integration testing
|
2
|
+
====
|
3
|
+
|
4
|
+
An _integration test_ is a test that helps ensure that different modules and routines can work properly together.
|
5
|
+
The structure of your integration tests is up to you, but a typical integration test in RPicSim should probably have these properties:
|
6
|
+
|
7
|
+
* It runs the simulation from the beginning of the code (address 0).
|
8
|
+
* It gets the simulation into the desired state by manipulating its input pins rather than directly modifying its RAM.
|
9
|
+
* It tests that the firmware did the right thing by checking the states of the output pins.
|
10
|
+
* It does not alter the program counter except perhaps to make the tests faster, as discussed in the {file:Stubbing.md Stubbing page}.
|
11
|
+
* It might use {RPicSim::Sim#every_step} to check certain assertions after every step of the simulation. For example, it could test that a certain SFR's value never changes after it has been initialized.
|
12
|
+
* It might directly modify the device's EEPROM or flash memory at the beginning of the simulation if that memory is used to store settings.
|
13
|
+
|
14
|
+
For an example of an integration test, see the {file:Pins.md#label-PinMirror+example PinMirror example} from the Pins page.
|
15
|
+
|
@@ -0,0 +1,203 @@
|
|
1
|
+
Introduction to RSpec
|
2
|
+
====
|
3
|
+
|
4
|
+
[RSpec](http://rspec.info/) is a testing tool for the Ruby programming language that allows you to write an automated test suite.
|
5
|
+
RSpec provides great ways to combine code from similar tests, provides good error messages, and encourages you to specify exactly what you are testing.
|
6
|
+
|
7
|
+
The main documentation for RSpec can be found from the project's website at [rspec.info](http://rspec.info/), but I think it is not very easy to follow. This page goes over the most important things you should know about RSpec.
|
8
|
+
|
9
|
+
File structure
|
10
|
+
----
|
11
|
+
|
12
|
+
The recommended way to set up RSpec is to put your test suite in a directory named `spec`, as discussed in the {file:QuickStartGuide.md Quick-start guide}. When you run the `rspec` command, RSpec will look for all the files in `spec` and its subdirectories that have a name ending in `_spec.rb`.
|
13
|
+
|
14
|
+
|
15
|
+
Example groups and examples
|
16
|
+
----
|
17
|
+
|
18
|
+
Each spec file contains one or more _example groups_, which are defined using RSpec's `describe` or `context` commands. For example:
|
19
|
+
|
20
|
+
!!!ruby
|
21
|
+
describe "my device" do
|
22
|
+
# examples of how your device should behave go here
|
23
|
+
end
|
24
|
+
|
25
|
+
You can have nested example groups:
|
26
|
+
|
27
|
+
!!!ruby
|
28
|
+
describe "my device" do
|
29
|
+
context "when RA1 is held high" do
|
30
|
+
# examples go here
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
The outer-most example group must be a `describe`, not a `context`.
|
35
|
+
|
36
|
+
An _example_ is the basic unit of an RSpec test suite. Examples are defined using the `it` or `specify` commands inside an example group:
|
37
|
+
|
38
|
+
!!!ruby
|
39
|
+
describe "my device" do
|
40
|
+
it "toggles RA2 often" do
|
41
|
+
# code to test the toggling goes here
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
The strings passed to `describe`, `context`, `it`, and `specify` are optional, but are used to generate helpful error messages and documentation. If an example fails then a string about the expected behavior is produced by concatenating all the provided strings, from outermost to innermost.
|
46
|
+
|
47
|
+
Expectations
|
48
|
+
----
|
49
|
+
|
50
|
+
In general, an RSpec example consists of some code to set up the situation being tested, and some code that called an _expectation_ that defines the expected outcome.
|
51
|
+
If an expectation fails, an exception is raised, the example stops executing, and a failure message is displayed.
|
52
|
+
Expectations look like this:
|
53
|
+
|
54
|
+
!!!ruby
|
55
|
+
expect(something).to have_some_property
|
56
|
+
expect(something).to_not have_some_property
|
57
|
+
|
58
|
+
* `expect` is a method defined by RSpec which you can use inside an example.
|
59
|
+
* `something` is the object being tested, which is usually the output of the system under test or part of the system under test.
|
60
|
+
* `to` and `to_not` are special methods defined by RSpec.
|
61
|
+
* `have_some_property` is a method call that returns a _Matcher_ object. The Matcher object decides whether the expectation was met or not. In the example below, this method call is `eq(6)`, which uses one of the [built-in matcher types that RSpec provides](https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers). Many RSpec examples only use `eq` matchers.
|
62
|
+
* Sometimes, as with `eq(6)`, you will pass arguments into the methods that create matchers. Often these arguments represent expected values, states, or properties being tested.
|
63
|
+
|
64
|
+
Here is a concrete, runnable example:
|
65
|
+
|
66
|
+
!!!ruby
|
67
|
+
describe "the number 5" do
|
68
|
+
it "when added to one is six" do
|
69
|
+
num = 1 + 5
|
70
|
+
expect(num).to eq 6
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
First, the code adds 1 to 5 and then expects it to equal 6.
|
75
|
+
Then the number 6 is passed as the first argument to `eq`, making an equality matcher that tests whether the result is equal to 6.
|
76
|
+
Note that parentheses are not required when calling a method in Ruby: you can write `eq(6)` or `eq 6`.
|
77
|
+
|
78
|
+
A common practice in RSpec is to have just one expectation per example.
|
79
|
+
This helps you organize your examples and makes it clear to the reader what each example is supposed to be testing.
|
80
|
+
However, it is not always practical because it makes the specs slower; there will be more examples and the code that gets the system into the the situation to be tested has to be run more times than necessary.
|
81
|
+
|
82
|
+
For more information, see the [RSpec Expectations documentation](https://www.relishapp.com/rspec/rspec-expectations/docs).
|
83
|
+
|
84
|
+
Before hooks
|
85
|
+
----
|
86
|
+
|
87
|
+
Inside an example group, RSpec lets you define various kinds of _hooks_. The only one we need for RPicSim is the _before hook_. A before hook runs before each example in the example group. For example:
|
88
|
+
|
89
|
+
!!!ruby
|
90
|
+
describe "my device" do
|
91
|
+
before do
|
92
|
+
# Code here runs before each example in this group.
|
93
|
+
# This is equivalent to before(:each).
|
94
|
+
end
|
95
|
+
|
96
|
+
specify do
|
97
|
+
# Code for example 1
|
98
|
+
end
|
99
|
+
|
100
|
+
specify do
|
101
|
+
# Code for example 2
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
In RPicSim, you will usually have a before hook that starts the simulation of your firmware.
|
106
|
+
|
107
|
+
If you have a context referring to your system being in a particular state, a before hook is a great place for the code that actually gets the system into that state.
|
108
|
+
The code in that hook can easily be reused in multiple examples that test different things about the state.
|
109
|
+
For example:
|
110
|
+
|
111
|
+
!!!ruby
|
112
|
+
describe "my car" do
|
113
|
+
context "in second gear at 20 MPH" do
|
114
|
+
before do
|
115
|
+
car.speed = 20
|
116
|
+
car.gear = 2
|
117
|
+
end
|
118
|
+
|
119
|
+
it "has a lot of torque" do
|
120
|
+
expect(car.torque).to eq 7
|
121
|
+
end
|
122
|
+
|
123
|
+
it "has a high RPM" do
|
124
|
+
expect(car.rpm).to eq 9001
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
Instance variables
|
130
|
+
----
|
131
|
+
|
132
|
+
In Ruby, a variable whose name starts with `@` behaves specially and is called an _instance variable_.
|
133
|
+
Instance variables defined in a before hook can be accessed in examples within the example group.
|
134
|
+
|
135
|
+
For example:
|
136
|
+
|
137
|
+
describe "foo" do
|
138
|
+
before do
|
139
|
+
@car = Car.new
|
140
|
+
@wheel = car.wheels.find_by_location(:front, :left).first
|
141
|
+
end
|
142
|
+
|
143
|
+
it "is round" do
|
144
|
+
expect(@wheel).to be_round
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
Let variables
|
150
|
+
----
|
151
|
+
|
152
|
+
Another way to define a variable in RSpec is to use the `let` syntax.
|
153
|
+
The `let` method should be called inside an example group.
|
154
|
+
The first argument is the name of a variable to define.
|
155
|
+
The `let` method is passed a block that computes the value of the variable, and the block will be called if the value of the variable is ever needed.
|
156
|
+
In other words, `let` variables are lazily evaluated.
|
157
|
+
|
158
|
+
The example below shows how a `let` variable could be useful for making your tests more readable; I only had to write the number 2 once. In this case, `let` allows us to separate the description of the expected behavior (the car can shift gears) from the arbitrary value (2) that we used to test it.
|
159
|
+
|
160
|
+
!!!ruby
|
161
|
+
describe "my car" do
|
162
|
+
let(:gear) { 2 }
|
163
|
+
|
164
|
+
it "can shift gears" do
|
165
|
+
car.gear = gear
|
166
|
+
expect(car.gear).to eq gear
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
These `let` variables can also be a useful way to share data or bits of code between different examples.
|
171
|
+
|
172
|
+
!!!ruby
|
173
|
+
describe "my car's front left wheel" do
|
174
|
+
let(:car) { Car.new }
|
175
|
+
let(:wheel) { car.wheels.find_by_location(:front, :left).first }
|
176
|
+
|
177
|
+
it "is round" do
|
178
|
+
expect(wheel).to be_round
|
179
|
+
end
|
180
|
+
|
181
|
+
it "is a wheel" do
|
182
|
+
expect(wheel).to be_a_kind_of Car::Wheel
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
Blocks in RSpec
|
188
|
+
----
|
189
|
+
|
190
|
+
Whenever you see code between the Ruby keywords `do` and `end`, or between `{` and `}`, that code is inside a Ruby _block_.
|
191
|
+
A block is a chunk of executable code that can be easily created, passed around, and called like a method.
|
192
|
+
|
193
|
+
In RSpec, the blocks you pass to the `describe` and `context` methods are executed right away.
|
194
|
+
However, the blocks passed to the `it`, `specify`, `before`, `after`, and `let` commands serve to define how the examples will be executed, and those blocks do not get called until later after RSpec has chosen which examples to run.
|
195
|
+
|
196
|
+
You cannot read a spec file like you would read a simple step-by-step program.
|
197
|
+
Any given block could be called once, multiple times, or never depending on the situation.
|
198
|
+
|
199
|
+
|
200
|
+
Shared examples
|
201
|
+
----
|
202
|
+
|
203
|
+
Sometimes you will be tempted to copy a set of examples from one context to another, because the system should behave the same in both contexts. However, your tests will be long and hard to maintain if you have too much duplicated code. In this situation, you should consider making a _shared example group_. See the [RSpec shared examples](https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples) documentation for more information.
|
@@ -0,0 +1,90 @@
|
|
1
|
+
Introduction to Ruby
|
2
|
+
====
|
3
|
+
|
4
|
+
RPicSim, and the tests that it enables you to write, are written in the {http://www.ruby-lang.org Ruby programming language}. From ruby-lang.org:
|
5
|
+
|
6
|
+
> Ruby is a dynamic, open source programming language with a focus
|
7
|
+
> on simplicity and productivity. It has an elegant syntax
|
8
|
+
> that is natural to read and easy to write.
|
9
|
+
|
10
|
+
Instead of using the standard Ruby interpreter (known as MRI), RPicSim uses {http://jruby.org JRuby} in order to gain access to the Java classes that come with MPLAB X.
|
11
|
+
|
12
|
+
This manual comes with plenty of concrete, usable examples that you can start with even if you do not know Ruby.
|
13
|
+
You should be able to accomplish a lot with RPicSim by just copying the examples in this manual, without any specific study of the Ruby language.
|
14
|
+
However, knowing Ruby will allow you to condense repetitive parts of your tests, enable you to express complex concepts, and make it much easier to troubleshoot problems.
|
15
|
+
|
16
|
+
If you are new to Ruby, I recommend spending an afternoon perusing the [Documentation page on ruby-lang.org](https://www.ruby-lang.org/en/documentation/).
|
17
|
+
If you want more, there are many books you can buy that teach Ruby.
|
18
|
+
If you have any particular questions, try searching Google and then try asking on [StackOverflow](http://www.stackoverflow.com).
|
19
|
+
Your question will probably be answered within hours, but remember to provide all the necessary information in your first post (see [SSCCE.org](http://www.sscce.org)).
|
20
|
+
|
21
|
+
|
22
|
+
Symbols
|
23
|
+
----
|
24
|
+
|
25
|
+
Whenever you see a colon followed by a word in Ruby, such as `:all`, that is called a {http://www.ruby-doc.org/core/Symbol.html Symbol}.
|
26
|
+
Symbols are a part of the Ruby language.
|
27
|
+
They are like strings, but the main difference is that they are not mutable; they cannot be changed after they have been made.
|
28
|
+
RPicSim almost always uses symbols instead of strings to represent names of things.
|
29
|
+
|
30
|
+
|
31
|
+
Method calls
|
32
|
+
----
|
33
|
+
|
34
|
+
Ruby does not require parentheses around method arguments.
|
35
|
+
The following code retrieves the `sim` object and calls its `run_cycles` method with an argument of 250:
|
36
|
+
|
37
|
+
!!!ruby
|
38
|
+
sim.run_cycles 250
|
39
|
+
|
40
|
+
|
41
|
+
Hashes
|
42
|
+
----
|
43
|
+
|
44
|
+
Ruby has a built-in hash table implementation called {http://www.ruby-doc.org/core/Hash.html Hash}.
|
45
|
+
A hash can hold any type of Ruby object as keys and values.
|
46
|
+
|
47
|
+
Here is some example code that makes a hash that associates the symbol `:cycle_limit` to the number 500:
|
48
|
+
|
49
|
+
!!!ruby
|
50
|
+
hash = { :cycle_limit => 500 }
|
51
|
+
|
52
|
+
Since the key is a symbol, we can simplify this using special Ruby syntax:
|
53
|
+
|
54
|
+
hash = { cycle_limit: 500 }
|
55
|
+
|
56
|
+
Multiple pairs can be separated by commas:
|
57
|
+
|
58
|
+
!!!ruby
|
59
|
+
hash = { temperature: 30, humidity: 10 }
|
60
|
+
|
61
|
+
Values can be read or written after the hash is created:
|
62
|
+
|
63
|
+
!!!ruby
|
64
|
+
hash = {}
|
65
|
+
hash[:cycle_limit] = 500
|
66
|
+
hash[:cycle_limit] # returns 500
|
67
|
+
|
68
|
+
Ruby has a special syntax for passing a hash as the last argument of a method call; you do not need to write the brackets:
|
69
|
+
|
70
|
+
!!!ruby
|
71
|
+
sim.run_to :loopDone, cycle_limit: 44
|
72
|
+
|
73
|
+
|
74
|
+
Blocks
|
75
|
+
----
|
76
|
+
|
77
|
+
Whenever you see code between the Ruby keywords `do` and `end`, or between `{` and `}`, that code is inside a Ruby _block_.
|
78
|
+
A block is a chunk of executable code that can be easily created, passed around, and called like a method.
|
79
|
+
Any given block could be called once, multiple times, or never depending on the situation.
|
80
|
+
|
81
|
+
For example, here is some code that passes a black to a method called `foo_method`.
|
82
|
+
The block prints "hello world" to the standard output.
|
83
|
+
|
84
|
+
!!!ruby
|
85
|
+
foo_method do
|
86
|
+
puts "hello world"
|
87
|
+
end
|
88
|
+
|
89
|
+
Depending on how `foo_method` behaves, this code could output "hello world" any number of times or not at all.
|
90
|
+
Also, `foo_method` might store the block in an object and call it at some later point in the program.
|
data/docs/KnownIssues.md
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
Known issues
|
2
|
+
====
|
3
|
+
|
4
|
+
This page documents all the known issues RPicSim has that could affect its users.
|
5
|
+
Some issues are caused by the MPLAB X simulator and would need to be addressed by Microchip.
|
6
|
+
|
7
|
+
RPicSim has only been tested with the following versions of MPLAB X:
|
8
|
+
|
9
|
+
* 1.85
|
10
|
+
* 1.90
|
11
|
+
* 1.95
|
12
|
+
* 2.00
|
13
|
+
|
14
|
+
If you are using a different version of MPLAB X, some of the issues might not apply to you.
|
15
|
+
|
16
|
+
Many of these issues have only been reproduced on a single model of PIC microcontroller and they may or may not affect other models.
|
17
|
+
|
18
|
+
Many of these issues are also reported on other pages of this {file:Manual.md manual}, but this page is a complete list of all issues that could affect users of RPicSim.
|
19
|
+
|
20
|
+
Internal issues that have been successfully worked around are not listed here, but might be found in the RPicSim specs by searching for the word "flaw".
|
21
|
+
|
22
|
+
There are almost certainly many issues that have not been found yet.
|
23
|
+
|
24
|
+
|
25
|
+
MPLAB X simulator does not support all PIC devices equally
|
26
|
+
----
|
27
|
+
_Type: MPLAB X missing feature_
|
28
|
+
|
29
|
+
Be sure to check the Device Support table to see if your device is properly supported by the MPLAB X simulator.
|
30
|
+
The table can be found in your MPLAB X installation folder under "`docs/Device Support.htm`".
|
31
|
+
The _SIMISA_ column probably stands for "Simulator (instruction set and architecture)" while the _SIMP_ column probably stands for "Simulator (peripherals)".
|
32
|
+
|
33
|
+
|
34
|
+
Simulation timing is affected by the details of how long each instruction takes
|
35
|
+
----
|
36
|
+
_Type: MPLAB X missing feature_
|
37
|
+
|
38
|
+
As mentioned on the {file:Running.md Running} page, RPicSim's only way to advance the simulation is to execute an entire instruction.
|
39
|
+
Some instructions take two instruction cycles to run and others only take one.
|
40
|
+
When you request RPicSim to delay for a certain number of cycles, it might need to delay by one cycle more than was requested since it cannot stop in the middle of a two-cycle instruction.
|
41
|
+
As a result, the timing of your tests and the input signals you send to the simulated device can sometimes be slightly off and these errors could accumulate in longer tests.
|
42
|
+
|
43
|
+
One workaround that prevents timing errors from accumulating is to only use {RPicSim::Sim#run_to_cycle_count} to run the simulation.
|
44
|
+
|
45
|
+
|
46
|
+
MPLAB X must be on the C drive
|
47
|
+
----
|
48
|
+
_Type: MPLAB X bug_
|
49
|
+
|
50
|
+
_MPLAB X versions affected: all tested versions_
|
51
|
+
|
52
|
+
In Windows, a bug in MPLAB X prevents RPicSim from using an MPLAB X installed on any drive other than the C drive.
|
53
|
+
|
54
|
+
This issue is tested in `spec/mplab_x/path_retrieval_spec.rb`.
|
55
|
+
|
56
|
+
|
57
|
+
Firmware under test must be inside a folder named "dist"
|
58
|
+
----
|
59
|
+
_Type: MPLAB X bug_
|
60
|
+
|
61
|
+
_MPLAB X versions affected: all tested versions_
|
62
|
+
|
63
|
+
This issue is tested in `spec/mplab_x/program_file_spec.rb`.
|
64
|
+
|
65
|
+
|
66
|
+
Limited number of variable types supported
|
67
|
+
----
|
68
|
+
_Type: RPicSim missing feature_
|
69
|
+
|
70
|
+
There is no support for variables larger than 32 bits.
|
71
|
+
There is no support for arrays or structs of variables.
|
72
|
+
There is also no support for reading and writing directly from the simulated device's RAM, Flash, EEPROM, and stack memories from Ruby.
|
73
|
+
|
74
|
+
No EEPROM support
|
75
|
+
----
|
76
|
+
_Type: RPicSim missing feature_
|
77
|
+
|
78
|
+
RPicSim does not support reading or writing from EEPROM from Ruby.
|
79
|
+
|
80
|
+
|
81
|
+
Dissasembly is limited to midrange and baseline PIC microcontrollers
|
82
|
+
----
|
83
|
+
_Type: RPicSim missing feature_
|
84
|
+
|
85
|
+
The disassembled instruction graph created by {RPicSim::ProgramFile} currently only supports baseline and midrange PICs, but it should be easy to expand to other PICs.
|
86
|
+
This is a side feature of RPicSim, and not required for simulation.
|
87
|
+
|
88
|
+
|
89
|
+
Stack trace will show slightly wrong values for PIC18 microcontrollers
|
90
|
+
----
|
91
|
+
_Type: RPicSim bug_
|
92
|
+
|
93
|
+
For the PIC18, {RPicSim::Sim#stack_trace} will probably show values that are too high by one because it does not account for the fact that PIC18 instructions take two bytes.
|
94
|
+
|
95
|
+
|
96
|
+
Cannot detect PIC model from COF file
|
97
|
+
----
|
98
|
+
_Type: RPicSim missing feature_
|
99
|
+
|
100
|
+
The MPLAB X code might allow RPicSim to detect the PIC device name from the COF file so that the user does not have to specify it when creating a {RPicSim::ProgramFile} or a subclass of {RPicSim::Sim}.
|
101
|
+
Currently RPicSim requires the user to always specify the PIC device name.
|
102
|
+
|
103
|
+
|
104
|
+
Not tested on Linux and Mac OS X
|
105
|
+
----
|
106
|
+
_Type: RPicSim missing feature_
|
107
|
+
|
108
|
+
RPicSim has not been tested on Linux and Mac OS X. See {file:SupportedOperatingSystems.md Supported operating systems} for more information.
|
109
|
+
|
110
|
+
|
111
|
+
Variables defined in user ID space are not read from the COF file
|
112
|
+
----
|
113
|
+
_Type: MPLAB X bug_
|
114
|
+
|
115
|
+
_MPLAB X version affected: all tested versions_
|
116
|
+
|
117
|
+
The workaround is to simply set any variables defined in user ID space to the correct values from Ruby before running the simulation.
|
118
|
+
This issue is tested in `spec/integration/flash_variable_spec.rb`.
|
119
|
+
|
120
|
+
|
121
|
+
Simulated firmware cannot write to the first user ID location
|
122
|
+
----
|
123
|
+
_Type: MPLAB X bug_
|
124
|
+
|
125
|
+
_MPLAB X versions affected: 1.85, 1.90_
|
126
|
+
|
127
|
+
This issue is tested in `spec/integration/flash_variable_spec.rb`.
|
128
|
+
It has been {http://www.microchip.com/forums/m743214.aspx reported to Microchip} and was fixed in later versions.
|
129
|
+
|
130
|
+
|
131
|
+
Pins report the wrong output state if the ANSELx bit is 1
|
132
|
+
----
|
133
|
+
_Type: MPLAB X bug_
|
134
|
+
|
135
|
+
_MPLAB X versions affected: all tested versions_
|
136
|
+
|
137
|
+
The ANSELx bit for a real PIC pin only disables the digital input circuitry and should not affect the pin's use as a digital output.
|
138
|
+
However, if the ANSELx bit is set to 1, then {RPicSim::Pin#driving_low?} always seems to return true even if the pin is actually driving high.
|
139
|
+
|
140
|
+
This issue is tested in `spec/integration/pin_spec.rb`.
|
141
|
+
|
142
|
+
|
143
|
+
Pins report the wrong output state if LATx is set before TRISx
|
144
|
+
----
|
145
|
+
_Type: MPLAB X bug_
|
146
|
+
|
147
|
+
_MPLAB X versions affected: all tested versions_
|
148
|
+
|
149
|
+
Updating a pin's LATx bit before its clearing its TRISx bit is the proper way to turn on an output pin without causing glitches.
|
150
|
+
However, if you set the two bits in that order then {RPicSim::Pin#driving_low?} always seems to return true even if the pin is actually driving high.
|
151
|
+
|
152
|
+
This issue is tested in `spec/integration/pin_spec.rb`.
|
153
|
+
|
154
|
+
|
155
|
+
Pins report the wrong output state if TRISx is cleared again
|
156
|
+
----
|
157
|
+
_Type: MPLAB X bug_
|
158
|
+
|
159
|
+
_MPLAB X versions affected: all tested versions_
|
160
|
+
|
161
|
+
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.
|
162
|
+
|
163
|
+
This issue is tested in `spec/integration/pin_spec.rb`.
|
164
|
+
|
165
|
+
|
166
|
+
RAM watcher is useless because all of RAM seems to change on every step
|
167
|
+
----
|
168
|
+
_Type: MPLAB X bug_
|
169
|
+
|
170
|
+
_MPLAB X versions affected: 1.95, 2.00_
|
171
|
+
|
172
|
+
This issue is tested in `spec/mplab_x/memory_attach_spec.rb`.
|
173
|
+
If you want to use the {file:RamWatcher.md RAM watcher}, you should use MPLAB X version 1.85 or 1.90.
|
174
|
+
|
175
|
+
|
176
|
+
RAM watcher reports a write to PORTA instead of to LATA
|
177
|
+
----
|
178
|
+
_Type: MPLAB X bug_
|
179
|
+
|
180
|
+
_MPLAB X versions affected: all tested versions_
|
181
|
+
|
182
|
+
The {file:RamWatcher.md RAM watcher}, when testing code that writes to LATA, might actually report it as a write to PORTA instead of LATA.
|
183
|
+
This issue has been observed on a PIC10F322 but it probably affects other PORTx and LATx registers.
|
184
|
+
|
185
|
+
This issue is tested in `spec/integration/ram_watcher_spec.rb`.
|
186
|
+
This issue could not be tested on MPLAB X versions affected by the "RAM watcher is useless" issue above.
|
187
|
+
|
188
|
+
|
189
|
+
Midrange ADC gives incorrect readings
|
190
|
+
----
|
191
|
+
_Type: MPLAB X bug_
|
192
|
+
|
193
|
+
_MPLAB X versions affected: all tested versions_
|
194
|
+
|
195
|
+
The simulated ADC for midrange PIC microcontrollers has various issues in different versions of MPLAB X that make it give incorrect readings.
|
196
|
+
These issues might affect other PIC architectures as well.
|
197
|
+
|
198
|
+
* **Bad modulus:** In MPLAB X 1.90 and later, simply setting a pin to high with `pin.set(true)` will result in an ADC reading of 0.
|
199
|
+
The workaround is to use `pin.set(4.9)`.
|
200
|
+
The ADC acts like it is using a modulus operator incorrectly as a way of limiting the ADC result to be between 0 and 255.
|
201
|
+
* **No intermediate values:** In MPLAB X 1.85, setting a pin to any voltage other than 0 V will result in an ADC reading of 255.
|
202
|
+
|
203
|
+
These issues are tested in `spec/integration/adc_midrange_spec.rb`. The bad modulus issue was {http://www.microchip.com/forums/m760886.aspx reported to Microchip} in November 2013.
|
204
|
+
|