This blog is not a “real blog”: I just wanted to publish the results of my work somewhere on the internet. I have been using everything I could find from nice people who published their work online. Having reached my goal, it is time for me to give back a bit of what I got, and hopefully, bring something new to the [Arduino] community.
My english is far from being perfect. Please feel free to correct my sentences, words or typo so that this very single article/post will be easily readable by any english-reading person.
This article is about building an inter MCU/PIC/microcontroller mutex/lock, allowing to have several disctinct cores (of any kind) working together and using a single resource without conflict.
Right now, the board and schematics that are described in this post can handle up to 4 MCU cores (of any kind), letting them to access/use a single resource without conflict. The principle could be easily extended to handle more cores or more resources. For my own prototypes, I use several PIClock boards when the AVRs have to access several resources.
Ok, but why or when should we use such a mutex board ?
Let’s say you want to access a single SD card or a single EEPROM from several MCU. You will want to have atomic IO operations so that your data will always be correcty organized and correctly interpreted when read by MCUs. You would’nt want to have a MCU reading data in the middle of another MCU writing operation, isn’t it ?
Let’s say you want 2 MCUs to read the temperature from a single K thermocouple. You would’nt want to activate the reading operation at the same time on both cores.
Imagine you built sentries for lazy hunters. The hunter install the sentries at the 4 corners of a field and boot them so that sentries wait for a poor rabbit to enter their sensor field. If all of them discover a rabbit at the same time and decide to shoot it, the rabbit won’t look good in the guests’ plates. Using a mutex between sentries will make every sentry to “ask for shooting”, get (or not) the permission to proceed, and shoot when allowed. (NOTE: that’s the cynical example I used to explain the whole stuff to my daughters ;)).
To sum up the goal of the circuit: it lets a particular MCU (within a group of MCUs) request the (temporary) ownership of a resource, hold it while doing stuff, and release it when finished. During the time the given MCU owns the resource, no other MCU will become owner of the resource (which don’t mean they can’t ask for ownership!). As soon as the owner release the ownership, another one can become the temporary owner. It’s a mutex (mutual exclusion).
You crazy guy! Why damned did you work on that subject ?
I had never practice electronics before. Experts will confirm this point when looking at my stuff (schematics, etc.) 😉 I am a “pure” software developper. I played with Arduino, building a framework (a very tiny OS) to handle display, sensors, IO, config and EEPROM, multiplexers, etc. As soon as I benchmarked my stuff , I noticed that the Arduino’s ATMega328 can’t do much. When interacting with the user through a fancy interface and a joystick, it can’t poll sensors with a stable frequency anymore: strings, IO and “fancy formatting” are expensive operations on such a CPU. I could rewrite the code for every project but it would be a pain in the ass. The easiest is to assemble sets of AVR, use specific schemes on each one, and have them discuss and synchronize through busses. Having more than one AVRs costs few dollars per chip and some more place to solder them.
Then I thought I really needed some kind of mutex for AVRs.
I decided to get a result that would “look like” professional stuff. I wanted a PCB with female and male headers, a DC regulator, some LEDs (Arduino compliancy), my name written on it, and some fancy writing making usage easier. I decided to use only “through hole” componants because I didn’t wan’t to dig into the baker skills at this moment. SMT components would offer smaller consumption, smaller board surface, probably better (and faster ?) performances (in term of mutex’ed resources ?).
What I did:
- Read at loooot of datasheets,
- Made some schematics on paper and simulated it with CEDAR Logic Simulator (PIClock CEDAR simulation file given at the bottom).
- Bought components (RS, BatchPCB, Sparkfun, Ada industries, Seeed studio, all are perfect companies when buying from France) and breadboard’ed that stuff,
- Found a bug in my shift register implementation (real chip “command” pins do not exactly match pins meaning in CEDAR),
- Discovered the fanstatic Open Bench Logic Sniffer and made the breadboard work properly thanks to it,
- Wrote a small library (for Arduino) so that my schemes could use the hardware mutex,
- Draw schematics and board with Eagle CAD,
- Order boards from BatchPCB,
- Soldered and prayed,
- Wired my cores to the populated PCB, using solderless cables and breadboard,
- Powered on,
How does it work ?
Basically, it is an all 0/1 circuit (logic gates). AVRs ask for the mutex with a HIGH request pin. They get the ownership through a HIGH answer pin. A shift register handles a very single round robin 1 valued bit – the token – and introduce it to every request pin (powered by a 6MHz TTL clock). When a request pin is HIGH, AND(request pin, token) is true, logic gates stop the wandering token (by saying to the shift register to stop shifting). Input timing is stabilized using D Latches (is that really useful) ? When the owner of the token releases its request pin, wandering token (1) goes on its road again, catchable by another AVR.
The shift register has the following values (on its parallel output):
- bit is magictronically teletransported from left to right
The token is re-injected into the shift register’s right (input bit) using the “output bit pin” copied on the inut bit (left to right). Primary value (0001) is loaded when shift register reloads (its parallel input value) by connecting the parallel load pins to ground (3x 0) or +5V (1x 1).
The circuit has a 7805 regulator and can be connected to +5V arduino’s pin when bypassing the regulator. I am not sure that the circuit is properly designed for that part: no diode between the +5V and the 7805.
- 4 pairs of (request, answer) pins, one pair per AVR,
- 4 “mutex is owned” pins (so that AVR’s can know that another AVR owns the mutex),
- 1 reset pin (making the shift register to load 0000 and flag the board as “locked”/”owned”. When releasing the reset pin, (5V -> ground), 0001 is reloaded and token walks again through request pins.
- 5 “jumpers” pins (dual row headers) to “hard connect” request pins to ground (forcing a 0 – no request) on unused/unconnected requests pins. For example, this is used when having 3 cores (and not 4) or when not using/connecting reset pin. Request pins are protected from being directly connected to ground (when putting a request pin to 1 and having the corresponding jumper pin closed) using 1K resistors).
- 1 DIN/JACK connector (~6-7V, 2.1mm connector),
- PCB populated with the components I had on my desk. 1K resistors for LEDs are an example of point.
And next ?
I am absolutely not a rabbit hunter, but I am a lazy writer. I publish this stuff to share it. I am tired of writing and I beleive I published every important information (including following files). You can ask questions in comments and I’ll try to answer to you. Feel free to help people by yourself (if you understand or use PIClock), improve the whole stuff, reuse, etc. This project is published under the Creative Commons Attribution Share-Alike license.
- about 65mA when powered,
- 0.1V on anwer pins when 0 (no ownership), 3.5V when 1 (ownership),
- Ada industries, Sparkfun, Seeedstudio, RS, Jameco, the whole community (forums, blogs, etc.), Google reader, etc. Using all those internet ingredients, I managed to have this stuff working and I am quite proud of it.
- 12x 1K resistors (LED resistors should be recalculated ;))
- 2x 8 pins female headers
- 1x dual row 5 male pins header
- 7x leds (power, locked/unlocked, 4 channels/avr)
- 1x TOYOCOM 711S4 6Mhz TTL clock
- 1x 7805C regulator
- 1x JACK connector 2,1mm
- 2x SN74LS74AN
- 3x SN74LS132N
- 1x SN74LS194AN
- 2x SN74LS32N
- 1x SN74LS08n
- All that stuff could be implemented easily on a single and cheapiest ATMega328,
- Design is not perfect but it does the job,
- Critics are welcome.
- Save the files (hosted on dl.free.fr) on any stable server and give the links in the comments. When the files will be disappeared, look into the comments for new links 😉
Files, pics, etc.
Arduino PIClock library (including a PDE example sketch)
Youtube video (boring) of the breadboard just debugged
Youtube video: 3 ATMega328 knocking on a PIClock PCB