Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@wayoda
Last active April 26, 2023 18:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wayoda/db3c023417757f726088 to your computer and use it in GitHub Desktop.
Save wayoda/db3c023417757f726088 to your computer and use it in GitHub Desktop.
Implementing an Arduino Yun boot-status monitor using the handshake signal between the MIPS 24k CPU and the ATMega

Monitoring the handshake signal on an Arduino Yun

There are two independent processors on the Yun which communicate over a dedicated serial connection. The Bridge library from the Arduino developers makes is possible to initate commands on the Linux machine from the code that runs on the ATMega32U4 processor. That is the canonical way of communinication of the internal parts on the Yun.

Another option would be to detach the serial port (Serial1) from the console and use self written code for talking between the Linuxmachine and the ATmega32.

Detaching the serial port from the console is easy, you just need to a comment out a line in file /etc/inittab :

::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
#We do not start a login shell on the console, because we want to talk to the 
#ATMega through some custom code. So the next line needs to be commented out
#ttyATH0::askfirst:/bin/ash --login

The problem is, it takes effect only after the Linux machine has gone through almost the whole boot process. When you startup the Yun all the Linux boot messages will appear on the Serial port of the ATMega32 and you can't be quite sure when exactly the Linux boot process has finished. So its hard to say when the serial port is ready to be used for your own purposes. The same is true when you shut down or reboot the Linux machine. You won't notice that condition from the ATMega so your code might hang because you wait for some answer from the Linux side which never comes.

This little gist shows how to make use of a GPIO on the Yun to create a kind of boot-monitor for the Arduino processor.

The Handshake Hardware

The Arduino developers connected one of the GPIO's on the MIPS chip to Pin7 on the ATMega processor. What we have to do is to toggle this GPIO whenever the Linux OS has finished booting or just before it goes into a reboot sequence.

The Arduino Sketch could either install a pin change interrupt or permanantly poll Pin 7 so it knows when to startup or stop communication wit the Linux machine.

The AR9331 processor that runs the linux machine provides a few GPIO pins to connect external hardware. Two of these GPIO's are relevant to the handshakesignal.

  • GPIO22 activates a NXP NTB0104 which is used for bidirectional voltage level translation. When GPIO22 is off (standard setting on the Yun) the IO-Pins of the NTB0104 are disabled.
  • GPIO19 is the signal routed from the AR9331 through the NTB0104 to Pin 7 of the ATmega32U

In order to use the handshake signal we need to install an Init Script that toggles the GPIO pins. The basics of Init Scripts on OpenWRT based Linux distributions are explained here: http://wiki.openwrt.org/doc/techref/initscripts . Please read this short article to understand what is being done here.

Have a look at file boot-status we enable the startup part of the script at the latest possible moment in the boot process to be sure that the console is already detached from the serial port when we set the Handshake GPIO pin.

On shutdown we will reset the pin as early as possible so the ATMega knows the Linux machine is going away.

####Pull-Down Resistor The chip that is used for the voltage level translation on the Handshake GPIO has a feature that enables it to automaticly detect if a given pin is an input our output signal. But that seems not to work reliably on the handshake line. Without the pull-down resistor I could perceive a short delay on the handshake signal. The pull-down resistor that runs from Pin 7 on the Arduino to the (Arduino) GND. The NTB0104 Datasheet says to use a minimum value of 50k. I used a 100k resistor and it works fine.

WARNING_On Do not add a Led directly to pin 7 of the Arduino. The NTB0104 does not provide enough power to drive an Led directly. WARNING_Off

####Install the script Copy the file boot-status to the Yun directory for init scripts

scp boot-status root@[NameOfYourYun].local:/etc/init.d

Log into your Yuns commandline and make the file executable

chmod a+x /ect/init.d/boot-status 

Install the script

/etc/init.d/boot-status enable

Upload the little Arduino examle Sketch to your Yun, and test the script from the shell running /etc/init.d/boot-status start to light up the Led on the Yun and /etc/init.d/boot-status stop to turn it off.

If that works, you are ready to reboot the Yun from the commandline in order to see if it works from inside the boot process.

#!/bin/sh /etc/rc.common
# (C) 2008 openwrt.org
START=99
STOP=01
start() {
[ -e /sys/class/gpio/ ] && {
echo "Arduino Handshake On"
echo "19" > /sys/class/gpio/export
echo "high" > /sys/class/gpio/gpio19/direction
echo "1" > /sys/class/gpio/gpio22/value
echo "1" > /sys/class/gpio/gpio19/value
}
}
stop() {
[ -e /sys/class/gpio/ ] && {
echo "Arduino Handshake Off"
echo "0" > /sys/class/gpio/gpio19/value
echo "19" > /sys/class/gpio/unexport
echo "0" > /sys/class/gpio/gpio22/value
}
}
::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
#We do not start a login shell on the console, because we want to talk to the
#ATMega through some custom code. So the next line needs to be commented out
#ttyATH0::askfirst:/bin/ash --login
// We want to light up the Led on Pin 13 when the Linux-machine
// is up and running.
int led = 13;
// This is the pin where the handshake signal from the
// Linux processor is connected
int handshake = 7;
// We install a interrupt on the handshake pin so
// the interrupt flag and the status of the handshake
// signal must be volatile
volatile int stateChange=0;
volatile int state=0;
void setup() {
pinMode(led, OUTPUT);
pinMode(handshake,INPUT);
//read current status of the handshake signal
state=digitalRead(handshake);
//switch the Led on/off depending on the current state
digitalWrite(led, state);
//now activate an interrupt routine that monitors the handshake signal
attachInterrupt(4,bootStatusChange,CHANGE);
}
// the loop routine runs over and over again forever:
void loop() {
if (stateChange) {
//The handshake signal changed
stateChange=0;
digitalWrite(led, state);
}
// Now Do whatever your sketch is supposed to do ...
}
void bootStatusChange() {
// We are called because the handshake signal has changed
stateChange=1;
state=digitalRead(handshake);
}
@maujabur
Copy link

Hi!

I've been trying to access the handshake GPIO19 but it keeps failing. Are you aware of any changes on Linino that prevent exporting this GPIO?

Thanks!

@Workshopshed
Copy link

Would I be correct in thinking that your script "boot-handshake" is the one you are calling "boot-status" in the readme?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment