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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 68c98fd21ee27688b36375bd75f7a3a7e3755c8d
|
4
|
+
data.tar.gz: 9cf6e19491d34d6d59ab2d8ecd80a730bf72eb42
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 38b585a3818466ed83a7bc012b9cbc5606f89413f39a7d05bc1784d3de243cf23a41043bc3931f41cea0d6ab3a2089434450b9eb207d3d1048dc2b7dd1de0592
|
7
|
+
data.tar.gz: d47eccfcfe720bb7805a4a5131e4f251d1d5c0479ee2d39131e2f4502c96e99a67e4c9231e1f76627ef2252b1b0da299744ccb59084fc3973a116b762028b473
|
data/.yardopts
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
lib/rpicsim/**/*.rb
|
2
|
+
--readme Introduction.md
|
3
|
+
--load docs/plugin/plugin.rb
|
4
|
+
-
|
5
|
+
docs/Manual.md
|
6
|
+
docs/ChangeLog.md
|
7
|
+
docs/QuickStartGuide.md
|
8
|
+
docs/SupportedDevices.md
|
9
|
+
docs/SupportedCompilers.md
|
10
|
+
docs/SupportedMPLABXVersions.md
|
11
|
+
docs/SupportedOperatingSystems.md
|
12
|
+
|
13
|
+
docs/IntroductionToRuby.md
|
14
|
+
docs/DefiningSimulationClass.md
|
15
|
+
docs/Pins.md
|
16
|
+
docs/Labels.md
|
17
|
+
docs/Running.md
|
18
|
+
docs/Variables.md
|
19
|
+
docs/SFRs.md
|
20
|
+
docs/RamWatcher.md
|
21
|
+
docs/PreventingCallStackOverflow.md
|
22
|
+
|
23
|
+
docs/IntroductionToRSpec.md
|
24
|
+
docs/UnitTesting.md
|
25
|
+
docs/IntegrationTesting.md
|
26
|
+
docs/RSpecIntegration.md
|
27
|
+
docs/PersistentExpectations.md
|
28
|
+
|
29
|
+
docs/Stubbing.md
|
30
|
+
docs/MakingTestsRunFaster.md
|
31
|
+
docs/Debugging.md
|
32
|
+
|
33
|
+
docs/HowMPLABXIsFound.md
|
34
|
+
docs/KnownIssues.md
|
35
|
+
docs/DesignDecisions.md
|
36
|
+
docs/Contributing.md
|
data/Gemfile
ADDED
data/Introduction.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# RPicSim: Ruby PIC® simulator interface
|
2
|
+
|
3
|
+
The RPicSim library provides an interface to the MPLAB® X PIC® simulator that allows you to write simulator-based automated tests of PIC firmware.
|
4
|
+
RPicSim is written in the [Ruby language](http://ruby-lang.org) and runs on [JRuby](http://jruby.org).
|
5
|
+
It can be used in any type of JRuby application, and it has bindings that make it especially convenient to use with the [RSpec](http://rspec.info) testing framework.
|
6
|
+
RPicSim is free to use and does not require any external hardware.
|
7
|
+
|
8
|
+
With RPicSim, you can write tests for your PIC firmware in the Ruby language. Here is an example integration test that simulates input and output on the device's pins:
|
9
|
+
|
10
|
+
!!!ruby
|
11
|
+
it "continuously mirrors" do
|
12
|
+
main_input.set false
|
13
|
+
run_cycles 10
|
14
|
+
expect(main_output).to be_driving_low
|
15
|
+
|
16
|
+
main_input.set true
|
17
|
+
run_cycles 10
|
18
|
+
expect(main_output).to be_driving_high
|
19
|
+
end
|
20
|
+
|
21
|
+
Here is an example unit test written with RPicSim that tests a single subroutine in the firmware:
|
22
|
+
|
23
|
+
!!!ruby
|
24
|
+
it "adds 70 to 22" do
|
25
|
+
addend1.value = 70
|
26
|
+
addend2.value = 22
|
27
|
+
run_subroutine :addition, cycle_limit: 100
|
28
|
+
expect(sum.value).to eq 92
|
29
|
+
end
|
30
|
+
|
31
|
+
Simulator-based testing has many advantages over testing in hardware:
|
32
|
+
|
33
|
+
* Simulator-based unit tests can help catch bugs sooner.
|
34
|
+
* You can debug your firmware without having to connect an oscilloscope or add special debugging signals.
|
35
|
+
* The tests are inherently deterministic.
|
36
|
+
* The tests usually require no extra code to be added to the firmware.
|
37
|
+
|
38
|
+
RPicSim has features that allow you to:
|
39
|
+
|
40
|
+
* Simulate signals on inputs pins.
|
41
|
+
* Read the state of output pins.
|
42
|
+
* Run small parts of your code in isolation.
|
43
|
+
* Read and write from variables and special function registers (SFRs).
|
44
|
+
* Monitor all writes to RAM.
|
45
|
+
* Run assertions at every step of a simulation.
|
46
|
+
|
47
|
+
For some applications, RPicSim can also analyze the firmware and verify that the call stack will never overflow.
|
48
|
+
|
49
|
+
RPicSim is distributed as a Ruby gem named `rpicsim`. To install RPicSim, run:
|
50
|
+
|
51
|
+
jgem install rpicsim
|
52
|
+
|
53
|
+
|
54
|
+
RPicSim has been tested with MPLAB X v1.85, v1.90, v1.95, and v2.00.
|
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.
|
56
|
+
|
57
|
+
RPicSim is not intended to replace formal specifications, code reviews, and rigorous testing of your firmware on actual hardware.
|
58
|
+
RPicSim is just another tool that can make it easier to write and test the firmware.
|
59
|
+
|
60
|
+
The names Microchip, PIC, MPLAB, and MPASM are trademarks of Microchip Technology Incorporated. RPicSim is not written, supported, or endorsed by Microchip.
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2014 Pololu Corporation. For more information, see
|
2
|
+
|
3
|
+
http://www.pololu.com/
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person
|
6
|
+
obtaining a copy of this software and associated documentation
|
7
|
+
files (the "Software"), to deal in the Software without
|
8
|
+
restriction, including without limitation the rights to use,
|
9
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
copies of the Software, and to permit persons to whom the
|
11
|
+
Software is furnished to do so, subject to the following
|
12
|
+
conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
19
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
21
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
22
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
23
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
24
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# RPicSim: Ruby PIC<sup>®</sup> simulator interface
|
2
|
+
|
3
|
+
The RPicSim library provides an interface to the MPLAB<sup>®</sup> X PIC<sup>®</sup> simulator that allows you to write simulator-based automated tests of PIC firmware.
|
4
|
+
RPicSim is written in the [Ruby language](http://ruby-lang.org) and runs on [JRuby](http://jruby.org).
|
5
|
+
It can be used in any type of JRuby application, and it has bindings that make it especially convenient to use with the [RSpec](http://rspec.info) testing framework.
|
6
|
+
RPicSim is free to use and does not require any external hardware.
|
7
|
+
|
8
|
+
With RPicSim, you can write tests for your PIC firmware in the Ruby language. Here is an example integration test that simulates input and output on the device's pins:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
it "continuously mirrors" do
|
12
|
+
main_input.set false
|
13
|
+
run_cycles 10
|
14
|
+
expect(main_output).to be_driving_low
|
15
|
+
|
16
|
+
main_input.set true
|
17
|
+
run_cycles 10
|
18
|
+
expect(main_output).to be_driving_high
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
Here is an example unit test written with RPicSim that tests a single subroutine in the firmware:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
it "adds 70 to 22" do
|
26
|
+
addend1.value = 70
|
27
|
+
addend2.value = 22
|
28
|
+
run_subroutine :addition, cycle_limit: 100
|
29
|
+
expect(sum.value).to eq 92
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Simulator-based testing has many advantages over testing in hardware:
|
34
|
+
|
35
|
+
* Simulator-based unit tests can help catch bugs sooner.
|
36
|
+
* You can debug your firmware without having to connect an oscilloscope or add special debugging signals.
|
37
|
+
* The tests are inherently deterministic.
|
38
|
+
* The tests usually require no extra code to be added to the firmware.
|
39
|
+
|
40
|
+
RPicSim has features that allow you to:
|
41
|
+
|
42
|
+
* Simulate signals on inputs pins.
|
43
|
+
* Read the state of output pins.
|
44
|
+
* Run small parts of your code in isolation.
|
45
|
+
* Read and write from variables and special function registers (SFRs).
|
46
|
+
* Monitor all writes to RAM.
|
47
|
+
* Run assertions at every step of a simulation.
|
48
|
+
|
49
|
+
For some applications, RPicSim can also analyze the firmware and verify that the call stack will never overflow.
|
50
|
+
|
51
|
+
RPicSim is distributed as a Ruby gem named `rpicsim`. To install RPicSim, run:
|
52
|
+
|
53
|
+
jgem install rpicsim
|
54
|
+
|
55
|
+
|
56
|
+
RPicSim has been tested with MPLAB X v1.85, v1.90, v1.95, and v2.00.
|
57
|
+
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
|
+
|
59
|
+
RPicSim is not intended to replace formal specifications, code reviews, and rigorous testing of your firmware on actual hardware.
|
60
|
+
RPicSim is just another tool that can make it easier to write and test the firmware.
|
61
|
+
|
62
|
+
The names Microchip, PIC, MPLAB, and MPASM are trademarks of Microchip Technology Incorporated. RPicSim is not written, supported, or endorsed by Microchip.
|
63
|
+
|
64
|
+
<github>For complete documentation, see the [RPicSim API documentation](http://www.davidegrayson.com/hold/rpicsim/_index.html) and the [RPicSim manual](http://www.davidegrayson.com/hold/rpicsim/file.Manual.html).</github>
|
65
|
+
|
66
|
+
|
data/docs/ChangeLog.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Change log
|
2
|
+
====
|
3
|
+
|
4
|
+
0.1.0
|
5
|
+
----
|
6
|
+
|
7
|
+
Released on 2014-02-12.
|
8
|
+
This is the initial release.
|
9
|
+
There are still some major things missing from this version that need to be added before we release 1.0.0.
|
10
|
+
Until 1.0.0 is released, we will not worry about backwards compatibility or writing complete change logs.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Contributing
|
2
|
+
====
|
3
|
+
|
4
|
+
RPicSim is hosted on the [pololu/rpicsim github page](https://github.com/pololu/rpicsim).
|
5
|
+
|
6
|
+
To report a bug, go to a github page and create a new issue.
|
7
|
+
|
8
|
+
If you want to contribute code, these are the general steps:
|
9
|
+
|
10
|
+
1. Clone our git repository to your computer.
|
11
|
+
2. Install JRuby and MPLAB X if you have not done so already.
|
12
|
+
3. Run these commands to get the development dependencies:
|
13
|
+
|
14
|
+
jgem install bundler
|
15
|
+
bundle
|
16
|
+
|
17
|
+
4. Run the specs with the command `bundle exec rake` to make sure they are working.
|
18
|
+
5. Add a new spec somewhere in the `spec` directory for the bug or feature you want to fix.
|
19
|
+
6. Run the specs again to make sure your spec is failing.
|
20
|
+
7. Modify the code.
|
21
|
+
8. Run the specs again to make sure they are all passing.
|
22
|
+
9. Fork our repository on github and push your changes to a branch of your repository. It is good practice make a branch with a special name and push to that instead of master.
|
23
|
+
10. On github, make a pull request from your branch to our repository.
|
24
|
+
|
25
|
+
You can generate documentation from the source code by running:
|
26
|
+
|
27
|
+
bundle exec rake doc
|
28
|
+
|
29
|
+
If you have multiple versions of Ruby installed it is good to keep just one version of Ruby on your PATH at any given time so you do not accidentally run the wrong version.
|
30
|
+
|
data/docs/Debugging.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
Debugging
|
2
|
+
====
|
3
|
+
|
4
|
+
RPicSim makes it easier to fix firmware bugs that you have found.
|
5
|
+
With RPicSim, you have access to the entire state of the simulation at every step.
|
6
|
+
You can see exactly how your code is behaving without having to hook up an oscilloscope or add debugging signals.
|
7
|
+
|
8
|
+
Suppose you are writing an RSpec-based integration test that fails with the following error message:
|
9
|
+
|
10
|
+
!!!plain
|
11
|
+
................................................F.....
|
12
|
+
|
13
|
+
Failures:
|
14
|
+
|
15
|
+
1) FooWidget when exposed to 1.5 ms pulses behaves correctly
|
16
|
+
Failure/Error: run_cycles 1500*4
|
17
|
+
expected INTCON to satisfy block
|
18
|
+
# ./lib/rpicsim/rspec/persistent_expectations.rb:29:in `check_expectations'
|
19
|
+
# ./lib/rpicsim/rspec/persistent_expectations.rb:27:in `check_expectations'
|
20
|
+
# ./lib/rpicsim/rspec/helpers.rb:25:in `start_sim'
|
21
|
+
# ./lib/rpicsim/sim.rb:574:in `step'
|
22
|
+
# ./lib/rpicsim/sim.rb:716:in `run_to_cycle_count'
|
23
|
+
# ./lib/rpicsim/sim.rb:708:in `run_cycles'
|
24
|
+
# ./spec/foo_widget_spec.rb:10:in `(root)'
|
25
|
+
|
26
|
+
Simulation cycle count: 78963
|
27
|
+
|
28
|
+
Simulation stack trace:
|
29
|
+
0x01A0 = startMotor
|
30
|
+
0x0044 = motorService+0x14
|
31
|
+
0x0B12 = mainLoop+0x2
|
32
|
+
0x008C = start2
|
33
|
+
|
34
|
+
Finished in 4.55 seconds
|
35
|
+
44 examples, 1 failure
|
36
|
+
|
37
|
+
Failed examples:
|
38
|
+
|
39
|
+
rspec ./spec/example/nice_error_spec.rb:8 # FooWidget when exposed to 1.5ms pulses behaves correctly
|
40
|
+
|
41
|
+
In this example, we had a {file:PersistentExpectations.md persistent expectation} asserting something about the INTCON SFR and and at some point in a lengthy integration test our expectation failed.
|
42
|
+
|
43
|
+
The stack trace gives us a big clue about what code might be causing the problem.
|
44
|
+
If we want to inspect the situation more carefully, we could use `run_to_cycle_count 78950` to run the simulation to a point just a few cycles before the error happened and then insert code at the point to do something special.
|
45
|
+
Two different options are described below.
|
46
|
+
|
47
|
+
|
48
|
+
Logging
|
49
|
+
----
|
50
|
+
One option for debugging is to print some debugging information to the console after each step.
|
51
|
+
For example, we might insert this code into the appropriate point in the RSpec example that is failing:
|
52
|
+
|
53
|
+
!!!ruby
|
54
|
+
run_to_cycle_count 78950
|
55
|
+
100.times do
|
56
|
+
step
|
57
|
+
puts pc_description + " wreg=" + wreg.value.to_s
|
58
|
+
end
|
59
|
+
|
60
|
+
This code runs until the cycle count of the simulation is 78950, and then it starts printing debugging information for the next 100 steps.
|
61
|
+
This example prints a friendly description of the program counter's value and the current value of WREG, but it could be changed to print other things.
|
62
|
+
|
63
|
+
|
64
|
+
Interactive debugging
|
65
|
+
----
|
66
|
+
You can also start an interactive session that allows you to manipulate the simulation and inspect its state.
|
67
|
+
This section shows how to use the ruby-debug gem, but there are other tools that could probably do the same thing (Ripl, PRY, and IRB).
|
68
|
+
|
69
|
+
First, install ruby-debug by running:
|
70
|
+
|
71
|
+
!!!plain
|
72
|
+
jgem install ruby-debug
|
73
|
+
|
74
|
+
In the test that is failing, choose the point where you want to start the interactive session and insert this code:
|
75
|
+
|
76
|
+
!!!plain
|
77
|
+
require 'ruby-debug'; debugger
|
78
|
+
|
79
|
+
For best results when using the debugger, you need to provide the `--debug` option to JRuby. From bash, you can do this by running a command like
|
80
|
+
|
81
|
+
!!!plain
|
82
|
+
RUBYOPT=--debug rspec
|
83
|
+
|
84
|
+
If you are using a Windows Command Prompt, you need to set the environment with the `set` command before running RSpec:
|
85
|
+
|
86
|
+
!!!plain
|
87
|
+
set RUBYOPT=--debug
|
88
|
+
rspec
|
89
|
+
|
90
|
+
This debugger provides many commands, but the only one you really need is the `p` command because it can run arbitrary code.
|
91
|
+
To advance the simulation by one step and print a friendly description of where the program counter is pointing, you could run `p step; p pc_description` as shown below:
|
92
|
+
|
93
|
+
!!!plain
|
94
|
+
(rdb:1) p step; p pc_description
|
95
|
+
nil
|
96
|
+
"0x0044 = motorService+0x0E"
|
@@ -0,0 +1,84 @@
|
|
1
|
+
Defining your simulation class
|
2
|
+
====
|
3
|
+
|
4
|
+
In order to run a simulation of your firmware using RPicSim, you must make a new subclass of {RPicSim::Sim}. This class is called your _simulation class_. Below is an example:
|
5
|
+
|
6
|
+
class MySim < RPicSim::Sim
|
7
|
+
device_is "PIC10F322"
|
8
|
+
filename_is File.dirname(__FILE__) + "../firmware/dist/firmware.cof"
|
9
|
+
end
|
10
|
+
|
11
|
+
A full list of the special RPicSim methods you can call inside your class definition can be found by looking at the documentation for {RPicSim::Sim::ClassDefinitionMethods}.
|
12
|
+
|
13
|
+
Required properties
|
14
|
+
----
|
15
|
+
|
16
|
+
There are two things you must do inside a simulation class.
|
17
|
+
|
18
|
+
First, call {RPicSim::Sim::ClassDefinitionMethods#device_is device_is} in order to specify the PIC device your firmware runs on. Unfortunately, RPicSim cannot just detect this information from your COF file. The argument to `device_is` should be a simple string containing the official name of the PIC device, like "PIC10F322".
|
19
|
+
|
20
|
+
Second, call {RPicSim::Sim::ClassDefinitionMethods#filename_is filename_is} to specify the path to your COF or HEX file. This must be done after calling `device_is`.
|
21
|
+
In the example, we start with `File.dirname(__FILE__)`, which is the name of the directory that the current Ruby file is in, and add a string to that.
|
22
|
+
This allows us to move our tests and firmware files around on the disk without changing the `filename_is` line.
|
23
|
+
|
24
|
+
Pins
|
25
|
+
----
|
26
|
+
|
27
|
+
You can use {RPicSim::Sim::ClassDefinitionMethods#def_pin def_pin} to define an alternative name for a pin. For more information, see {file:Pins.md}.
|
28
|
+
|
29
|
+
|
30
|
+
Variables
|
31
|
+
----
|
32
|
+
|
33
|
+
You can use {RPicSim::Sim::ClassDefinitionMethods#def_var def_var} to define a variable in RAM, and {RPicSim::Sim::ClassDefinitionMethods#def_flash_var def_flash_var} to define a variable in flash. For more information, see {file:Variables.md}.
|
34
|
+
|
35
|
+
|
36
|
+
Methods
|
37
|
+
----
|
38
|
+
|
39
|
+
It is sometimes helpful to define your own methods in the simulation class. For example, here are some methods that help us simulate the effect of the user placing a jumper between RA1 and GND:
|
40
|
+
|
41
|
+
class MySim < RPicSim::Sim
|
42
|
+
device_is "PIC10F322"
|
43
|
+
filename_is File.dirname(__FILE__) + "../firmware/dist/firmware.cof"
|
44
|
+
|
45
|
+
def jumper_on
|
46
|
+
pin(:RA1).set false
|
47
|
+
end
|
48
|
+
|
49
|
+
def jumper_off
|
50
|
+
pin(:RA1).set true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
By making these `jumper_on` and `jumper_off` methods, we can write lots of tests that manipulate the jumper but we don't have to constantly worry about how the hardware jumper is implemented when writing or reading those tests.
|
55
|
+
This makes our tests clearer to the reader and makes it easier to adapt them to change.
|
56
|
+
|
57
|
+
If you have an instance of the simulation class, you can call such a method in the usual way:
|
58
|
+
|
59
|
+
sim.jumper_on
|
60
|
+
|
61
|
+
|
62
|
+
Using the simulation class
|
63
|
+
----
|
64
|
+
|
65
|
+
To start a new simulation, you can simply make a new instance of the simulation class. For example:
|
66
|
+
|
67
|
+
sim = MySim.new
|
68
|
+
|
69
|
+
However, if you are using RSpec and RPicSim's {file:RSpecIntegration.md RSpec Integration}, then you should not create a new instance yourself.
|
70
|
+
Instead, make a before hook that calls {RPicSim::RSpec::Helpers#start_sim start_sim}.
|
71
|
+
This will start the simulation for you and use it to make some other methods and features available in your examples.
|
72
|
+
After running {RPicSim::RSpec::Helpers#start_sim start_sim}, you will be able to access your simulation object using the method `sim`.
|
73
|
+
|
74
|
+
For example:
|
75
|
+
|
76
|
+
describe "my firmware" do
|
77
|
+
before do
|
78
|
+
start_sim MySim
|
79
|
+
end
|
80
|
+
|
81
|
+
it "runs to the :abc label" do
|
82
|
+
sim.run_to :abc, cycle_limit: 100
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
Design decisions
|
2
|
+
====
|
3
|
+
|
4
|
+
|
5
|
+
Why use JRuby?
|
6
|
+
----
|
7
|
+
[Ruby](https://www.ruby-lang.org/) is a great, versatile programming language and it is a pleasure to work in.
|
8
|
+
The Ruby community has produced many books, blog posts, and online tutorials about Ruby.
|
9
|
+
Many questions about Ruby and RSpec are answered within minutes on [StackOverflow](http://www.stackoverflow.com).
|
10
|
+
|
11
|
+
[JRuby](http://jruby.org) is a Java implementation of the [Ruby programming language](https://www.ruby-lang.org/).
|
12
|
+
Since it runs on the Java Virtual Machine (JVM), JRuby programs can easily access the Microchip Java classes, which do the real work of simulating the PIC microcontroller.
|
13
|
+
|
14
|
+
Unlike many other languages on the JVM, JRuby doesn't require compilation.
|
15
|
+
This means you don't need to worry about juggling Makefiles and IDEs while you are writing your tests.
|
16
|
+
Checking out your latest commit from version control is all that is needed to ensure you are running the latest tests.
|
17
|
+
|
18
|
+
|
19
|
+
Why use RPicSim instead of just accessing the Microchip classes directly?
|
20
|
+
----
|
21
|
+
The Microchip classes are mostly undocumented and are complicated to use.
|
22
|
+
With Ruby and RPicSim, we can have a simple, intuitive domain-specific language (DSL) for dealing with PIC simulations.
|
23
|
+
Also, by writing your tests with RPicSim there is some hope that you will be shielded from future changes in the MPLAB X code.
|
24
|
+
|
25
|
+
|
26
|
+
Why use RSpec?
|
27
|
+
----
|
28
|
+
RSpec provides great ways to combine code from similar tests, provides good error messages, and encourages you to specify exactly what you are testing.
|
29
|
+
It is popular in the Ruby community.
|
30
|
+
|
31
|
+
|
32
|
+
Why not use SCL?
|
33
|
+
----
|
34
|
+
Microchip's [Stimulus Control Language (SCL)](http://www.microchip.com/forums/m111255.aspx) serves a lot of the same purposes as RPicSim.
|
35
|
+
It can simulate an external stimulus being applied to pins of a device and see how it behaves.
|
36
|
+
MPLAB X has a button in the "Stimulus" pane for attaching an SCL script to a simulation.
|
37
|
+
|
38
|
+
We have not used SCL and don't know much about it, but we think the main reasons to not use SCL are:
|
39
|
+
|
40
|
+
* It seems like SCL does not have several features required for unit tests, such as reading and writing the internal state of the simulated device.
|
41
|
+
* SCL does not appear to have functions or subroutines.
|
42
|
+
* SCL has been around since at least 2005, but as of January 2014, it seems to not be officially documented.
|
43
|
+
The only documentation we could find is in the form of a few long forum posts at the top of the [MPLAB Simulator forum](http://www.microchip.com/forums/f18.aspx).
|
44
|
+
|
45
|
+
|
46
|
+
Why not use Textile?
|
47
|
+
----
|
48
|
+
Textile was not used as a markup language for the documentation because we could not figure out how to easily have Ruby syntax highlighting.
|