jueves, 8 de agosto de 2024

Activar Protecion Arduino UNO

Impedir la clonación del Arduino UNO


 
Les doy la bienvenida a esta entrada en la quiero responder a la pregunta que me han hecho en varias oportunidades, "¿Como hacer para que no copien mi proyecto realizado en Arduino?". Pues bien, ante la consulta debo recordar que el principio de utilizar una plataforma de código abierto como Arduino, implica que el proyecto(software) elaborado no debería estar cerrado a otras personas, mas al contrario compartir tu trabajo representa un pilar fundamental en el desarrollo de esta plataforma de código abierto. Ahora si pese a esto tu no quieres que alguien copie tu proyecto porque es una idea original que te costo muchas noches en desvelo para que alguien pueda sacar beneficio de ello, en esta entrada te explicare como hacerlo.

Introduccion al Tema

Para empezar listare las cosas que necesitaras:

  • Un programador(UsbASP, UTK500, ArduinoISP, etc);
  • Una tarjeta Arduino(UNO, Mega o Nano);
  • Software de programación para AVR(avrdude, avrp, uisp, etc).

Utilizaremos el programador USBASP por ser una de las opciones mas asequibles, junto al software de programación avrdude y la tarjeta Arduino UNO que como saben posee un Microcontrolador <MCU> ATMega328.

Fig2. Programador UsbASP


Este programador nos posibilita leer y cargar el código del programa <firmware> en la memoria ROM <FLASH> del Microcontrolador ATMega utilizando la interfaz de comunicación serial ISP que poseen las tarjeta Arduino UNO. 
Otra alternativa si no dispone de un programador, es utilizar un tarjeta Arduino UNO cargado con el programa ISP <Arduino as ISP>, que convertirá nuestro Arduino UNO en un programador, eso si, necesitaras realizar correctamente las conexiones entre el Arduino Programador y el Arduino que requiere ser programado. Abordare este punto en la entrada <Cargar el bootloader Arduino con Arduino UNO>
 
Bueno, ya entrando en el tema, indicar que la forma de llevar a cabo la protección de memoria del microcontrolador, es sencillamente impedir su lectura desde un programador, y esto es posible programando los bits del registro LOCK, ver figura 3, este registro permite activar la restricción de acceso a la memoria de programa y también la memoria datos EEPROM.

Fig3. bits del registro LOCK
Por defecto los bits del registro están sin programar o desactivados, lo que representa un valor 0xFF todo en 1, y pueden ser activados colocando en 0 en cualquier momento, pero una vez programados, la única forma de restablecer su valor a 1, es borrando toda la memoria de microcontrolador, esto significa aplicar la instrucción de borrado chip erase. Entonces si desea restringir la programación y lectura de la memoria Flash (Programa) y EEPROM (Datos), deberá colocar en 0 los bits LB1 y LB2, pero antes de realizar esto debe considerar que en arduino los bits BLB12 y BLB11 están activados para proteger el cargador, mientras que los bits BLB02 y BLB01 permanecen desactivados para permitir el acceso a la memoria utilizada por la aplicación, por lo tanto, el valor del registro lock con relación a la protección de la memoria de programa, sera:
  •  0xCF = Se puede actualizar desde arduino y leer la memoria
  •  0xCC = Se puede actualizar desde arduino pero no leer la memoria
  •  0xC0 = No se puede actualizar desde arduino y tampoco leer la memoria
avrdude es un programa de linea de comandos disponible para linux y windows, que permitirá llevar a cabo la carga y descarga de toda la memoria, esto incluye el programa y los datos, así mismo con este programa podremos establecer los bits de los fusibles y el registro LOCK. 
Puesto que no haremos uso de todos los parámetros de comandos con avrdude solo nos centraremos en aquello que no permita realizar y verificar la protección de la memoria, pero te dejo un enlace que brinda mas detalle al respecto <Manual AVRDURE>
La instalación de avrdude en el caso Linux/Debian solo requiere la ejecución del siguiente comando desde una terminal de consola:
#apt-get install avrdude 
 
También dejo algunos enlaces de ayuda en caso de utilizar Windows:
 
Programacion del ATmega328
Ahora describiré el proceso para efectuar la protección en tres pasos.
 
PASO 1 (Cargar el firmware al Microcontrolador desde Arduino)
Se entiende por código del programa o firmware al fichero con extensión hex generado por el compilador, a partir del código fuente elaborado por el desarrollador. En este paso veremos como cargar el firmware al microcontrolador de la tarjeta UNO, para lo cual tomaremos de ejemplo un programa sencillo que destellara el LED integrado en la tarjeta, el programa puede encontrarlo en los ejemplo de Arduino con el nombre BlinkLED

//Programa de ejemplo para destellar un LED
void setup()
{
   pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
   digitalWrite(LED_BUILTIN, HIGH);
   delay(250);
   digitalWrite(LED_BUILTIN, LOW);
   delay(250);
}

Fig4. IDE Arduino

Como veras pasar el firmware al microcontrolador es sencillamente hacer click en el boton [UPLOAD], al hacer el programa previo es reemplazado por el recientemente compilado.

PASO 2 (Recuperar el firmware del Microcontrolador)
Recuperar o leer el firmware desde el microcontrolador, no es posible desde Arduino, y por lo tanto necesitara de un programador para este paso. 
Entonces una con el programador USBASP, debe conectarlo al puerto ISP de la tarjeta Arduino UNO, observe la figura 4 que muestra la disposición de los pines y su orientacion.
Fig5. Orientación de la conexión ISP
Una vez realizada la conexión del programador al puerto ISP, conectamos el programador a nuestro ordenador, mismo que se vinculara a traves de una puerto serial, en mi caso el puerto asignado es /dev/ttyUSB0, en el caso de windows sera una COMx. Entonces ejecutamos desde la consola linux, el comando avrdude con los siguientes parametros:
 
#avrdude -P /dev/ttyUSB0 -c usbasp -p m328p -U flash:r:flash.hex -U eeprom:r:eeprom.hex
avrdude: AVR device initialized and ready to accept instructions
Reading | ############################################ | 100% 0.00s
avrdude: Device signature = 0x1e950f (probably m328p)

avrdude: reading flash memory:
Reading | ############################################ | 100% 16.70s
avrdude: writing output file "flash.hex"

avrdude: reading eeprom memory:
Reading | ############################################ | 100% 0.53s
avrdude: writing output file "eeprom.hex"

avrdude: safemode: Fuses OK (E:FE, H:DE, L:FF)
avrdude done.  Thank you.

 
Con esto avrdude recupero el contenido de la memoria de programa y tambien de datos del microcontrolador Atmega328 (Arduino UNO), y los guardo en los archivos de sistema flash.hex y eeprom.hex. El parametro -P especifica el puerto serie asignado al programador USBASP en mi caso.
Notara también que la respuesta al comando muestra al final los valores que tienen los fusibles del microcontrolador que son EFUSE, HFUSE y LFUSE con valores 0xFE, 0xDE y 0xFF respectivamente.  Estos valores son los establecidos por el programa cargador bootloader que utiliza Arduino y por lo tanto no deben modificarse, al menos si planea seguir utilizando arduino.
 
Otra manera de hacer lectura de los fusibles es ejecutando avrdude en modo linea de comando, con la siguiente instrucción:
 
#avrdude -c usbasp -p m328p -t //Ingresara en modo comando
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e950f (probably m328p)
avrdude> d efuse
Reading | ################################################## | 100% 0.00 s
0000 fd
avrdude> d hfuse
Reading | ################################################## | 100% 0.00 s
0000 de
avrdude> d lfuse
Reading | ################################################## | 100% 0.00 s
0000 ff
avrdude> d lock
Reading | ################################################## | 100% 0.00 s
0000 cf
 
PASO 3 (Restringir la lectura de firmware del Microcontrolador)
Este seria el paso necesario para evitar recuperar el firmware del microcontrolador, es decir el programa de la tarjeta Arduino UNO, con esto no sera posible que alguien clone la funcionalidad en otra tarjeta. 
El comando avrdude se ejecuta desde la consola con los siguientes parametros:
 
#avrdude -P /dev/ttyUSB0 -c usbasp -p m328p -U lock:w:0xCC:m
avrdude: AVR device initialized and ready to accept instructions
Reading | ############################################ | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "0xCC"
avrdude: writing lock (1 bytes):
Writing | ############################################ | 100% 0.01s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0xCC:
avrdude: load data lock data from input file 0xCC:
avrdude: input file 0xC0 contains 1 bytes
avrdude: reading on-chip lock data:
Reading | ########################################### | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: safemode: Fuses OK (E:FE, H:DE, L:FF)
avrdude done.  Thank you.
 
El establecimiento del registro lock con el valor 0xCC, impedira la lectura de la memoria FLASH (Programa) y datos (EEPROM), manteniendo la posibilidad de seguir actualizando el programa desde arduino.
 
Otra manera de modificar el registro lock es ejecutando avrdude en modo linea de comando con la siguiente instrucción: 
 
#avrdude -c usbasp -p m328p -t //Ingresara en modo comando
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e950f (probably m328p)
avrdude> w lock 0 0xcc
Writing | ################################################## | 100% 0.00 s
avrdude> d lock
Reading | ################################################## | 100% 0.00 s
0000  cc 

 
A manera comprobar la restricción establecidad por el lock = 0xcc, intentaremos extraer nuevamente el contenido de la memoria de programa, ejecutando la siguiente instrucción:
 
#avrdude -P /dev/ttyUSB0 -c usbasp -p m328p -U flash:r:flash2.hex -U 

Aparentemente como respuesta a la instrucción nos indica que el código se recupero con normalidad y se almaceno en el archivo flash2.hex, pero haciendo una lista de los archivos de la carpeta de trabajo notamos que flash2.hex tiene 0 bytes, es decir no contiene informacion.

Fig6. Lista de ficheros recuperados

Entones esto hemos conseguido proteger la posible clonacion de la tarjeta Arduino UNO y la única manera de lograr quitar la restricción es borrando el microcontrolador con instrucción chip erase, este paso borrara incluso el cargador de arduino, por lo que necesitara cargarlo nuevamente con un programador. 

PASO 4 (Cargar el firmware al Microcontrolador)

A diferencia del paso 1, considerando que el microcontrolador no cuenta con el cargador o bootloader de Arduino, no sera posible hacer la carga desde Arduino. Por lo tanto veremos como cargar el código de programa a una tarjeta UNO, a partir de los ficheros hex recuperados de otra tarjeta, este paso también nos servirá para restablecer los bits de protección de memoria en el registro LOCK al valor por defecto 0xCF.  
 
La instrucción requerida para llevar a cabo esta tarea es:
 
#avrdude -P /dev/ttyUSB0 -c usbasp -p m328p -e -V -U flash:w:flash.hex -U eeprom:w:eeprom.hex -U efuse:w:0xFE:m -U hfuse:w:0xDE:m -U lock:w:0xCF:m

avrdude: AVR device initialized and ready to accept instructions
Reading | ########################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: erasing chip
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: reading input file "flash.hex"
avrdude: input file flash.hex auto detected as raw binary
avrdude: writing flash (32768 bytes):
Writing | ########################################### | 100% 29.07s

avrdude: 32768 bytes of flash written
avrdude: reading input file "eeprom.hex"
avrdude: input file eeprom.hex auto detected as raw binary
avrdude: writing eeprom (1024 bytes):
Writing | ########################################### | 100% 10.81s

avrdude: 1024 bytes of eeprom written
avrdude: reading input file "0xFE"
avrdude: writing efuse (1 bytes):
Writing | ########################################### | 100% 0.00s

avrdude: 1 bytes of efuse written
avrdude: reading input file "0xDE"
avrdude: writing hfuse (1 bytes):
Writing | ########################################### | 100% 0.00s

avrdude: 1 bytes of hfuse written
avrdude: reading input file "0xCF"
avrdude: writing lock (1 bytes):
Writing | ########################################### | 100% 0.01s

avrdude: 1 bytes of lock written
avrdude: safemode: Fuses OK (E:FE, H:DE, L:FF)
avrdude done.  Thank you.

 
Ahora con los bits del registro LOCK restablecidos al valor por defecto probaremos recuperar nuevamente el código de la memoria del microcontrolador, ejecutando la siguiente orden.

#avrdude -P /dev/ttyUSB0 -c usbasp -p m328p -U flash:r:flash3.hex

avrdude: AVR device initialized and ready to accept instructions
Reading | ########################################### | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading flash memory:
Reading | ########################################### | 100% 16.68s

avrdude: writing output file "flash3.hex"
avrdude: safemode: Fuses OK (E:FE, H:DE, L:FF)
avrdude done.  Thank you.

Fig7. Lista de ficheros recuperados
Conclusiones
Se recomienda cautela en la transcripción al momento de ejecutar las instrucciones, sobre todo cuando se aplica el parámetro -e que borra y restablecer los fusibles del microcontrolador, tenga en cuenta que el bit SPIEN de HFUSE debe estar activado, caso contrario dejara al microcontrolador inhabitado para posteriores actualizaciones por SPI. para mayores datos puede consultar el apartado 31.2 de la hoja de datos del microcontrolador Atmega328.
 
Estos son los valores por defecto que el cargado(Bootloader) Arduino utiliza en las tarjetas Atmega.
Modelo      UNO328   NANO328    MEGA2560  
-U efuse      0xFD      0xFD       0xFD
-U hfuse     0xDE      0xDA        0xD8
-U lfuse      0xFF       0xFF        0xFF
-U lock       0xCF      0xCF
Algunos enlaces de interés relacionados al tema de esta entrada:

Dejo el vídeo donde muestro como hacer la copia, protección y restauración de una placa Arduino UNO. 



Sin mas que mencionar agradezco tu visita al blog y espero que el ejemplo visto pueda ser útil en tu formación y el proyecto que desarrollas.

Atentamente, Pablo Zárate Arancibia  email: pablinza@me.com / pablinzte@gmail.com, @pablinzar

Santa Cruz de la Sierra - Bolivia

No hay comentarios:

Publicar un comentario