Fråga:
Hur lär sig init känna händelser?
SlySven
2015-12-16 01:41:00 UTC
view on stackexchange narkive permalink

Jag har en Pi Model B Rev 2.0 (tror jag) och jag tänker använda den för ett hemautomationssystem. Eftersom jag har en förskottsmätare på min elförsörjning tar jag ibland slut på elektroner för att gå runt mitt hems nätförsörjning!

För att undvika problem har jag fått en UPS i form av en UPis Basic gjord av PiModules. Jag har konfigurerat det så att jag kan undersöka matningsspänningarna via Pi: s egen seriella port (inte standardkonfigurationen men en inställning som stöds dokumenterad i manualen).

Vid nu använder den en dedikerad GPIO-stift (stift 13 på sidhuvudet, GPIO27 tror jag) och den inbyggda mikrokontrollern använder det och ett python-skript som körs från rc.local för att berätta för Pi att avstängning -h nu när stiftet är lågt - vilket händer när UPS "Avstängning" -knappen trycks ned eller om batteriförsörjningen blir kritiskt låg i händelse av huvudförsörjningsfel. För posten är skriptet:

  #! / Usr / bin / python # importera biblioteken för att använda tidsfördröjningar, skicka OS-kommandon och få tillgång till GPIO pinsimport PRi.GPIO som GPIOimport timeimport osGPIO.setmode (GPIO.BCM) # Ställ in pin-numrering till kortnumreringGPIO.setup (27, GPIO.IN, pull_up_don = GPIO.PUD_UP) # Ställ in pin 27 som inmatning under True: # Ställ in en hel loopto vänta på en knapptryckning om (GPIO.input (27) == 0): # Ställ in en if-loop för att köra ett avstängningskommando när knapptryckningen känns av os.system ("sudo shutdown -h now") # Skicka avstängningskommandot till os pausetid. sömn (1) # Tillåt en vilotid på 1 sekund för att minska CPU-användningen  

Detta är lite oelegant med tanke på att init har inbyggd förmåga att hantera strömhändelser. Jag bör upprepa att jag använder sysVinit på Raspbian Jessie INTE standard systemd för den versionen (av personliga preferenser och kännedom om skäl).

Jag vill till en början ersätta ovanstående skript med något som säger till init att göra sin powerfailnow när stiftet blir lågt - och göra en powerokwait om det återvänder därefter högt. Så småningom vill jag också undersöka den seriella porten och hålla ett öga på svaren på @ rpi , @kat och @ kupor som returnerar den aktuella spänningar på Pi: s 5V-skena, LiPo-batteriet och UPis egen microUsb-ingång respektive - så att Pi kan ge en varning om / hantera ett strömavbrott (det bör resultera i en powerfail init-åtgärd och låt Pi rapportera strömförluststatusen till mig, användaren - förutsatt att jag inte har lagt märke till det!)

Men jag har svårt att ta reda på hur Linux UPS-enheter signalerar till init kod > att powerfail \ powerwait \ powerfailnow \ powerokwait kommandon definierade i \ etc \ inittab kod> bör utföras.

Kan någon till exempel ge mig råd om hur "vuxna" UPS säger till en Linux-kärna på en vanlig dator att "power" -händelser händer och hur jag kan återge samma i detta system på en Pi?

Tack @Jacobm001 för att upptäcka frånvaron av taggen för den Python-ish delen av denna fråga, under de senaste timmarna har jag genomgått en kraschkurs i språket (jag går framåt) men för kort tid sedan skulle jag inte ' Jag har inte känt min Asp från min armbåge ...
Jag är också nyfiken på hur Pi (eller init) vet om krafthändelser. Förhoppningsvis svarar någon snart.
Jag skulle titta på acpid och kanske kan du ändra ditt skript så att det reagerar när något ändras (pin high -> low) istället för att polla värdet varje sekund?
@PandaLion98 Pi-hårdvaran har inga strömhändelser, så det finns inget att veta om dem. Om vissa implementeras, skulle init bara veta om dem om de får veta, antingen av kärnan (på grund av en drivrutinhändelse, som i fallet med pi antagligen skulle vara en drivrutin för ytterligare hårdvara) eller via en användarlandapplikation.
Tre svar:
SlySven
2015-12-16 22:51:32 UTC
view on stackexchange narkive permalink

Ah, ha! Vissa stycken på mansidorna för init (8) hänvisar till avskrivet gränssnitt för att skriva ett värde på en bokstav till / etc / powerstatus (nu ersatt av / var / run / powerstatus ) och sedan skicka init en SIGPWR -signal; bokstaven ska vara en av:

  • ' F ' sjuk sjukdom: [huvudströmmen har misslyckats och] UPS tillhandahåller strömmen, kör powerwait och powerfail poster.
  • Power ' O ' kay: [main] power har återställts, kör posten powerokwait .
  • ' L ' ström: strömmen misslyckas och UPS har ett [kritiskt] lågt batteri, kör posten powerfailnow .
Om den angivna filen inte finns eller innehåller något annat än bokstäverna F , O eller L , kommer init att bete sig som om den har läst bokstaven F.

Under detta är det rådande:

Användning av SIGPWR och / etc / powerstatus är avskräckt. Någon som vill interagera med init bör använda / run / initctl kontrollkanalen - se källkoden för sysvinit -paketet för mer dokumentation om detta .

Så även om detta kan vara ett svar så är det inte svaret - nästa måste jag titta vid källkoden som hålls som ett icke-GNU-projekt som värd på GNU: s webbhotell.

Chad Farmer
2015-12-19 01:31:30 UTC
view on stackexchange narkive permalink

Jag antar att det renaste tillvägagångssättet skulle vara att ha en kärnenhetsdrivrutin som hanterar GPIO27 och ställa in för att få ett avbrott när det blir lågt. Avbrottshanteraren skulle meddela init. Sidan http://elinux.org/RPi_Low-level_peripherals säger att Raspbian Wheezy stöder GPIO-avbrott.

Jag ber om ursäkt för svaret av låg kvalitet, jag har inte tittat på Linux gpio-drivrutiner och hur man utökar / förbättrar dem. Jag har inte heller letat upp den nuvarande godkända metoden för att meddela init från en avbrottshanterare. Förhoppningsvis stimulerar detta inlägg bättre svar.

Ja, ett avbrott verkar bättre än omröstning - Diederik de Haas nämnde det ovan. Fokus för min undersökning för närvarande är dock "Avbrottshanteraren skulle meddela init ..." det är den mekanismen som är förbryllande, "powerstat" -filen / SIGPWR-signalen ser relativt enkel och rak ut men verkar vara föråldrad. Jag försöker ta reda på om användningen av `initctl`-röret i verkligheten ...
SlySven
2017-01-02 01:29:31 UTC
view on stackexchange narkive permalink

Genom att gräva i källkoden för SysV init som är tillgänglig från Free Software Foundations Savannah-server kunde jag skicka förfrågningar till min RPis init kod> genom att fylla i en struct init_request som beskrivs i initreq.h rubrikfilen. Specifikt krävde detta magi , sleeptime och, för mina ändamål, fylls cmd -fälten ut, varvid den senare är inställd på en av > INIT_CMD_POWERFAIL , INIT_CMD_POWERFAILNOW eller INIT_CMD_POWEROK.

Min demon / program som måste köras som användare med tillstånd att skriva till init-kontrollröret {ursprungligen vid / dev / initctrl men flyttade på Debian och därmed kunde Raspbian till / run / initctrl } sedan skicka den strukturen till init som sedan svarade på lämpligt sätt genom att svara på följande poster i /etc/inittab:

  # Vad ska jag göra när strömmen misslyckas / returnerar.pf: : powerwait: /etc/init.d/powerfail startpn :: powerfailnow: /etc/init.d/powerfail nowpo :: powerokwait: /etc/init.d/powerfail stop  

Obs: detta gränssnitt - eller åtminstone meddelandet om strömförsörjning har INTE antagits av det nya snygga systemd - även du gh, av vad som kan betraktas som lite av programmering av lastkult, försöker det att se till att initctrl -röret finns. Å andra sidan gör detta precis vad jag vill att det ska göra på mitt RPi-system!

Medan jag beundrar ditt engagemang för ditt problem, kan jag inte låta bli att lägga märke till att du har lagt mycket tid på att implementera en lösning som är funktionellt motsvarande ditt ursprungliga skript och som inte ens är framtida bevis.
Även om det funktionellt motsvarar det ursprungliga systemet, använder det det rekommenderade gränssnittet snarare än det föråldrade. När det gäller framtida korrektur är det inte upp till personer som skriver det framtida systemet att implementera det ___kända gränssnittet___ för systemet de försöker ersätta för att säkerställa _ bakåtkompatibilitet_ där det är möjligt.
När allt kommer omkring är att få ett meddelande om huvudströmavbrott ganska viktigt för ett system med en UPS, så en halv anständig process / systemansvarig borde vara medveten om hur dess föregångare gjorde saker och se upp för andra processer som använder det API - ett gränssnitt som existerar men ignoreras verkar lite kortsiktig ... 8- / Enligt kod på: https://github.com/systemd/systemd/blob/master/src/initctl/initctl.c alla en UPS som säger `systemd `att huvudströmmen misslyckades på detta sätt kommer att logga meddelande:" Mottagen UPS / power initctl-begäran. Detta implementeras inte i systemd. Uppgradera din UPS-demon! "
"Detta implementeras inte i systemd. Uppgradera din UPS-demon" - det är allt du behöver veta om bakåtkompatibilitet i Linux;)
Gränssnittet `initctl` till van Smoorenburg init [förklarades privat och inte för tredje part] (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=657990#57) av ett av programmets ( sedan) underhållare tillbaka 2012. Miquel van Smoorenburgs "powerd", senare Tom Websters "genpowerd", använde ursprungligen mekanismen "/ etc / powerstatus".
Det inlägget (från Roger Leigh) kommer från en Debian-person - medan uppströms faktiskt nu dokumenterar det på: http://git.savannah.nongnu.org/cgit/sysvinit.git/tree/doc/initctl som innehåller ett avslutande stycke som inkluderar: "* Vanligtvis skulle röret` / run / initctl` endast användas av lågnivåprogram för att begära en strömavstängning eller ändra runlevel, som telinit skulle göra ... * "- med tanke på att min daemon * är * ett lågnivåprogram som kan behöva begära en strömrelaterad avstängning, jag är nöjd med vad jag har producerat ... 8-)


Denna fråga och svar översattes automatiskt från det engelska språket.Det ursprungliga innehållet finns tillgängligt på stackexchange, vilket vi tackar för cc by-sa 3.0-licensen som det distribueras under.
Loading...