在关闭前将GPIO引脚拉至最后一个动作

时间:2013-10-14 00:27:50

标签: raspberry-pi gpio halt

我想通过将GPIO引脚拉低10秒来发出断电状态信号。我在/etc/rc.*目录中发现了运行级别。最终“halt”命令运行。

我想编辑并重新编译halt.c文件,但我无法找到它。我有两个问题:

  1. 这是正确的方法吗?
  2. 源代码在哪里? (等待Q1的肯定回答)。
  3. 谢谢。 贾斯汀

2 个答案:

答案 0 :(得分:2)

我没有使用Raspberry Pi,但在大多数系统上停止 poweroff reboot 都是指向同一二进制文件的链接。另一种方法是编写一个程序来做你想做的事情,并使它成为/etc/rc.d/rc0.d中调用的最后一件事。 Runlevel 0是系统关闭时的功能。

答案 1 :(得分:0)

以下是我对此问题的看法' powerctl_pin' https://pastebin.com/BdzGM5TJ

/*
    Raspi3B Power Control Pin Raspbian Jessie
    Bilgus -- 2017 CC-BY-SA 3.0
    Requires WiringPI http://wiringpi.com/

    Compiling:
    gcc -o powerctl_pin powerctl_pin.c -l wiringPi && chmod +x powerctl_pin     && 
    sudo cp powerctl_pin /bin/

    Install:
    sudo /bin/powerctl_pin 21 install

    Uninstall:
    sudo /bin/powerctl_pin 21 uninstall

    Shutdown:
    sudo /bin/powerctl_pin 21 poweroff


    /bin/powerctl_pin Broadcom_pin#, mode
    Valid Modes: poweroff, poweron, install, uninstall
    Works with mosfet latch switch
    https://easyeda.com/Bilgus/New_Project-4ce1316bb1f6402985f8d1c4f196448d
    Original Circuit:
    http://www.mosaic-industries.com/embedded-systems/microcontroller-projects
    /raspberry-pi/on-off-power-controller

* /



/*
        Raspi3B Power Control Pin Raspbian Jessie
        Bilgus -- 2017 CC-BY-SA 3.0
        Requires WiringPI http://wiringpi.com/

        Compiling:
        gcc -o powerctl_pin powerctl_pin.c -l wiringPi && chmod +x powerctl_pin && 
        sudo cp powerctl_pin /bin/

        Install:
        sudo /bin/powerctl_pin 21 install
        
        Uninstall:
        sudo /bin/powerctl_pin 21 uninstall

        Shutdown:
        sudo /bin/powerctl_pin 21 poweroff


        /bin/powerctl_pin Broadcom_pin#, mode
        Valid Modes: poweroff, poweron, install, uninstall
        Works with mosfet latch switch
        https://easyeda.com/Bilgus/New_Project-4ce1316bb1f6402985f8d1c4f196448d
        Original Circuit:
        http://www.mosaic-industries.com/embedded-systems/microcontroller-projects
        /raspberry-pi/on-off-power-controller
*/

#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <signal.h> //sigterm, sigint()
#include "wiringPi.h"
#define WIRINGPI_CODES 999 /* enable error checking on setup */

#define POWEROFF_SVC "PwrCtl_Pin.service"
#define POWEROFF_SVC_PATH "/lib/systemd/system/"POWEROFF_SVC
#define REQUIRES "shutdown.target umount.target final.target poweroff.target"
#define AFTER "shutdown.target umount.target final.target"
#define BEFORE "systemd-poweroff.service"
#define WANTEDBY "poweroff.target"
#define POWERINT_SVC "PwrCtl_Pin-Interrupt.service"
#define POWERINT_SVC_PATH "/lib/systemd/system/"POWERINT_SVC

static void poweroff_ISR_INIT(int pin);
static int g_pin = 0;

        /* enables pullup - unneeded to hold latch */
        static void poweron_pin(int pin)
        {
                pullUpDnControl(pin, PUD_UP);
                pinMode(pin, INPUT);
        }

        /* pulls pin low in short loop to turn power off */
        static void poweroff_pin(int pin)
        {
                pullUpDnControl(pin, PUD_OFF);
                int c;
                for(c=0;c<20;c++)
                {
                        //pinMode(pin, INPUT);
                        //pullUpDnControl(pin, PUD_DOWN);
                        digitalWrite(pin,LOW);
                        pinMode(pin, OUTPUT);
                        digitalWrite(pin,LOW);
                        delay(500);
                }
        }
        
        /* ISR Called when pin goes from high to low debounce checks that still low */
        static void poweroff_ISR(void)
        {
                delay(100);
                if (digitalRead(g_pin) == LOW) /* pin debounce */
                {
                        openlog ("Poweroff ISR", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
                        syslog (LOG_NOTICE, "ISR Triggered - Shutdown -h now");
                        closelog();
                        system("shutdown -h now");
                        exit(0);
                }
                else
                        poweroff_ISR_INIT(g_pin);
        }

        /* signal handler recieves shutdown signals */
        static void signal_handler(int signal_0)
        {
                if (signal_0 == SIGINT || signal_0 == SIGTERM || signal_0 == SIGSTOP)
                exit(0);
        }

        /* Initialize Poweroff ISR handler */
        static void poweroff_ISR_INIT(int pin)
        {
                g_pin = pin;
                pinMode(pin, INPUT);
                pullUpDnControl(pin, PUD_UP);
                wiringPiISR(pin, INT_EDGE_FALLING, &poweroff_ISR);
                while(1)
                {
                        delay(100);
                        ;;
                }
        }

        /* creates service daemons */
        static void install(int pin, char *prog_path)
        {
                FILE *f = fopen(POWEROFF_SVC_PATH, "w");
                if (f == NULL)
                {
                        fprintf(stderr, "Error opening file! %s\n", POWEROFF_SVC_PATH);
                        exit(-6);
                }
                fprintf(f, "# POWER CONTROL PIN SERVICE \n# %s\n\n", prog_path);
                fprintf(f, "[Unit]\nDescription=PowerCtl_Pin pulls GPIO pin %i LOW\n", pin);
                fprintf(f, "DefaultDependencies=no\n");
                fprintf(f, "Requires=%s\n", REQUIRES);
                fprintf(f, "After=%s\nBefore=%s\n\n", AFTER, BEFORE);
                fprintf(f, "[Service]\nType=oneshot\n");
                fprintf(f, "ExecStart=%s %i poweroff\n\n", prog_path, pin);
                fprintf(f, "[Install]\nWantedBy=%s\n\n", WANTEDBY);
                fclose(f);
                printf("Service file created: %s\n", POWEROFF_SVC_PATH);
                system("systemctl enable " POWEROFF_SVC);

                FILE *f1 = fopen(POWERINT_SVC_PATH, "w");
                if (f1 == NULL)
                {
                        fprintf(stderr, "Error opening file! %s\n", POWERINT_SVC_PATH);
                        exit(-7);
                }
                fprintf(f1, "# POWER CONTROL PIN INTERRUPT SERVICE \n");
                fprintf(f1, "# %s\n\n", prog_path);
                fprintf(f1, "[Unit]\nDescription=PowerCtl_Pin Interrupt watches GPIO ");
                fprintf(f1, "for pin %i LOW calls shutdown now\n", pin);
                fprintf(f1, "DefaultDependencies=no\n");
                fprintf(f1, "After=network.target\n\n");
                fprintf(f1, "[Service]\nType=simple\n");
                fprintf(f1, "ExecStart=%s %i interrupt &\n", prog_path, pin);
                fprintf(f1, "TimeoutSec=0\nRestart=always\n\n");
                fprintf(f1, "[Install]\nWantedBy=multi-user.target\n\n");
                fclose(f1);
                printf("\n\rService file created: %s\n", POWERINT_SVC_PATH);
                system("systemctl enable " POWERINT_SVC);
                printf("Attempting to start: %s\n\r", POWERINT_SVC_PATH);
                system("systemctl start " POWERINT_SVC);
        }/*install*/

        /* disables/stops service daemons */
         static void uninstall(int pin, char *prog_path)
        {
                system("systemctl disable " POWEROFF_SVC);
                printf("Service file still exists: %s\n\n", POWEROFF_SVC_PATH);

                system("systemctl stop " POWERINT_SVC);
                system("systemctl disable " POWERINT_SVC);
                printf("Service file still exists: %s\n", POWERINT_SVC_PATH);
        }


        int main(int argc, char **argv)
        {
                int pin = 0;
                if (geteuid() != 0)
                {
                        fprintf (stderr, "You need to be root to run this program. (sudo?)\n") ;
                        exit(-1);
                }
                putenv("WIRINGPI_CODES=WhOkNoWs??");
                if (wiringPiSetupGpio() != 0) /* change to wiringPiSetup() for WiringPi Pins*/
                {
                        fprintf(stderr, "wiringPiSetup error\n");
                        exit(-2);
                }

                if(argc < 3)
                {
                        fprintf (stderr, "not enough args poweroff_pin(brcm_pin# mode)\n") ;
                        fprintf (stderr, "Valid Mode [power[off/on], interrupt, install, uninstall]])\n") ;
                        exit(-3);
                }
                else if (sscanf (argv[1],"%i", &pin) != 1)
                {
                        fprintf (stderr, "invalid pin number,  poweroff_pin(brcm_pin# mode) ");
                        fprintf (stderr, "Valid Mode [power[off/on], interrupt, install, uninstall]])\n") ;
                        exit(-4);
                }
                else if(strncmp(argv[2],"interrupt",10) == 0)
                {
                        openlog (argv[0], LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
                        syslog (LOG_NOTICE, "%s - interrupt mode pin = %s", argv[0], argv[1]);
                        closelog();

                        if (signal(SIGINT, signal_handler) == SIG_ERR)
                        {
                                fprintf(stderr, "Unable to register signal handler\n");
                                exit(-5);
                        }
                        poweroff_ISR_INIT(pin);
                }
                else if(strncmp(argv[2],"poweroff",10) == 0)
                {
                        poweroff_pin(pin);
                }
                else if(strncmp(argv[2],"install",10) == 0)
                {
                        openlog (argv[0], LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
                        syslog (LOG_NOTICE, "%s - install pin = %s", argv[0], argv[1]);
                        closelog();
                        install(pin, argv[0]);
                }
                else if(strncmp(argv[2],"uninstall",10) == 0)
                {
                        openlog (argv[0], LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
                        syslog (LOG_NOTICE, "%s - uninstall pin = %s", argv[0], argv[1]);
                        closelog();
                        uninstall(pin, argv[0]);
                }
                else
                {
                        poweron_pin(pin);
                }
        return 0;
        }/*main*/
&#13;
&#13;
&#13;