Bogusław Kempny

Zamykanie systemu

×
Autor English
Początek HC-SR04 LCD Kamera fork() sms strfry() GPIO impulsy Klawiatura Brama GPIO PWM SG90 RFID Grafolog RCP Shutdown Temperatura ....











Raspberry to wspaniały komputerek, czasami jednak brakuje możliwości łatwego zamknięcia systemu operacyjnego.
Nie zawsze mamy możliwość zalogowania się np. przez ssh i wydania komendy shutdown czy podobnej.
Pozostaje brutalne wyłączenie zasilania.

Pomocnym może być rozwiązanie, które zastosowałem w naszym systemie MiniRCP,

Centralnie umieszczony przycisk służy do przełączania pomiędzy rejestracją wejścia i wyjścia, jeśli jednak przytrzymamy go dłużej, przez 5 sekund (jak na załączonym wyżej filmiku), rozpocznie się procedura zamykania systemu.
Zakończone zostaną ważne dla nas procesy (w tym przypadku proces rejestrujący wejścia, badający trzeźwość pracowników, otwierający drzwi), rozpocznie się zamykanie systemu operacyjnego, a po 10 sekundach wyłączone zostanie podświetlenie wyświetlacza.

Nie zostanie niestety wyłączone zasilanie, wymagałoby to dodatkowego hardware, jednak poprawne zamknięcie systemu operacyjnego to już cenna rzecz.

Program, reset.c skompilować musimy z biblioteką WiringPI, a więc:

cc reset.c -o reset  -lwiringPi

Wyświetlacz tym razem został podłączony przez magistralę I2C, inaczej niż opisałem w LCD .

Dzięki niewielkiemu, niedrogiemu modułowi HW-061

zamiast 8 przewodów łączących wyświetlacz z Raspberry, potrzebujemy tylko 4 (w tym zasilanie i masę).
Nasz wyświetlacz staje się też znacznie odporniejszy na zakłócenia.

Jak taki wyświetlacz podłączyć przez magistralę I2C, opiszę w najbliższym czasie, na razie, dla zrozumienia działania oprogramowania, proponuję zerknąć na schemat rejestratora MiniRCP.

No to teraz, jak to działa.

Nie będziemy omawiać procedur sterowania wyświetlaczem przez I2C, to przy innej okazji, skupimy się jedynie na głównej procedurze zamykanie systemu operacyjnego:


Ten pin wyłącznikiem astabilnym łączymy z pinem GND Raspberry:

#define WEWY 25 // connect reset switch to this pin and GND
Będziemy maskować sygnały, więc potrzebna będzie ich maska:
static sigset_t   signal_mask;  /* signals to block         */
void main (argc, argv)
int argc;
char *argv[];
{

.......
Inicjujemy wiringPi, pin WEWY programujemy na wejście i wymuszamy na nim jedynkę logiczną aktywując rezystor 'pull-up':

// check wiringPi setup
if (wiringPiSetup() == -1)
  {
        printf("wiringPi-Error\n");
    exit(1);
  }

// set reset pin to input, activate pull-up resistor
pinMode (WEWY , INPUT) ;
pullUpDnControl(WEWY, PUD_UP);

Teraz w nieskończonej pętli co 200 milisekund sprawdzamy stan pinu WEWY. Jeśli naciśniemy wyłącznik, pojawi się na nim zero logiczne.

int state;
int count;


while (TRUE)
  {
   state=digitalRead(WEWY);
Sprawdzamy, czy wyłącznik był naciśnięty przez 6 sekund (30 x 200 mS):
   if (state == 0) // WEWY pin connected to GND
    {
     for(count=30;count>0;count--)  //WEWY pin connected to GND for 5 seconds
      {
       state=digitalRead(WEWY);
       if(state == 1) break;
       Delay_ms(200);
      }
Tu znajdziemy się po 6 sekundach nieprzerwanie naciśniętego wyłącznika:
     if (state == 0)
      {
Kończymy pracę procesu (lub kilku procesów), które chcemy poprawnie zakończyć:
       system("killall pomiar");  // terminate a process
       sleep(1);
Inicjujemy współpracę z wyświetlaczem po I2C i wyświetlamy komunikat o zamykaniu systemu:
//**** initiate LCD Display
    fdlcd = wiringPiI2CSetup(I2C_ADDR);
    lcd_init(); // setup LCD
    lcdLoc (0, 0) ; // set cursor at line 0, column 0
    typeln ("Closing the system") ; // display some info on LCD
Teraz maskujemy sygnały, żeby system operacyjny nie zakończył naszego procesu przedwcześnie:
//*****  mask signals to avoid premature closure of our process

    sigemptyset (&signal_mask);
    sigaddset (&signal_mask, SIGINT);
    sigaddset (&signal_mask, SIGTERM);
    sigaddset (&signal_mask, SIGHUP);
    sigprocmask(SIG_BLOCK, &signal_mask, NULL);
Czekamy 900 milisekund (to nie jest potrzebne) i rozpoczynamy zamykanie systemu:

    Delay_ms(900);
    system("shutdown -h now"); // begin shutdown procedure
Po 10 sekundach (w praktyce zwykle wystarczy krótszy czas, około 6 sekund) wyłączamy podświetlenie wyświetlacza LCD i kończymy nasz proces. Można wyłączyć zasilanie Raspberry:
//**** wait 10 seconds
    sleep_time = 10;
    while (sleep_time > 0)
      sleep_time = sleep (sleep_time);
// *** turn off LCD backlight
    lcd_backlight = 0x00;
    typeln (" ") ;
    exit(0);