boris_r_v Posted December 19, 2011 Share Posted December 19, 2011 На диске, что шел со зверьком не было исходников методов работы со сторожевым таймером, а статическая библиотека, что так же была на диске не линкуется с динамическими по вполне понятным причинам. Поэтому спасибо обществу подсказали пару ссылок, на исходники библиотеку moxalib и документашку к ней: Библиотека Документашка Там есть исходники работы со сторожевиком, используя их написал такую прожку для управления: [root@fc-14 mmu]# cat wdt.c #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #define IOCTL_SWATCHDOG_ENABLE 1 #define IOCTL_SWATCHDOG_DISABLE 2 #define IOCTL_SWATCHDOG_GET 3 #define IOCTL_SWATCHDOG_ACK 4 int wdt_open( const char* _t, unsigned _time ) { int fd = -1; fd = open (_t, O_RDWR ); if ( fd < 0 ) return -1; unsigned tt = _time*1000; if ( ioctl (fd, IOCTL_SWATCHDOG_ENABLE, &tt ) ) return -2; return fd; } void wdt_close(int fd) { ioctl(fd, IOCTL_SWATCHDOG_DISABLE, NULL); close(fd); } /* get the status of a watch dog timer Inputs: <fd> file descriptor respresenting the timer Outputs: <mode> the status <time> the timer Returns: 0 on success, failure otherwise */ int wdt_get_status(int fd, int *mode, unsigned long *time) { int ret; struct { int mode; unsigned long time; } nowset; ret = ioctl(fd, IOCTL_SWATCHDOG_GET, &nowset); *mode = nowset.mode; *time = nowset.time; return ret; } int wdt_refresh(int fd) { return ioctl(fd, IOCTL_SWATCHDOG_ACK, NULL); } int main ( int argc, char** argv ) { unsigned tt = 12; if(argc == 2 ) tt = atol (argv[1]); int wfd = open ("/dev/swtd", tt ); if ( argc == 3 ) return 0; int mode; unsigned long time; while ( wfd > 0 ) { wdt_get_status( wfd, &mode, &time ); printf( " mode=%d, time=%d\n", mode, time ); wdt_refresh ( wfd ); usleep( 50000 ); } } собрал запускаю, без параметров root@Moxa:/var/sd# ./wdt mode=0, time=30000 mode=0, time=30000 mode=0, time=30000 mode=0, time=30000 как видно таймаут установлен на 30 секунд, а я ставил на 12 -первая странность, прерываю программу, в конце специально нету метода закрытия сторожевого таймера, по прошествии минуты зверек не перезагружен если указать с двумя параметрами, wdt 1 1 например, то программа завершиться только открыв таймер и записав в него требуемый интервал. По логике, должны опять таки были перегрузиться, но этого не происходит. Общество, скажите что я делаю не так. Link to comment
MuadDib Posted December 20, 2011 Share Posted December 20, 2011 Я недавно получил возможность поработать с 7112 Plus, поэтому теперь могу ответить на данный вопрос. Упомянутая мной в соседнем топике библиотека без проблем компилируется под plus-версию контроллера. Даже менять имя устройства в функции открытия таймера не нужно (в отличие от случая с uClinux вариантом). Библиотека работает так как и ожидается. Попытаюсь объяснить, что у вас не так 1. Вы переписали функцию wdt_open(), но вызываете не её а стандартную open(). Данная функция не делает запуск таймера вызовом ioctl, следовательно таймер просто не работает. 2. Вы работаете не непосредственно с таймером, а с его драйвером. Когда файловый дескриптор закрывается (а именно это происходит при закрытии приложения, вне зависимости от наличия вызова close() в программе), драйвер, очевидно, прекращает требовать сброс таймера со стороны пользовательского приложения. Судя по тому, что написано в доках, сторожевой таймер работает постоянно и сбрасывается драйвером. Но если пользовательское приложение вызывает wdt_open(), то привилегия сброса передается приложению. Когда приложение так или иначе закрывает дескриптор, операционная система возвращается к старому способу работы с таймером. Во всяком случае, эксперимент это подтверждает. Мне самому такая ситуация не нравится - по идее, при аварийном завершении приложения на необслуживаемой машине должна произойти перезагрузка по сторожевому таймеру, но ее просто не будет. Но что есть, то есть. Link to comment
boris_r_v Posted December 21, 2011 Author Share Posted December 21, 2011 Упс... да по пункту 1 - это епикфайл. поправил все отлично, перезаписывает значение таймера. Если закоментировать строку //wdt_refresh ( wfd ); и запустить прожку без параметров то зверек как и положено перегружается через 12 секунд, ну или около того, время не замерял. все в соответствии с инструкцией. 4. Special Note When you “kill the application with -9” or “kill without option” or “Ctrl+c” the kernel will change to auto ack the sWatchDog. When your application enables the sWatchDog and does not ack, your application may have a logical error, or your application has made a core dump. The kernel will not change to auto ack. This can cause a serious problem, causing your system to reboot again and again. Теперь по поводу реализации самого sWatchDog, вопросы к админам форума, ибо у них есть прямой выход на разработчиков. 1. sWatchDog - надо понимать как сокращение от Soft WatchDog? - это так для общего развития 2. как сделать так чтобы когда приложение будет остановлено ( не важно как, kill, cntl+C, хоть само свалится, например из-за ошибки приводящей к маленькой утечки памяти, и пропущенной при тестировании) watchdog не начал сбрасываться ядром, а перегрузил систему, ибо в такой реализации таймера профита от него не много. 3. И как этот таймер отреагирует на подвисание самого ядра - ребутнет систему или вместе с ядром повиснет. Заранее спасибо за ответы. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now