Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Arduino:Примеры/ExpandingYúndiskspace

Материал из Онлайн справочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Как расширить дисковое пространство на Yun[1]

Операционная система OpenWrt-Yun на базе GNU/Linux, будучи установленной на Yun, занимает примерно 9 из 16 мегабайт доступной Flash-памяти. Это значит, что если вы установите слишком много приложений и программных пакетов, места вам будет категорически не хватать.

Впрочем, дисковое пространство на Arduino Yun можно увеличить, подключив к плате SD-карту и настроив ее таким образом, чтобы она стала вашей новой Linux’овой файловой системой. После этого все, что вы будете делать на Linux-стороне Yun , будет храниться на этой SD-карте.

Процедура настройки не сложна, но все же требует базовых знаний в области Linux. Поэтому мы автоматизировали все шаги и сделали соответствующий скетч, использующий библиотеку Bridge. Так что просто вставьте карту и следуйте интерактивным инструкциям в Serial Monitor.

Скетч разделит SD-карту на две части. Первая будет отформатирована под FAT32 и с ней можно будет работать с любого компьютера, т.е. ею можно будет пользоваться для того, чтобы обмениваться файлами между компьютером и Yun. Вторая часть будет содержать файловую систему Yun. Любая установленная вами программа и любой конфигурационный файл будет скопирован на SD-карту, поэтому вам не придется ничего переустанавливать и перенастраивать – Yun останется такой же, как прежде, просто дискового пространства у нее будет побольше. Впрочем, имейте в виду, что если вы используете Windows или Mac, то вторая часть для вашего компьютера будет недоступна.

Подготовка

Подключите вашу Yun к компьютеру и подождите около минуты. Убедитесь, что Yun подключена к интернету, потому что процедура потребует дополнительного ПО. Отключите от Yun все девайсы, а затем вставьте SD-карту.

Внимание! Ваша SD-карта будет отформатирована, поэтому вы потеряете все записанные на нее данные. Поэтому перед тем, как расширять дисковое пространство на Yun, убедитесь, что вся необходимая информация скопирована в другое, более безопасное место.

Загрузите ZIP-файл, содержащий скетч, распакуйте его и скопируйте содержимое в папку скетчей для Arduino. Откройте среду разработки Arduino и загрузите скетч YunDiskSpaceExpander.

Вот ссылка на ZIP-файл.

  1. /*
  2.  
  3. Расширение дискового пространства на Yun
  4.  
  5. Требуются:
  6. * Карта формата micro SD
  7. * Подсоединение к интернету
  8.  
  9. Этот скетч конфигурирует SD-карту, чтобы расширить дисковое пространство Arduino Yun.
  10. Загрузите его, откройте Serial Monitor и следуйте интерактивным инструкциям.
  11.  
  12. Внимание! Ваша SD-карта будет отформатирована, поэтому вы потеряете все имеющиеся на ней файлы.
  13. Поэтому, перед тем, как расширять дисковое пространство на Yun,
  14. сделайте бэкап этих файлов.
  15.  
  16. Создан в апреле 2014
  17. Федерико Фиссоре (Federico Fissore) и Федерико Ванзати (Federico Vanzati).
  18.  
  19. Этот код не защищен авторским правом.
  20.  
  21. http://arduino.cc/en/Tutorial/ExtendingYunDiskSpace
  22.  
  23. */
  24.  
  25. #include <Process.h>
  26.  
  27. #define DEBUG 0
  28. #define SUCCESSFUL_EXIT_CODE 0
  29.  
  30. void setup() {
  31.   Serial.begin(115200);
  32.   while (!Serial);
  33.  
  34.   Serial.print(F("This sketch will format your micro SD card and use it as additional disk space for your Arduino Yun.\nPlease ensure you have ONLY your micro SD card plugged in: no pen drives, hard drives or whatever.\nDo you wish to proceed (yes/no)?"));  //  "Этот скетч отформатирует вашу SD-карту и воспользуется ею, как дополнительным дисковым пространством для Yun.\nПожалуйста, убедитесь, что в Yun вставлена только SD-карта и ничего более – ни флэшек, ни жестких дисков, ни т.п."
  35.   expectYesBeforeProceeding();
  36.  
  37.   Serial.println(F("\nStarting Bridge..."));  //  "Запускаем Bridge..."
  38.  
  39.   Bridge.begin();
  40.  
  41.   haltIfSDAlreadyOnOverlay();
  42.  
  43.   haltIfInternalFlashIsFull();
  44.  
  45.   haltIfSDCardIsNotPresent();
  46.  
  47.   installSoftware();
  48.  
  49.   partitionAndFormatSDCard();
  50.  
  51.   createArduinoFolder();
  52.  
  53.   copySystemFilesFromYunToSD();
  54.  
  55.   enableExtRoot();
  56.  
  57.   Serial.print(F("\nWe are done! Yeah! Now press the YUN RST button to apply the changes."));  //  "Готово! Отлично! Теперь нажмите на кнопку YUN RST, чтобы изменения вступили в силу."
  58. }
  59.  
  60. void loop() {
  61.   // Это превратит скетч в пример «Доступ к терминалу Linux через Serial Monitor»
  62.   if (Serial.available()) {
  63.     char c = (char)Serial.read();
  64.     Serial1.write(c);
  65.   }
  66.   if (Serial1.available()) {
  67.     char c = (char)Serial1.read();
  68.     Serial.write(c);
  69.   }
  70. }
  71.  
  72. void halt() {
  73.   Serial.flush();
  74.   while (true);
  75. }
  76.  
  77. void expectYesBeforeProceeding() {
  78.   Serial.flush();
  79.  
  80.   while (!Serial.available());
  81.  
  82.   String answer = Serial.readStringUntil('\n');
  83.  
  84.   Serial.print(F(" "));
  85.   Serial.println(answer);
  86.   if (answer != "yes") {
  87.     Serial.println(F("\nGoodbye"));  //  "Пока!"
  88.     halt();
  89.   }
  90. }
  91.  
  92. int readPartitionSize() {
  93.   int partitionSize = 0;
  94.   while (!partitionSize)
  95.   {
  96.     Serial.print(F("Enter the size of the data partition in MB: "));  //  "Введите размер для разбиения дискового пространства (в мегабайтах): "
  97.     while (Serial.available() == 0);
  98.  
  99.     String answer = Serial.readStringUntil('\n');
  100.     partitionSize = answer.toInt();
  101.     Serial.println(partitionSize);
  102.     if (!partitionSize)
  103.       Serial.println(F("Invalid input, retry"));  //  "Неправильно, введите снова"
  104.   }
  105.   return partitionSize;
  106. }
  107.  
  108. void debugProcess(Process p) {
  109.   #if DEBUG == 1
  110.   while (p.running());
  111.  
  112.   while (p.available() > 0) {
  113.     char c = p.read();
  114.     Serial.print(c);
  115.   }
  116.   Serial.flush();
  117.   #endif
  118. }
  119.  
  120. void haltIfSDAlreadyOnOverlay() {
  121.   Process grep;
  122.  
  123.   grep.runShellCommand(F("mount | grep ^/dev/sda | grep 'on /overlay'"));
  124.   String output = grep.readString();
  125.   if (output != "") {
  126.     Serial.println(F("\nMicro SD card is already used as additional Arduino Yun disk space. Nothing to do."));  //  "\nSD-карта уже используется в качестве дополнительного дискового пространства для Yun."
  127.     halt();
  128.   }
  129. }
  130.  
  131. void haltIfSDCardIsNotPresent() {
  132.   Process ls;
  133.   int exitCode = ls.runShellCommand("ls /mnt/sda1");
  134.  
  135.   if (exitCode != 0) {
  136.     Serial.println(F("\nThe micro SD card is not available"));  //  "\nSD-карта недоступна"
  137.     halt();
  138.   }
  139. }
  140.  
  141. void haltIfInternalFlashIsFull() {
  142.   Process awk;
  143.  
  144.   awk.runShellCommand(F("df / | awk '/rootfs/ {print $4}'"));
  145.   int output = awk.parseInt();
  146.   if (output < 1000) {
  147.     Serial.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!"));  //  "У вас недостаточно дискового пространства для установки утилиты. Нужно освободить как минимум один мегабайт Flash-памяти.\nПопробуйте еще раз!"
  148.     halt();
  149.   }
  150. }
  151.  
  152. void installSoftware() {
  153.   Serial.print(F("\nReady to install utility software. Please ensure your Arduino Yun is connected to internet.\nReady to proceed (yes/no)?"));  //  "К установке утилиты все готово. Пожалуйста, убедитесь, что Arduino Yun подключена к интернету.\nГотовы продолжать (да/нет)?"
  154.   expectYesBeforeProceeding();
  155.  
  156.   Serial.println(F("Updating software list..."));  //  "Обновление списка ПО..."
  157.  
  158.   Process opkg;
  159.  
  160.   // Обновляем список пакетов
  161.   int exitCode = opkg.runShellCommand("opkg update");
  162.   // если с кодом завершения (exitCode) процесса никаких проблем нет, это значит, что пакет установлен успешно:
  163.   if (exitCode != SUCCESSFUL_EXIT_CODE) {
  164.     Serial.println(F("err. with opkg, check internet connection"));  //  "Ошибка с opkg, проверьте интернет-соединение"
  165.     debugProcess(opkg);
  166.     halt();
  167.   }
  168.   Serial.println(F("Software list updated. Installing software (this will take a while)..."));  //  "Список ПО обновлен. Установка ПО (этот процесс займет какое-то время)..."
  169.  
  170.   // Устанавливаем утилиту для форматирования в EXT4:
  171.   exitCode = opkg.runShellCommand(F("opkg install e2fsprogs mkdosfs fdisk rsync"));
  172.   if (exitCode != SUCCESSFUL_EXIT_CODE) {
  173.     Serial.println(F("err. installing e2fsprogs mkdosfs fdisk"));  //  "Ошибка в установке e2fsprogs mkdosfs fdisk"
  174.     debugProcess(opkg);
  175.     halt();
  176.   }
  177.   Serial.println(F("e2fsprogs mkdosfs fdisk rsync installed"));  //  " e2fsprogs mkdosfs fdisk rsync установлена"
  178. }
  179.  
  180. void partitionAndFormatSDCard() {
  181.   Serial.print(F("\nProceed with partitioning micro SD card (yes/no)?"));  //  "\nПродолжать разбиение SD-карты? (да/нет)?"
  182.   expectYesBeforeProceeding();
  183.  
  184.   unmount();
  185.  
  186.   Process format;
  187.  
  188.   // Очищаем таблицу разбиения SD-карты:
  189.   format.runShellCommand("dd if=/dev/zero of=/dev/sda bs=4096 count=10");
  190.   debugProcess(format);
  191.  
  192.   // Запускаем процесс разбиения и создаем первую часть:
  193.   int dataPartitionSize = readPartitionSize();
  194.  
  195.   Serial.println(F("Partitioning (this will take a while)..."));  //  "Разбиение SD-карты (этот процесс займет какое-то время)..."
  196.   String firstPartition = "(echo n; echo p; echo 1; echo; echo +";
  197.   firstPartition += dataPartitionSize;
  198.   firstPartition += "M; echo w) | fdisk /dev/sda";
  199.   format.runShellCommand(firstPartition);
  200.   debugProcess(format);
  201.  
  202.   unmount();
  203.  
  204.   // Создаем вторую часть:
  205.   format.runShellCommand(F("(echo n; echo p; echo 2; echo; echo; echo w) | fdisk /dev/sda"));
  206.   debugProcess(format);
  207.  
  208.   unmount();
  209.  
  210.   // Уточняем, что форматировать нужно в формате FAT32:
  211.   format.runShellCommand(F("(echo t; echo 1; echo c; echo w) | fdisk /dev/sda"));
  212.  
  213.   unmount();
  214.  
  215.   delay(5000);
  216.  
  217.   unmount();
  218.  
  219.   // Форматируем первую часть в FAT32:
  220.   int exitCode = format.runShellCommand(F("mkfs.vfat /dev/sda1"));
  221.   debugProcess(format);
  222.   if (exitCode != SUCCESSFUL_EXIT_CODE) {
  223.     Serial.println(F("\nerr. formatting to FAT32"));  //  "\nОшибка при форматировании в FAT32"
  224.     halt();
  225.   }
  226.   delay(100);
  227.  
  228.   // Форматируем вторую часть в Linux EXT4:
  229.   exitCode = format.runShellCommand(F("mkfs.ext4 /dev/sda2"));
  230.   debugProcess(format);
  231.   if (exitCode != SUCCESSFUL_EXIT_CODE) {
  232.     Serial.println(F("\nerr. formatting to EXT4"));  //  "\nОшибка при форматировании в EXT4"
  233.     halt();
  234.   }
  235.  
  236.   Serial.println(F("Micro SD card correctly partitioned"));  // "Разбиение SD-карты прошло успешно"
  237. }
  238.  
  239. void createArduinoFolder() {
  240.   Serial.print(F("\nCreating 'arduino' folder structure..."));  //  "Создание папки «arduino»"
  241.   Process folder;
  242.  
  243.   folder.runShellCommand(F("mkdir -p /mnt/sda1"));
  244.   folder.runShellCommand(F("mount /dev/sda1 /mnt/sda1"));
  245.   folder.runShellCommand(F("mkdir -p /mnt/sda1/arduino/www"));
  246.  
  247.   unmount();
  248. }
  249.  
  250. void copySystemFilesFromYunToSD() {
  251.   Serial.print(F("\nCopying files from Arduino Yun flash to micro SD card..."));  //  "Копирование файлов с flash-памяти Arduino Yun на SD-карту"
  252.   Process copy;
  253.  
  254.   copy.runShellCommand(F("mkdir -p /mnt/sda2"));
  255.   copy.runShellCommand(F("mount /dev/sda2 /mnt/sda2"));
  256.   copy.runShellCommand(F("rsync -a --exclude=/mnt/ --exclude=/www/sd /overlay/ /mnt/sda2/"));
  257.  
  258.   unmount();
  259. }
  260.  
  261. void unmount() {
  262.   Process format;
  263.   format.runShellCommand(F("umount /dev/sda?"));
  264.   debugProcess(format);
  265.   format.runShellCommand(F("rm -rf /mnt/sda?"));
  266.   debugProcess(format);
  267. }
  268.  
  269. void enableExtRoot() {
  270.   Serial.print(F("\nEnabling micro SD as additional disk space... "));  //  "Активация SD-карты в качестве дополнительного дискового пространства..."
  271.  
  272.   Process fstab;
  273.  
  274.   fstab.runShellCommand(F("uci add fstab mount"));
  275.   fstab.runShellCommand(F("uci set fstab.@mount[0].target=/overlay"));
  276.   fstab.runShellCommand(F("uci set fstab.@mount[0].device=/dev/sda2"));
  277.   fstab.runShellCommand(F("uci set fstab.@mount[0].fstype=ext4"));
  278.   fstab.runShellCommand(F("uci set fstab.@mount[0].enabled=1"));
  279.   fstab.runShellCommand(F("uci set fstab.@mount[0].enabled_fsck=0"));
  280.   fstab.runShellCommand(F("uci set fstab.@mount[0].options=rw,sync,noatime,nodiratime"));
  281.   fstab.runShellCommand(F("uci commit"));
  282.  
  283.   Serial.println(F("enabled"));  //  "Активация завершена"
  284. }

Откройте Serial Monitor и обязательно проверьте, выбран ли в выпадающем меню пункт Newline.

Старт

Когда вы откроете Serial Monitor, появится сообщение, которое известит вас о том, что от Yun нужно отключить все другие дисковые устройства, кроме SD-карты. Если готовы продолжать, напишите «yes» и нажмите Enter.

Extroot 1.png

Установка ПО

Для начала устанавливаем программное обеспечение, необходимое для форматирования SD-карты. Перед тем, как напечатать «yes», убедитесь, что Yun подключена к интернету, иначе установка будет неудачной.

Extroot 2.png

Форматирование SD-карты

Теперь, когда необходимое ПО корректно установлено, печатаем «yes» и жмем Enter, чтобы начать форматирование SD-карты.

Extroot 3.png

Уточняем размер первой части SD-карты – той, которую выбудете использовать для обмена файлами с компьютером. Оставшаяся часть будет отведена под файловую систему Linux. В данном примере мы используем 2-гигабайтную SD-карту, а под первую часть отводим 700 Мб. Оставшиеся 1,3 Гб приютят у себя Linux.

Extroot 4.png

Когда все будет готово, все конфигурационные и прочие файлы, хранящиеся во внутренней flash-памяти, будут скопированы на вторую часть SD-карты. Далее, чтобы все изменения вступили в силу, Yun нужно перезагрузить. Для этого нажмите на кнопку YUN RST (она располагается недалеко от светодиодов).

Extroot 5.png

Скетч продолжит показывать оболочку Yun Linux, а на экран будет выводиться множество сообщений, оповещающих о загрузке Yun. Когда она закончится, впишите это:

  1. df -h / /mnt/sda1

В ответ вы должны получить что-то вроде этого:

  1. Filesystem              Size    Used Available Use% Mounted on
  2. rootfs                  1.2G    51.7M   1.0G   5% /
  3. /dev/sda1               698.6M  12.0K   698.6M   0% /mnt/sda1

Как видите, теперь нам доступен один гигабайт свободного дискового пространства. В самой OpenWrt оно будет называться extroot. Более подробную информацию можно найти на сайте OpenWrt.

См.также

Внешние ссылки

  1. Arduino - How to expand the Yún disk space