2015/11/07
■ Watch Dog Timer
ローダブルモジュールが使えればデバイスドライバorion_wdtを使うのがスマートだが、
ハードウエア直たたきでも問題ないだろう。
このページを参考にしてCで作成してみた。
http://plugcomputer.org/plugforum/index.php?topic=466.0
約21秒でtime upするWatch Dog Timerである。
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <inttypes.h> #include <sys/types.h> #include <sys/io.h> #include <sys/mman.h> typedef uint64_t u64; typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; typedef int64_t s64; typedef int32_t s32; typedef int16_t s16; typedef int8_t s8; main() { #define REG_SIZE 0xfff #define PAGE_SIZE (sysconf(_SC_PAGE_SIZE)) int mem_fd; u8 *preg; mem_fd=open("/dev/mem",O_RDWR|O_CREAT,0666); if ( mem_fd < 0 ) { puts("/dev/mem error."); return 1; } preg=(u8 *)malloc(REG_SIZE+(PAGE_SIZE-1)); // PAGE_SIZEでアラインメント if ( (u32)preg % PAGE_SIZE ) { preg+=(PAGE_SIZE-((u32)preg % PAGE_SIZE)); } preg=(u8 *)mmap((caddr_t)preg,REG_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_FIXED, mem_fd,0xf1020000ul); *(u32 *)(preg+0x0324)=0xfffffffful; // カウンタ値(約21秒) *(u32 *)(preg+0x0300)|=0x10; // WDT enable *(u32 *)(preg+0x0108)=0x2; // WDT start for (;;) { *(u32 *)(preg+0x0324)=0xfffffffful; // カウンタ値リロード puts("WDT clear."); sleep(15); // 15秒毎にWDTクリア } }
これを gcc -O2 -o wdt_dp wdt_dp.c でコンパイルして、
./wdt_dp & と動かせばよい。(root必須)