Programação

Lançar uma aplicação após o boot, no Linux Debian 11 (bullseye)

Imaginemos um script escrito em Python, chamado o_meu_script.py e guardado na pasta /home/utilizador/scripts.
Imaginemos agora que pretendemos que este script seja lançado automaticamente, após o arranque do computador (Linux Debian 11). Para tal, pode-se recorrer ao gestor de serviços ‘systemd‘ da seguinte forma (no Terminal):

Ir para a pasta onde se encontra o ficheiro ‘o_meu_programa.py’:
utilizador@hostname:~$ cd scripts

Tornar o ficheiro executável:
utilizador@hostname:~/scripts$ chmod +x o_meu_programa.py

Criar um ficheiro de serviço para o gestor ‘systemd’, com o mesmo nome que o do script, usado um editor de texto (e.g., ‘nano’ ou ‘vim’):
utilizador@hostname:~/scripts$ sudo nano /etc/systemd/system/o_meu_programa.service

Inserir o código abaixo, alterando os parâmetros necessários, de acordo com a sua realidade.

[unit]
Description=Descrição do meu script

[Service]
ExecStart=/usr/bin/python3 /home/utilizador/scripts/o_meu_programa.py
WorkingDirectory=/home/utilizador/scripts
Restart=always
User=utilizador

[Install]
WantedBy=multi-user.target

Após guardar o ficheiro de serviço, carregar o novo ficheiro de serviço, no gestor de serviços ‘systemd’:
utilizador@hostname:~/scripts$ sudo systemctl daemon-reload

Permitir que o ficheiro de serviço seja executado após o boot do computador:
utilizador@hostname:~/scripts$ sudo systemctl enable o_meu_programa.service

Lançar o serviço:
utilizador@hostname:~/scripts$ sudo systemctl start o_meu_programa.service

Verificar que o serviço foi lançado e encontra-se a correr normalmente:
utilizador@hostname:~/scripts$ sudo systemctl status o_meu_programa.service

Et voilà le travail! 🙂

Converter um número Real para o formato binário em vírgula flutuante segundo a Norma IEEE-754

Já são tantas as vezes que expliquei o processo de conversão de um número qualquer para o formato binário em vírgula flutuante de acordo com a Norma IEEE-754 que desta vez, apeteceu-me escrever sobre isto. 🙂 Quem não quiser ler o que segue e preferir saltar para a versão condensada, clique aqui.

Entre outras coisas, a Norma IEEE-754 especifica dois níveis de precisão: simples e dupla. O primeiro nível ocupa 32 bits, o segundo, 64 bits. Para quem programa em linguagem C, o primeiro nível de precisão corresponde a uma variável do tipo float, o segundo, a uma variável do tipo double.

Atente à distribuição dos bits, de acordo com o nível de precisão do formato:

Tomemos por exemplo o número 94.0254, para o converter para um número em vírgula flutuante com precisão simples (32-bits) de acordo com a Norma IEEE-754. Este número é composto por duas partes: uma inteira (94) e uma fraccionária (0.0254).

1) Comecemos por converter para binário a parte inteira. Não vou entrar nos detalhes da conversão de um número entre os formatos Decimal e Binário. Há muita literatura sobre este assunto e muitos conversores automáticos online…

Portanto, a parte inteira fica: 1011110

2) Em seguida, converte-se a parte fraccionária. Mais uma vez, abstenho-me de entrar nos detalhes deste tipo de conversão. Creio que tal como a imagem anterior, a imagem abaixo é self-explanatory.

Portanto, o número Real convertido para binário fica:

3) O passo seguinte consiste na normalização do número convertido para o formato 1.xxxxxx… Isto é, operar o número original por forma a que a parte inteira fique “reduzida” a uma unidade. Para tal, usa-se a operação SHIFT LOGICAL RIGHT, ou simplesmente, divide-se por 2 e multiplica-se por 2, tantas vezes quantas as necessárias:

A última linha do processo acima, apresenta o número 94.0254, convertido para um número binário normalizado, multiplicado por 2^6, para satisfazer um dos requisitos da Norma IEEE-754. A parte em fundo cor de rosa, corresponde à parte fraccionária que aparecerá na trama final de 32 bits. São apenas 23 bits (os que cabem na precisão simples). Os restantes bits ficam truncados, originando um erro na representação do número original.

4) O 6 a fundo amarelo do passo anterior será adicionado a um BIAS, definido pela Norma IEEE-754, de acordo com o nível de precisão pretendido:

float (32 bits): BIAS = 127 (expoente de 8 bits)
double (64 bits): BIAS = 1023 (expoente de 11 bits)

O resultado desta soma corresponde ao valor da parte correspondente ao EXPOENTE do número em vírgula flutuante. Este expoente fica então (a fundo verde):

5) Por fim, o bit mais significativo da trama de 32 bits (64, no caso da precisão dupla), corresponde ao bit de Sinal. Este bit é igual a 1 se o valor original for negativo. Neste exemplo, este bit (a fundo azul na representação abaixo) fica igual a Zero.

6) Juntanto as parcelas todas, obtém-se a representação de 94.0254 no formato vírgula flutuante com precisão simples de acordo com a Norma IEEE-754:

————————

Resumidamente:

Shutdown button for the Raspberry Pi

shutdown_1
One thing that sometimes bothers me when using an headless embedded Linux system, is the workload I get when I need to power off the system for some hardware maintenance (e.g. adding some sensor, replacing some peripheral, moving the system to another location). Indeed, one cannot just cut the power supply; there is the risk that some files become corrupted. So, the proper way to shutdown a Linux system is to send a command like:

$ shutdown -h now

But to do this, one needs to be “online” with the system, via SSH for example, using another system (computer) that, at that moment, may precisely be OFF… Doh!

So, at the expense of a simple push-button (normally open), a couple of wires and some programming, I implemented a smart(?) way of shutting down my Raspberry Pi, safely, without the need of an extra computer, SSH and other complications.

Connecting the push-button

The push-button is connected to two of the 26 or 40 pins header, depending on the version of the raspberry Pi in use. From those two pins, one is GND and the other may be any free GPIO. Remember that some pins have multiple possible roles (I2C, UART, SPI, etc), so choose wisely. In my case, I plugged the button between pins 14 and 16, respectively GND and GPIO23.

raspi_pinout

Programming

To translate any action on the push-button into a Shutdown command, a script was written in the Pi’popular Python programming language.

In a folder of your choice (e.g., /home/pi), using the terminal command line, enter:

$ nano shutdown_button.py

Then, copy the following code into it and save as usual (CTRL-X + Y + ENTER):

shutdown_2

Testing the script

To test this script, just enter the following command and then press the button once.

$ sudo python shutdown_button.py

If everything is correct, the system should shutdown itself. You must then unplug and replug the power cord to start your system again.

Launching this script automatically after every system power-up

In order to launch this script automatically after every system boot, one must add the following line to the /etc/rc.local file (just before the line with exit 0) as shown in the image hereafter (assuming your script file is in the /home/pi folder):

python /home/pi/shutdown_button.py &

shutdown_3

Final notes

  1. If you prefer to have your Pi to reboot instead of shutting down after pressing the button, in the shutdown_button.py script, in the line containing os.system(“shutdown -h now”), replace the letter ‘h‘ (from halt) by a ‘r‘ (for reboot).
  2. The line stated in the above note is in fact a System Call. So, with this script, you can have your Pi doing “anything you want” after pressing the push-button, just by replacing the command between quotation marks, by another command invoking some application that suit your needs.

Have fun!