Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Interruptor de selección de arranque de hardware con Pico

Elija previamente el sistema operativo para arrancar, incluso antes de encender la computadora, activando un interruptor. Ahora no tiene que esperar para seleccionar el sistema operativo.

Historia

Deambulando por Hackaday.io en busca de proyectos, me topé con este proyecto (clic) de Stephen Holdaway. En este proyecto, resolvió una tarea frustrante que enfrentan todos los usuarios de arranque dual, que están sentados y esperando para elegir el sistema operativo (Windows) del menú de GRUB en cualquier momento cuando queremos cambiar a Windows. Pudo agregar un interruptor de hardware para determinar el sistema operativo que debe arrancar cada vez que se enciende la computadora.

Lo logró configurando el microcontrolador STM32 como un dispositivo de almacenamiento masivo USB. Ha documentado todo su viaje a través de la investigación y la implementación del proyecto en hackaday post (clic). Revise esta publicación para comprender mejor las implementaciones.

En este proyecto, mostraré cómo logré portar los cambios a Raspberry Pi Pico. Puede encontrar mi versión en este repositorio de GitHub (clic).

Concepto

GNU GRUB es un programa que se ejecuta antes de que se cargue cualquier sistema operativo. A través de este menú, podemos seleccionar qué sistema operativo cargar. GRUB ofrece módulos muy limitados para trabajar. Esto significa que no puede leer datos de un microcontrolador conectado a través de USB. Pero puede leer datos de discos de almacenamiento.

Entonces podemos engañar a GRUB para que lea datos del microcontrolador, enumerando nuestro micro como un dispositivo de almacenamiento masivo.

Por lo tanto, enumeramos nuestro raspberry pi pico como un dispositivo de almacenamiento masivo, a través de la biblioteca tinyUSB, que tendrá un archivo switch.cfg archivo, en el que pico escribirá la posición del interruptor, es decir, 1 para ON 0 para OFF .

Tenemos que agregar un script en GRUB, que son funciones para leer el archivo switch.cfg y establecer el valor predeterminado a 0 (Ubuntu) / 2 (Windows).

GRUB cuando se carga, ejecuta nuestros scripts personalizados, que a su vez busca nuestro dispositivo por sus identificadores UUID, y si sale lee el archivo switch.cfg. Después de obtener la posición del interruptor, establece la selección predeterminada del sistema operativo respectivamente.

En resumen,

Configuración de Pico como un dispositivo de almacenamiento masivo

He usado el cdc_msc ejemplo por tinyUSB para lograr esto. El ejemplo configura el pico como un dispositivo de almacenamiento masivo y crea un sistema de archivos FAT12 y enumera un archivo README.txt.

Cambié el archivo README.txt a switch.cfg y agregué la línea "set os_hw_switch =0 \ n" al archivo.

 # define SWITCH_CFG_CONTENTS \ 
"set os_hw_switch =0 \ n"

...
// ----- -------- Bloque3:Contenido Léame ------------- //
SWITCH_CFG_CONTENTS

Ahora hemos configurado pico como un dispositivo de almacenamiento masivo. Después de copiar el archivo uf2 a pico, se enumera como dispositivo de almacenamiento. Necesitaremos el ID de UUID del dispositivo para la secuencia de comandos de GRUB, que es UUID =”0000-1234 ″.

 $ sudo blkid 
...
/ dev / sda:SEC_TYPE ="msdos" LABEL_FATBOOT ="TinyUSB MSC" LABEL ="TinyUSB MSC" UUID ="0000-1234" BLOCK_SIZE ="512" TYPE ="vfat"

Circuito

Leyendo la posición del interruptor y escribiendo en el archivo

Ahora necesitamos leer la posición del interruptor y cambiar el contenido del archivo switch.cfg en consecuencia, es decir,

He usado GPIO_PIN 28 como el pin del interruptor, que está configurado para bajar.

read_switch_value vuelva a la posición del interruptor, es decir, "1" está encendido (alto) y "0" apagado (abajo).

 // ------------------------- main.c -------- ------------- 
#define SWITCH_PIN 28

// leer el valor del interruptor
uint8_t read_switch_value ()
{
devolver gpio_get (SWITCH_PIN)? '1':'0';
}

int main (void)
{
gpio_init (SWITCH_PIN);

// configurar el pin como ENTRADA
gpio_set_dir (SWITCH_PIN, falso);

// configura el pin como PULL_DOWN
gpio_set_pulls (SWITCH_PIN, false, true);

Para escribir la posición del interruptor en switch.cfg, he usado readGRUBConfig () que llama al read_switch_value función, y configure el búfer de salida con la posición del interruptor.

Descubrí que al leer el tercer bloque3 lba está configurado en 3, por lo que intercepta la llamada y llama a readGrubConfig y pasando el búfer donde se copiará el contenido del archivo.

 // ------------------------- msc_disk.c -------- ------------- 

static char grubConfigStr [] ="set os_hw_switch =0 \ n";
static void readGrubConfig (uint8_t * salida)
{
// Modifica la cadena de configuración con el valor de cambio actual
grubConfigStr [sizeof (grubConfigStr) -3] =read_switch_value ();
memcpy (salida, &grubConfigStr, sizeof (grubConfigStr));
}

// Se invoca la devolución de llamada cuando se recibe el comando READ10.
// Copia los datos del disco al búfer (hasta el tamaño de búfer) y devuelve el número de bytes copiados.
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void * buffer, uint32_t bufsize)
{
(void) lun;
// al leer el archivo
if (lba ==3) {
readGrubConfig (búfer);
return bufsize;
}
...
...
}

Compila el código Pico

Necesitamos agregar pico stdlib a nuestro código para obtener el gpio PIN de acceso.

 // ------------------------- main.c -------- --------------------------- 
#include
#include
# include
#include "bsp / board.h"
#include "tusb.h"
...
#include "pico / stdlib.h "

Para hacer el proyecto:

 $ mkdir build 
$ cd build
$ cmake ..
$ make

Configuración de GRUB para leer el contenido del archivo

He agregado estos cambios en mi Ubuntu 20.10.

 $ sudo vim /etc/grub.d/40_custom 

....
# Busque el dispositivo de conmutador de hardware por su codificación ID del sistema de archivos
buscar --no-floppy --fs-uuid --set hdswitch 0000-1234

# Si lo encuentra, lea el archivo de configuración dinámica y seleccione la entrada adecuada para cada posición
si ["$ {hdswitch}"]; luego
fuente ($ hdswitch) /switch.cfg

if ["$ {os_hw_switch}" ==0]; luego
# Boot Linux
set default ="0"
elif ["$ {os_hw_switch}" ==1]; luego
# Arrancar Windows
establecer predeterminado ="2"
si no
# Recuperar el valor predeterminado
establecer predeterminado ="$ {GRUB_DEFAULT}"
fi

else
establecer predeterminado ="$ {GRUB_DEFAULT}"
fi

Primero, buscamos nuestro sistema de archivos. GRUB tiene un subcomando buscar solo por esto.

Si se encuentra algún dispositivo, el primer dispositivo encontrado se establece como el valor de la variable de entorno.

–set hdswitch hdswitch es nuestra variable de entorno y se establece con el nombre del disco si se encuentra.

A continuación, obtenemos el archivo switch.cfg si el hdswitch se establece la variable, que crea otra variable de entorno os_hw_switch con la posición del interruptor, es decir, 0/1.

Leemos el valor del os_hw_switch y establezca el valor predeterminado en 0 o 2 respectivamente. 0 porque Ubuntu está en la posición 0 y las ventanas en la 2ª posición en el menú de GRUB.

Por último, si hdswitch no se configuró, configuramos el valor predeterminado en GRUB_DEFAULT.

Ahora necesitamos actualizar nuestro grub:

 $ sudo update-grub 

Fuente: Conmutador de selección de arranque de hardware con Pico


Proceso de manufactura

  1. Dispositivo de depilación
  2. Declaración de cambio de C#
  3. C # usando
  4. Estación meteorológica Raspberry Pi 2
  5. Sistema de control de dispositivo basado en temperatura usando LM35
  6. Monitoreo remoto del clima usando Raspberry Pi
  7. SensorTag a Blynk usando Node-RED
  8. Sensor de movimiento con Raspberry Pi
  9. Robot que usa Raspberry Pi y Bridge Shield
  10. Robot controlado por Wifi usando Raspberry Pi
  11. Una introducción a la piratería de hardware integrado en dispositivos IoT