RT-Thread es un sistema operativo en tiempo real de código abierto que se utiliza para programar dispositivos de Internet de las cosas (IoT). FinSH es el componente de línea de comandos de RT-Thread y proporciona un conjunto de interfaces de operación que permiten a los usuarios contactar un dispositivo desde la línea de comandos. Se utiliza principalmente para depurar o ver información del sistema.
Por lo general, la depuración de desarrollo se muestra mediante depuradores de hardware y printf
registros En algunos casos, sin embargo, estos dos métodos no son muy útiles porque se abstraen de lo que se está ejecutando y pueden ser difíciles de analizar. Sin embargo, RT-Thread es un sistema de subprocesos múltiples, que es útil cuando desea conocer el estado de un subproceso en ejecución o el estado actual de un sistema de control manual. Debido a que es de subprocesos múltiples, puede tener un shell interactivo, por lo que puede ingresar comandos, llamar a una función directamente en el dispositivo para obtener la información que necesita o controlar el comportamiento del programa. Esto puede parecerle normal si solo está acostumbrado a los sistemas operativos modernos como Linux o BSD, pero para los piratas informáticos esto es un gran lujo y está muy lejos de conectar cables serie directamente a las placas para vislumbrar errores.
FinSH tiene dos modos:
- Un modo de intérprete de lenguaje C, conocido como estilo c
- Un modo de línea de comandos tradicional, conocido como
msh
(carcasa del módulo)
En el modo de interpretación del lenguaje C, FinSH puede analizar expresiones que ejecutan la mayoría del lenguaje C y acceder a funciones y variables globales en el sistema mediante llamadas a funciones. También puede crear variables desde la línea de comandos.
En msh
modo, FinSH funciona de manera similar a shells tradicionales como Bash.
El estándar de comandos GNU
Más recursos de Linux
- Hoja de trucos de los comandos de Linux
- Hoja de trucos de comandos avanzados de Linux
- Curso en línea gratuito:Descripción general técnica de RHEL
- Hoja de trucos de red de Linux
- Hoja de trucos de SELinux
- Hoja de trucos de los comandos comunes de Linux
- ¿Qué son los contenedores de Linux?
- Nuestros últimos artículos sobre Linux
Cuando estábamos desarrollando FinSH, aprendimos que antes de poder escribir una aplicación de línea de comandos, debe familiarizarse con los estándares de línea de comandos de GNU. Este marco de prácticas estándar ayuda a familiarizar una interfaz, lo que ayuda a los desarrolladores a sentirse cómodos y productivos al usarla.
Un comando GNU completo consta de cuatro partes principales:
- Nombre del comando (ejecutable): El nombre del programa de línea de comandos
- Subcomando: El nombre de la subfunción del programa de comando
- Opciones: Opciones de configuración para la función de subcomando
- Argumentos: Los argumentos correspondientes para las opciones de configuración de la función de subcomando
Puede ver esto en acción con cualquier comando. Tomando Git como ejemplo:
git reset --hard HEAD~1
Que se desglosa como:
El comando ejecutable es git , el subcomando es restablecer , la opción utilizada es --head , y el argumento es HEAD~1 .
Otro ejemplo:
systemctl enable --now firewalld
El comando ejecutable es systemctl , el subcomando es habilitar , la opción es --ahora , y el argumento es firewalld .
Imagine que desea escribir un programa de línea de comandos que cumpla con los estándares GNU utilizando RT-Thread. FinSH tiene todo lo que necesita y ejecutará su código como se esperaba. Mejor aún, puede confiar en este cumplimiento para poder migrar con confianza sus programas Linux favoritos.
Escribe un elegante programa de línea de comandos
Este es un ejemplo de RT-Thread ejecutando un comando que los desarrolladores de RT-Thread usan todos los días.
usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard]
[--upgrade] [--printenv]
optional arguments:
-h, --help show this help message and exit
--force-update force update and clean packages, install or remove the
packages by your settings in menuconfig
--update update packages, install or remove the packages by your
settings in menuconfig
--list list target packages
--wizard create a new package with wizard
--upgrade upgrade local packages list and ENV scripts from git repo
--printenv print environmental variables to check
Como puede ver, parece familiar y actúa como la mayoría de las aplicaciones POSIX que ya puede ejecutar en Linux o BSD. Se proporciona ayuda cuando se usa una sintaxis incorrecta o insuficiente, se admiten opciones largas y cortas, y la interfaz de usuario general es familiar para cualquiera que haya usado una terminal Unix.
Tipos de opciones
Hay muchos tipos diferentes de opciones, y se pueden dividir en dos categorías principales por longitud:
- Opciones cortas: Consta de un guión más una sola letra, por ejemplo, el
-h
opción enpkgs -h
- Opciones largas: Consta de dos guiones más palabras o letras, por ejemplo,
--target
opción enscons- --target-mdk5
Puede dividir estas opciones en tres categorías, según si tienen argumentos:
- Sin argumentos: La opción no puede ir seguida de argumentos
- Deben incluirse argumentos: La opción debe ir seguida de argumentos
- Argumentos opcionales: Los argumentos después de la opción están permitidos pero no son obligatorios
Como cabría esperar de la mayoría de los comandos de Linux, el análisis de opciones de FinSH es bastante flexible. Puede distinguir una opción de un argumento basándose en un espacio o un signo igual como delimitador, o simplemente extrayendo la opción en sí misma y asumiendo que lo que sigue es el argumento (en otras palabras, ningún delimitador):
wavplay -v 50
wavplay -v50
wavplay --vol=50
Usando optparse
Si alguna vez ha escrito una aplicación de línea de comandos, puede saber que generalmente hay una biblioteca o módulo para su idioma de elección llamado optparse. Se proporciona a los programadores para que las opciones (como -v o --detallado ) ingresado como parte de un comando puede ser analizado en relación con el resto del mando. Es lo que ayuda a que su código reconozca una opción de un subcomando o argumento.
Al escribir un comando para FinSH, el optparse
el paquete espera este formato:
MSH_CMD_EXPORT_ALIAS(pkgs, pkgs, this is test cmd.);
Puede implementar opciones usando la forma larga o corta, o ambas. Por ejemplo:
static struct optparse_long long_opts[] =
{
{"help" , 'h', OPTPARSE_NONE}, // Long command: help, corresponding to short command h, without arguments.
{"force-update", 0 , OPTPARSE_NONE}, // Long comman: force-update, without arguments
{"update" , 0 , OPTPARSE_NONE},
{"list" , 0 , OPTPARSE_NONE},
{"wizard" , 0 , OPTPARSE_NONE},
{"upgrade" , 0 , OPTPARSE_NONE},
{"printenv" , 0 , OPTPARSE_NONE},
{ NULL , 0 , OPTPARSE_NONE}
};
Después de crear las opciones, escriba el comando y las instrucciones para cada opción y sus argumentos:
static void usage(void)
{
rt_kprintf("usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard]\n");
rt_kprintf(" [--upgrade] [--printenv]\n\n");
rt_kprintf("optional arguments:\n");
rt_kprintf(" -h, --help show this help message and exit\n");
rt_kprintf(" --force-update force update and clean packages, install or remove the\n");
rt_kprintf(" packages by your settings in menuconfig\n");
rt_kprintf(" --update update packages, install or remove the packages by your\n");
rt_kprintf(" settings in menuconfig\n");
rt_kprintf(" --list list target packages\n");
rt_kprintf(" --wizard create a new package with wizard\n");
rt_kprintf(" --upgrade upgrade local packages list and ENV scripts from git repo\n");
rt_kprintf(" --printenv print environmental variables to check\n");
}
El siguiente paso es el análisis. Si bien aún no puede implementar sus funciones, el marco del código analizado es el mismo:
int pkgs(int argc, char **argv)
{
int ch;
int option_index;
struct optparse options;
if(argc == 1)
{
usage();
return RT_EOK;
}
optparse_init(&options, argv);
while((ch = optparse_long(&options, long_opts, &option_index)) != -1)
{
ch = ch;
rt_kprintf("\n");
rt_kprintf("optopt = %c\n", options.optopt);
rt_kprintf("optarg = %s\n", options.optarg);
rt_kprintf("optind = %d\n", options.optind);
rt_kprintf("option_index = %d\n", option_index);
}
rt_kprintf("\n");
return RT_EOK;
}
Aquí está el archivo principal de la función:
#include "optparse.h"
#include "finsh.h"
Luego, compile y descargue en un dispositivo.
Hackeo de hardware
El hardware de programación puede parecer intimidante, pero con IoT se está volviendo cada vez más común. No todo puede o debe ejecutarse en una Raspberry Pi, pero con RT-Thread puede mantener una sensación familiar de Linux, gracias a FinSH.
Si tiene curiosidad acerca de la codificación en bare metal, pruebe RT-Thread.