Has anybody tried to do a Model 01 emulation/simulation yet? This might be useful not only for debugging but also for automatic testing.
Proposal: Enable unit testing Kaleidoscopes core and client plugins by Dependency Inversion
Why use properties instead of setters/getters?
If I remember correctly, @craigdissel was working on a virtual hardware plugin that would allow automatic testing on the host system, without the need of a simulator.
Looking at the Hardware-Virtual plugin, at first glance it seems that the sketch runs on x86. As x86 is not binary compatible to avr (atmega32u4), this makes debugging some errors impossible that are e.g. related to false memory layout assumptions. In such cases a true avr simulation is the only way to go.
Yes, that’s my Hardware-Virtual plugin. You’re correct that it allows x86 debugging-oriented builds of Kaleidoscope. For my own purposes I’ve found it useful for debugging, in that I can e.g. add printf statements to the code (and have them show in the terminal), log things to file, or even use gdb on a Kaleidoscope firmware. However, it’s certainly a known limitation that Hardware-Virtual bypasses most of the lower layers of the Arduino stack, so while it works great for high-level debugging of Kaleidoscope sketches, plugins, and core, it’s not suited to more detailed debugging of device-specific things, or changes to lower layers of the software stack. If you’re looking at low-level details like memory layout, there are a ton of differences between a Hardware-Virtual build and a true avr simulation, starting with the fact that we compile with “standard” gcc instead of avr-gcc and use the “standard” libc instead of the AVR one.
If there’s some specific feature(s) that could be added to Hardware-Virtual that would make it more useful, I’m open to suggestions - here, or as feature-request issues on the GitHub, or even as PRs (!). I have a few ideas for enhancements myself that I haven’t gotten around to. However, I have no plans to integrate with a “real” avr simulator - if you are interested in that, by all means go for it.
Thank you @craigdissel for your explanations. The Hardware-Virtual plugin really sounds like a great tool for most debugging work.
The reason why I am myself so keen on having a “real” simulation is that I had problems in the past with some software that I could run on both avr and x86, with some specific types of errors simply not showing in the x86 builds. Therefore, I would really love to have a tool that I could integrate in my travis-testing toolchains and that is 100% reliable in a sense that the program behaves exactly the same as it would on the actual hardware.
I had good experience with simavr, although not with complex inputs, i.e. not a complete firmware but only extracted parts of it. The printf part is also easy to do using hid_listen. Not sure if hid_listen is applicable with arduino also. simavr has a gdb interface that works via remote debugging.
Edit: It was a bit late when I wrote this. Hid_listen is actually used together with real hardware. For printf output from simavr this is not required. Simavr just passes printf output to stdout.
I really like the idea of of the Hardware-Virtual plugin, a tool that can be passed sequences of keystrokes to check what USB-output is produced.
Of course, with a tool like simutron, which is acutaly a simavr wrapper, this would mean to model the whole hardware, not only the CPU to get the Input/Output behaviour right. Even though I am currently mainly interested on the keyboard report, for other purposes it would also be nice to log the activation state of the LEDs. Not sure, however, if this is possible with simutron and unfortunately I am not too much of a hardware guy either. I imagine timing to be an issue if it comes to correctness of simulation results.
Maybe @jesse can comment on the feasibilty of modelling the Model 01 with simutron.
I spent 3-4 days trying to get something to work with simavr. The problems I ran into mostly revolved around not ever being able to get a build of an AVR simulator or emulator that could emulate the 32U4. There are some suggestions out there that at one point there was even a linux ‘virtual’ USB controller, so that such an emulator could appear as a USB device.
If you can get me a recipe to run a 32u4 simulator or emulator with the USB bits intact, I’d be thrilled to work with you to get further.
I’ve never played with simutron. (Or even heard of it.)
We wouldn’t necessarily need to model the atmega and both of the attinies it talks to over i2c to make this very, very useful.
At some point in the near future, I’d really like us to start to get at least some basic regression testing up and running using @craigdissel’s work.
Why use properties instead of setters/getters?
I did some research about what is currently possible. Seems there did not happen much since @jesse tried what he described in his post.
Anyway, those of you interested, find below a summary of what I found when searching for simavr, usb, etc. Maybe there’s someone with ideas how to get an emulation including USB communication done.
USB Virtual Host Controller Interface
There is a USB Virtual Host Controller Interface project (vhci). That’s probably what @jesse refered to. The host controller allows connecting virtual USB hardware, e.g. an emulator such as simavr to the Linux system as virtual USB device. Once connected a virtual USB device is handled as if it was real hardware. I was able to build and install vhci on Ubuntu 16.04 LTS
(Important: I had to export the environment variable ARCH=x86 for the build to work). Unfortunately, I did not succeed running the tests/examples that came with vhci.
simavr generally allows to run firmware for atmega32u4 build with avr-gcc. It comes with an example that models USB loopback communication with an at90usb162. The example relies on vhci. Unfortunately, the example is somewhat broken as it uses an old patched version of vhci that is included in the simavr repo. The old version seems not to work with modern kernels.
I was not able to modify the simavr example’s build system in a way that would enable me to compile it based on a separately build up-to-date vhci.
Also I am not sure if this example helps us with respect to usb-hid communication, anyway.
That’s what I ran into, yes.
Now, if you could get the 32U4 simulator to send output over a virtual serial port, we could add a second hardware definition which used the serial port instead of the HID output. Then we’d at least be testing a build intended for an AVR.
I am not too familiar with the USB protocol in general. That’s why I am currently not able to understand it the simavr example’s firmware part is of any help to us. It seems to model a general USB communication.
The keyboard hid-protocol on the other hand seems pretty straight forward. My next step will thus be to put the simavr example’s firmware aside and try a rudimentary Arduino sketch that goes without most of Kaleidoscope and just sends simple keyboard reports to the host in a loop. I will of course have to consider the modifications of the host-side parts of the simavr example that establishes the connection with vhci.
When trying to run QMK firmware sketches in other occasions, I experienced the firmware to hang already during start-up. This was probably because the code was spinning on some hardware condition, e.g.waiting for an input to change its state, something that would never happen because the particular hardware was not part of the simulation. Thus I was not able to simulate the firmware as a whole and had to extract the parts I was working on. I finally ran them a sort of test driver environment, which worked well but did not enable me to test the overall firmware.
What I want is to model the complete IO behavior from my virtual fingers pressing keys to the USB report on the host.
To speedup things, could somebody help me with an Arduino sketch by telling me what can be omitted and what not with respect to a Kaleidoscope firmware sketch? All this in a way that the firmware does not try to communicate with any hardware that is not there, e.g. the attinies.
@jesse, I did not quite understand, what you meant with the second serial port? Do you intent to use it to pass input data from the host to the simulated keyboard? Because that is something I am still pondering about. How to get a sequence of keystrokes, ideally with a defined timing, to the simavr-keyboard?
Of course one could hard code a sequence of keystrokes in the firmware and let a loop hook modify the keyboard matrix. But it would be much more versatile to have some sort of monolithic keyboard simulator that reads keystroke-data from a file and passes them to the simulated keyboard. The simulator’s output would preferably be the keyboard reports. Just like it’s done by the Hardware-Virtual approach. Such a tool would nicely integrate with a travis test bench.