Go Down

Topic: Dragino Yun Shield - Expand Disk Space with USB - Solution + Tutorial (Read 6093 times) previous topic - next topic

handyfreak

Hello,

i just managed to expand the Disk Space of the Dragino Yund Shield (which comes without SD-Card!), using a standart USB-Stick and a Arduino Mega 2560.

What i did:

1) Remove the jumper, to get the Arduino out of reset mode:

2) Include in the Sketch YunDiskExpander "#include <Console.h>"

3) Change the Setup:
Code: [Select]

  Bridge.begin();
  Console.begin();
  while (!Console);


4) Replace in the Sketch YunDiskExpander "Serial" with "Console", don´t change "Serial1"

OR

Copy my the Code of the next post:

5) Upload the Sketch using Arduino IDE, your Board connected via USB and selected as without shield (Exaple: Mega 2560 on Com 3)

6)Reconnect the jumper on the Arduino Board:



7) Connect Arduino to power source by DC Plug.

8.) In Arduino IDE select YunShield with WiFi connection (Example Yun SHield on 192.168.1.55)

9) Open Serial Monitor, make sure BaudRate in 115200 an NewLine selected.

10) IMPORTANT: The questions from Arduino as in the original tutorial wont be asked (Example "Do you wish to proceed")!

So follow the totorial blind
Original Tutorial

11) When ready wait min. 15 Seconds to avoid errors, then reconnect power source and wait to boot up.




12) enjoy you powerfull extendet Yun Shield!




 :smiley-cool: Have fun!  :smiley-cool:


handyfreak

Code: [Select]

/*
   Yún Shield Disk Space Expander
  
  Requirements:
  * Arduino Board
  * Dragino Yun Shield
  * USB Stick
  * internet connection

  This sketch configure the USB Stick to expand the disk space
  of the Yún Shield. Upload, open the Console Monitor and follow
  the interactive procedure.

  Warning: your USB Stick will be formatted and you will lose
  the files it contains. Be sure you have backed it up before
  using it for expanding Yún's Shield disk space.
 
  created Apr 2014
  by Federico Fissore & Federico Vanzati
  
 >> modded by HandyFreak Okt 2014 for DraginoYun Shield

  This code without any responsibility of damages or errors, successfully tested by me with Mega 2560.
  
*/

#include <Process.h>
#include <Console.h>   //Console class provide the interactive between IDE and Yun Shield

#define DEBUG 0
#define SUCCESSFUL_EXIT_CODE 0

void setup() {
  Bridge.begin();
  Console.begin();
  while (!Console);

  Console.print(F("This sketch will format your USB Stick and use it as additional disk space for your Arduino Yun.\nPlease ensure you have ONLY one USB-Stick plugged in: no other drives, hard drives or whatever.\nDo you wish to proceed (yes/no)?"));
  expectYesBeforeProceeding();

  Console.println(F("\nStarting Bridge..."));


  haltIfSDAlreadyOnOverlay();
  
  haltIfInternalFlashIsFull();

  haltIfSDCardIsNotPresent();

  installSoftware();

  partitionAndFormatSDCard();

  createArduinoFolder();

  copySystemFilesFromYunToSD();

  enableExtRoot();

  Console.print(F("\nWe are done! Yeah! Now reconnect to power to apply the changes."));
}

void loop() {
  // This turns the sketch into a YunSerialTerminal
  if (Console.available()) {
    char c = (char)Console.read();
    Serial1.write(c);
  }
  if (Serial1.available()) {
    char c = (char)Serial1.read();
    Console.write(c);
  }
}

void halt() {
  Console.flush();
  while (true);
}

void expectYesBeforeProceeding() {
  Console.flush();

  while (!Console.available());

  String answer = Console.readStringUntil('\n');

  Console.print(F(" "));
  Console.println(answer);
  if (answer != "yes") {
    Console.println(F("\nGoodbye"));
    halt();
  }
}

int readPartitionSize() {
  int partitionSize = 0;
  while (!partitionSize)
  {
    Console.print(F("Enter the size of the data partition in MB: "));
    while (Console.available() == 0);

    String answer = Console.readStringUntil('\n');
    partitionSize = answer.toInt();
    Console.println(partitionSize);
    if (!partitionSize)
      Console.println(F("Invalid input, retry"));
  }
  return partitionSize;
}

void debugProcess(Process p) {
  #if DEBUG == 1
  while (p.running());

  while (p.available() > 0) {
    char c = p.read();
    Console.print(c);
  }
  Console.flush();
  #endif
}

void haltIfSDAlreadyOnOverlay() {
  Process grep;

  grep.runShellCommand(F("mount | grep ^/dev/sda | grep 'on /overlay'"));
  String output = grep.readString();
  if (output != "") {
    Console.println(F("\nMicro SD card is already used as additional Arduino Yun disk space. Nothing to do."));
    halt();
  }
}

void haltIfSDCardIsNotPresent() {
  Process ls;
  int exitCode = ls.runShellCommand("ls /mnt/sda1");

  if (exitCode != 0) {
    Console.println(F("\nThe USB Stick is not available"));
    halt();
  }
}

void haltIfInternalFlashIsFull() {
  Process awk;

  awk.runShellCommand(F("df / | awk '/rootfs/ {print $4}'"));
  int output = awk.parseInt();
  if (output < 1000) {
    Console.println(F("\nYou don't have enough disk space to install the utility software. You need to free at least 1MB of Flash memory.\nRetry!"));
    halt();
  }
}

void installSoftware() {
  Console.print(F("\nReady to install utility software. Please ensure your Arduino Yun is connected to internet.\nReady to proceed (yes/no)?"));
  expectYesBeforeProceeding();

  Console.println(F("Updating software list..."));

  Process opkg;

  // update the packages list
  int exitCode = opkg.runShellCommand("opkg update");
  // if the exitCode of the process is OK the package has been installed correctly
  if (exitCode != SUCCESSFUL_EXIT_CODE) {
    Console.println(F("err. with opkg, check internet connection"));
    debugProcess(opkg);
    halt();
  }
  Console.println(F("Software list updated. Installing software (this will take a while)..."));

  // install the utility to format in EXT4
  exitCode = opkg.runShellCommand(F("opkg install e2fsprogs mkdosfs fdisk rsync"));
  if (exitCode != SUCCESSFUL_EXIT_CODE) {
    Console.println(F("err. installing e2fsprogs mkdosfs fdisk"));
    debugProcess(opkg);
    halt();
  }
  Console.println(F("e2fsprogs mkdosfs fdisk rsync installed"));
}

void partitionAndFormatSDCard() {
  Console.print(F("\nProceed with partitioning USB Stick (yes/no)?"));
  expectYesBeforeProceeding();

  unmount();

  Process format;

  //clears partition table
  format.runShellCommand("dd if=/dev/zero of=/dev/sda bs=4096 count=10");
  debugProcess(format);

  // create the first partition
  int dataPartitionSize = readPartitionSize();

  Console.println(F("Partitioning (this will take a while)..."));
  String firstPartition = "(echo n; echo p; echo 1; echo; echo +";
  firstPartition += dataPartitionSize;
  firstPartition += "M; echo w) | fdisk /dev/sda";
  format.runShellCommand(firstPartition);
  debugProcess(format);

  unmount();

  // create the second partition
  format.runShellCommand(F("(echo n; echo p; echo 2; echo; echo; echo w) | fdisk /dev/sda"));
  debugProcess(format);

  unmount();

  // specify first partition is FAT32
  format.runShellCommand(F("(echo t; echo 1; echo c; echo w) | fdisk /dev/sda"));

  unmount();

  delay(5000);

  unmount();

  // format the first partition to FAT32
  int exitCode = format.runShellCommand(F("mkfs.vfat /dev/sda1"));
  debugProcess(format);
  if (exitCode != SUCCESSFUL_EXIT_CODE) {
    Console.println(F("\nerr. formatting to FAT32"));
    halt();
  }
  delay(100);

  // format the second partition to Linux EXT4
  exitCode = format.runShellCommand(F("mkfs.ext4 /dev/sda2"));
  debugProcess(format);
  if (exitCode != SUCCESSFUL_EXIT_CODE) {
    Console.println(F("\nerr. formatting to EXT4"));
    halt();
  }

  Console.println(F("USB Stick correctly partitioned"));
}

void createArduinoFolder() {
  Console.print(F("\nCreating 'arduino' folder structure..."));
  Process folder;

  folder.runShellCommand(F("mkdir -p /mnt/sda1"));
  folder.runShellCommand(F("mount /dev/sda1 /mnt/sda1"));
  folder.runShellCommand(F("mkdir -p /mnt/sda1/arduino/www"));

  unmount();
}

void copySystemFilesFromYunToSD() {
  Console.print(F("\nCopying files from Arduino Yun flash to USB Stick..."));
  Process copy;

  copy.runShellCommand(F("mkdir -p /mnt/sda2"));
  copy.runShellCommand(F("mount /dev/sda2 /mnt/sda2"));
  copy.runShellCommand(F("rsync -a --exclude=/mnt/ --exclude=/www/sd /overlay/ /mnt/sda2/"));

  unmount();
}

void unmount() {
  Process format;
  format.runShellCommand(F("umount /dev/sda?"));
  debugProcess(format);
  format.runShellCommand(F("rm -rf /mnt/sda?"));
  debugProcess(format);
}

void enableExtRoot() {
  Console.print(F("\nEnabling USB Stick as additional disk space... "));

  Process fstab;

  fstab.runShellCommand(F("uci add fstab mount"));
  fstab.runShellCommand(F("uci set fstab.@mount[0].target=/overlay"));
  fstab.runShellCommand(F("uci set fstab.@mount[0].device=/dev/sda2"));
  fstab.runShellCommand(F("uci set fstab.@mount[0].fstype=ext4"));
  fstab.runShellCommand(F("uci set fstab.@mount[0].enabled=1"));
  fstab.runShellCommand(F("uci set fstab.@mount[0].enabled_fsck=0"));
  fstab.runShellCommand(F("uci set fstab.@mount[0].options=rw,sync,noatime,nodiratime"));
  fstab.runShellCommand(F("uci commit"));

  Console.println(F("enabled"));
}


JustGreg

I tried this with the Dragino Yun shield that I have.  It did not work correctly.  The partitions were created and the files copied.  However, upon the restart, the flash drive was not mounted.   It appears the flash drive (/dev/sda) was not detected and mounted.   I have the latest version of the Dragino OpenWrt.  I am using version Dragino-V2 common-1.3.5 of OpenWrt.   I suspect the problem is related to the version.

otrcomm

I just wanted to say, thank you very much  for this tutorial. I now have three Yun Shields running well with expanded memory.

I would like to share one issue that I ran into, not with the tutorial, but with SanDisk Cruzer Fit Flash Drives.

I got the memory expanded on first of my Yun Shields working great on a 16BG SanDisk Cruzer Fit. Then I started on the second Yun Shield and never could get the YunShieldDiskExpander sketch to recognize another 16GB SanDisk drive. The two disks were the same as far as I could tell, but I kept getting the error "The USB Stick is not available." What I eventually did was ssh into the Yun Shield and look at /etc/mcat to see how the SanDisk drive was mounted. I discovered that it was not mounted even though it was in the USB slot. So haltIfSDCardIsNotPresent() could not get a positive comeback on 'ls /mnt/sda1.'

I then mounted it in one of my debian boxes and discovered that it mounted as /dev/sde2. not /dev/sde1. What I eventually discovered was that there was some type of Novel file system installed on the sde1 partition. I had to dd zeros to the SanDisk drive to get rid of the Novel garbage and the first partition. Once I zeroed it, I could build a new partition and format it Fat32. Then it mounted properly on the YunShield and everything went smoothly for expanding memory.

The third Yun Shield and another 16GB SanDisk worked perfectly with no embedded Novel partition.

Just thought I would pass on my experience and solution.

sonnyyu


Isaac96

Do not PM me for help. I will delete immediately.
CONNECT THE GROUNDS!

After Tuesday, even the calendar goes W T F

Isaac96

And the Yun Shield has been released. Why not publish a tutorial to do the same with that?
Do not PM me for help. I will delete immediately.
CONNECT THE GROUNDS!

After Tuesday, even the calendar goes W T F

snapplepeach

I created an account specifically to say thank you, and that this worked for me.

I know who I'm nominating as a candidate for sainthood.

zeeHacker

I'm getting these errors (shown below) after running the code provided by handyfreak. I saved the file inside Documents/Arduino/libraries before attempting to upload. Also using Mega 2560 and Yun Shield. Can someone please help me...

Arduino: 1.6.5 (Windows 8.1), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

avr-gcc: error: C:\Users\Nyasha\AppData\Local\Temp\build2142350526624292970.tmp/core.a: No such file or directory
Error compiling.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

zeeHacker

I'm getting these errors (shown below) after running the code provided by handyfreak. I saved the file inside Documents/Arduino/libraries before attempting to upload. Also using Mega 2560 and Yun Shield. Can someone please help me...

Arduino: 1.6.5 (Windows 8.1), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

avr-gcc: error: C:\Users\Nyasha\AppData\Local\Temp\build2142350526624292970.tmp/core.a: No such file or directory
Error compiling.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

So I finally managed to fix that issue... what I did was, I navigated to the Temp directory and found out that the .tmp file was not there. Was running IDE 1.6.5 so I uninstalled it and installed the latest 1.6.8. After that I tried uploading again and what do u know...it worked!

But... After upgrading to the latest OpenWRT firmware using instructions from the link below, I found out that my memory had shrank back to the original hardware size. After redoing the steps again I get interesting messages from the serial monitor (says unable to connect blah blah blah). See image attachment below. Please help.
http://twilioinc.wpengine.com/2015/02/arduino-wifi-getting-started-arduino-yun.html

zeeHacker

Expand the storage by USB flash drive and hard drive for Dragino:

http://forum.arduino.cc/index.php?topic=321502.msg2227962#msg2227962




Aha!!..Found my solution here, thank you sonnyyu...if you did those scripts yourself then u'r my hero man! Awesome stuff.

AgroMeInc

Hi @handyfreak thanks A LOT for this post !

It worked perfectly for me, although I hacked the original sketch my way. I also bricked an UNO by sccidentally loading a YUN bootlader into it but I think I can recover it later by flashing the correct one ;-)

Anyway thanks again for taking the time to publish this.

Thanks to your post I was able to do this: http://www.perlmonks.org/?node=Embedded%20Perl%3A%20Installing%20Perl%20and%20Mojolicious%20on%20Arduino%20Y%FAn%20%2F%20OpenWRT%20ChaosCalmer

--
Alex

Go Up