14.3.2. Watchdog¶
Donanım watchdog’u, diğer her sağlamlaştırma seçiminin üzerinde oturduğu zemindir. Çok uzun süre aksi söylenmediğinde işlemciyi sıfırlayan, küçük ve bağımsız bir zamanlayıcıdır. Kararsız bir sensörde takılan bir betik, zaman aşımını geçerek bloke olan bir ağ çağrısı, yığının bir köşesinde sıkışmış bir bellek ayırıcısı, döngüden kaçan bir istisna – bunların hiçbiri watchdog’u durdurmaz. Zamanlayıcı yine de geri sayar ve kamera yeniden başlar.
Sevk edilen bir ürün için watchdog isteğe bağlı değildir. Watchdog olmadan, yukarıdaki arıza durumlarından herhangi biri, birisi fark edip cihazın gücünü kesip açana kadar kamerayı ölü bırakır. Watchdog ile kamera kendi kendine yeniden açılır ve arızanın tek kanıtı kayıttaki tek bir satırdır.
Ayrıca bakınız
Donanım bölümünün watchdog zamanlayıcısı sayfası, donanım düzeyinde bir watchdog’un ne olduğunu ve machine.WDT API’sinin temellerini ele alır. Bu sayfa, bir üretim dağıtımı için nelerin değiştiğini ele alır.
14.3.2.1. Watchdog’u başlatma¶
machine.WDT, kullanılan API’dir. Donanım destekli olup: bir kez oluşturulduğunda, zamanlayıcı bir sonraki sıfırlamaya kadar çalışır. stop() yoktur, deinit() yoktur, Ctrl-C ile çıkış yoktur. Amaç da budur.
main.py dosyasının başında, koruduğu döngüden hemen önce tipik bir kurulum:
from machine import WDT
wdt = WDT(timeout=10_000) # milliseconds
main.py, watchdog için doğru yerdir çünkü döngünün bulunduğu yer orasıdır. Bir watchdog sıfırlaması bir donanım sıfırlamasıdır, dolayısıyla soğuk önyükleme yolu yeniden çalışır ve main.py döngüye kendi kendine yeniden girer – kurtarma, boot.py içinde herhangi bir bağlantı olmadan çalışır. Watchdog’u bunun yerine boot.py içinde başlatmak, her yazılımsal sıfırlamanın (örneğin bir geliştiricinin Ctrl-D’si) uygulamaya durduramayacağı bir donanım zamanlayıcısı vermesi demektir; bu, tezgahta bir baş ağrısı ve döngü hazır olmadan önce çalışan üretim kurulum kodunda bir tuzaktır.
Zaman aşımını, ana döngünün gözlemlenen en kötü yineleme süresinin 2 ila 3 katı olacak şekilde seçin. Çerçeve hızı titremesi, soğuk bir sensörde yavaş bir sensör okuması, kısa bir Wi-Fi aksaması – bunların hiçbiri watchdog’u tetiklememelidir. Gerçek bir takılma (sonsuz bir döngü, bloke olmuş bir G/Ç çağrısı) tetiklemelidir. Çok kısa zaman aşımları watchdog’u bir yanlış sıfırlama kaynağına dönüştürür; çok uzun zaman aşımları, kurtarma devreye girmeden önce kameranın dakikalarca yanıt vermeden durmasına izin verir.
14.3.2.2. Beslemek¶
wdt.feed() geri sayımı sıfırlar. Bunu ana döngünün her yinelemesinde bir kez, beslemenin takılabilecek herhangi bir işten önce koşulsuz olarak gerçekleşmesi için döngü gövdesinin en üstünde çağırın:
while True:
wdt.feed()
frame = csi0.snapshot()
process(frame)
14.3.2.3. İstisnaları atlatmak¶
Watchdog takılmaları ele alır. İstisnalar farklı bir arıza durumudur. Yakalanmamış bir istisna betiğin en üst düzeyine kadar yükselir, main.py çıkar ve kamera REPL’e düşer. Watchdog daha sonra zaman aşımının ardından tetiklenir çünkü REPL’den onu besleyen hiçbir şey yoktur, kamera sıfırlanır ve main.py yeniden çalışır – yani kurtarma çalışır, ancak saha her çökme için tam bir zaman aşımı artı yeniden başlatma bedeli öder, geri izleme hiçbir şeyin okumadığı USB stdout’a gider ve uygulamanın tuttuğu bellek içi durum kaybolur.
Ana döngüyü en üst düzey bir try / except içine sarmak, bir çökmeyi uygulamanın devam ettiği, kayda alınmış bir olaya dönüştürür ve bir sıfırlama bedeli ödetmez:
import logging
log = logging.getLogger(__name__)
while True:
wdt.feed()
try:
frame = csi0.snapshot()
process(frame)
except Exception:
log.exception("frame loop iteration failed")
BaseException değil Exception yakalamak, KeyboardInterrupt ve SystemExit öğelerinin çalışır durumda kalmasını sağlar; bu da USB üzerinden bağlı bir geliştiricinin istediği şeydir.
Bu desen, canlılığın yazılım yarısıdır: watchdog takılmaları yakalar, sarmalayıcı çökmeleri yakalar ve kayıt, ikisinden herhangi birinin yakaladığını kaydeder.
14.3.2.4. Bir önyüklemenin neden gerçekleştiğini bilmek¶
Her yazılımsal sıfırlama ve her watchdog sıfırlaması, eninde sonunda taze bir önyükleme olarak ortaya çıkar. Önyükleme zamanı tanılama yardımcısı, her soğuk başlangıçta machine.reset_cause() öğesini kaydeder; reset cause satırı, kurtarmanın gerçekten tetiklenip tetiklenmediğini, yoksa kameranın yalnızca normal şekilde güç çevrimi mi yaptığını sahaya söyleyen şeydir.
Reset-cause satırı, watchdog’un işini kayıtta görünür kılan şeydir. watchdog timeout sıfırlamalarıyla dolu bir kayıt, uygulamanın takılıp kaldığını ve watchdog’un onu kurtardığını söyler. Bunlar olmayan bir kayıt ise watchdog’un tetiklenmek zorunda kalmadığını söyler – ki bu genellikle uygulamanın sağlıklı olduğu anlamına gelir, ancak zaman aşımının, gerçekte meydana gelen takılmaları yakalamak için çok uzun ayarlandığı anlamına da gelebilir.
14.3.2.5. Eksiksiz bir başlangıç noktası¶
Watchdog’u, kayıt kurulumunu, önyükleme zamanı tanılamasını ve sarmalayıcıyı bir araya getiren bir main.py şöyle görünür:
import logging
from machine import WDT
from app.logging_setup import setup_logging, log_boot_diagnostics
setup_logging('/sdcard/logs/app.log')
log_boot_diagnostics()
log = logging.getLogger(__name__)
wdt = WDT(timeout=10_000)
while True:
wdt.feed()
try:
step()
except Exception:
log.exception("loop iteration failed")
step() uygulamanın yineleme başına işidir; bu iskeletin geri kalanı ürünler arasında değişmez. Sağlamlaştırma; bir watchdog, bir sarmalayıcı ve her soğuk başlangıçta kayda alınmış bir önyüklemedir – çok fazla kod değil, ama kendi kendine kurtulan bir kamera ile bir servis çağrısına ihtiyaç duyan bir kamera arasındaki fark.