The Learning of Rust
During the last months I was rather busy with another project. On 21.08.2022
I've decided to finally start learning Rust, as I wanted to learn more about
the powers it possesses. As a professional C++ developer I've noticed certain
flaws of the way C handles concurrency. It doesn't matter if it is a Linux
daemon with threads or an embedded project with interrupts. Concurrency can
lead to stochastic bugs difficult to pin down. Rust doesn't have this issue as
the compiler itself makes use of formal verification to ensure that no data
structures are shared globally without mutual exclusive protection.
tl;dr Rust is very safe.
I
wanted to learn that language and needed a project to do so.
The Project
My
SlamySTM32Floppy
project was now finished for a long time. But I wasn't happy anymore with
its state. The code is messy and copy protected images were never fully
verified after being written. Also new projects have entered the game by
now. There is the
Greaseweazle and also
the KryoFlux. If it wasn't for my
desire to cleanup my old project and my love for old technology I would have
just bought a Greaseweazle. It is open source and prebuilt hardware is not
very expensive.
As I had the old hardware lying around I decided to just go with it and
start the firmware and the host tools from scratch. Also my solution never
had any housing. A fine remainder:
This was the state during 2016 and it was still like this in my closet by
now. That was about to change.
The goal
-
Yet another USB floppy flux thing project because there wasn't one
before. lol.
-
Writing of copy protected images as correct as possible
-
Make use of write precompensation this time
-
Verification of all written data to the level of a single flux
reversal
-
Writing of images as fast as possible. No rotation of the disk shall be
wasted.
-
Have some integration tests to check for regressions during
development
-
Adding features can break previous accomplishments easily
-
Have a proper documentation about its usage
-
Utilize DMA this time for better performance
-
USB communication is not stalled during flux operations
A different approach to write flux data
The way the Greaseweazle approaches its task is vastly superior to my old technique.
The SlamySTM32Floppy used code in its firmware for very specific tasks. GCR
and MFM are handled by different functions. DMA was not used to write and
collect pulses. Verification of written data was performed by parsing known
track formats. There was a verify function for Amiga sectors and for ISO
sectors. The code is
open source and can be used to learn from my old mistakes.
The Greaseweazle on the other hand has a very basic firmware with only one task
to solve: The correct writing of raw fluxes and reading of those. This keeps
the firmware simple as all intelligence is on the host side. This however
means that more data needs to be transferred between STM32 and PC. But I've
decided to go with this approach as well as it seems to be very
flexible.
A different approach to verify written flux data
However I was not happy with the way, the Greaseweazle verifies the written tracks. A whole track is read back to the
PC and then cross correlation is performed to check the equality of any
possible flux stream. I like this idea but I wanted to do the verification
on the firmware itself. My goal here is different. As before, this project
is targeted to be optimized for writing speed, so this simply won't do.
Instead I needed an algorithm for cross correlation which is performed on
the device while the just written track is read back from disk.
The idea of the Greaseweazle with cross correlation was good, but it needed
to be scaled down. By the time of writing I went with reading the first 200
flux pulses after the index signal and cross correlating them against the
first 20 pulses of the groundtruth data. As soon as both match up both flux
streams are considered in sync and are compared until no groundtruth data is
left to compare against.
200 flux pulses might sound like a lot, but it had to be as this floppy
writer is capable of working without the index pulse to support flipped
5.25" disks. The larger amount of data allows more room for fluctuation in
the rotation of the disk.
Usage of write precompensation
Early on, I've never thought about write precompensation but it really
improves the quality of the written data. For more information, I've written
a
markdown file about this topic in the github repo. This must be performed for every drive and can be essential for games
like the Amiga version of Turrican II.
A smaller board
Originally this project was started using the
STM32F4DISCOVERY. This eval board still performs well today but it's size makes it
difficult to fit into a case. I've decided use a smaller one this time: A
board without microphone, a headphone amplifier, an acceleration sensor and
an integrated stlink.
The
Diymore STM32F4
seemed to be the right choice. It is exactly the same microcontroller - the
STM32F407 - but reduced to the essentials. All this project needs, is I/O
and a USB port.
In the end, I've wasted space nonetheless as the
used perfboard could've been smaller.
But still look for yourself:
|
A much smaller board with only the relevant components
|
A case made from wood to properly store the electronics
This time I wanted to have a small case to store everything. It is much
easier for transportation that way and the especially naked 5.25" drive is
protected.
At first I thought about 3D printing (thx to Chris for support) but
wasn't satisfied with the result. It seems that 3D printed models are
difficult to rework in case the designed 3D model was not thoughtfully
planned to the end. (Yes, cables take up space. Especially thick cables
like the one used for floppy drives...)
So I've decided to go for wood instead. It makes reproduction for others
more difficult but in the end it would be possible to make a 3D model from
it as soon as I was satisfied with how the case was built. A wooden model
can be reworked very easily.
|
Early state of the case viewed from the top. Some rails added for the
drives to sit on
|
|
Viewed from the front
|
|
And the back.
|
|
Small piece of wood to keep the PicoPSU in place
|
|
Connected the PicoPSU to the small piece of wood
|
|
The case and the top piece
|
|
The whole case fitted together. A view inside.
|
|
A 3.5" drive and the Diymore board
|
|
The PicoPSU added
|
|
The floppy cable added.
|
|
The finished product.
|
The Result
The project goal was achieved. I did learn a lot about the Rust programming
language through practical usage and learning from problems during
development. I've learned about development of linux system software as well
as embedded development using that language.
In the end, the resulting device is very similar to the old
SlamySTM32Floppy but surely more advanced. Especially the verification of
every written track, even copy protected ones, makes the resulting disk more
trustworthy.
The knowledge about more sophisticated things like write precompensation
was also expanded.
This project is open source from the start and can be inspected on
github.
I've also decided to maintain a list of correctly written images so compatibility is properly documented.