Jump to content
Форум по продукции MOXA

Recommended Posts

На диске, что шел со зверьком не было исходников методов работы со сторожевым таймером, а статическая библиотека, что так же была на диске не линкуется с динамическими по вполне понятным причинам. Поэтому спасибо обществу подсказали пару ссылок, на исходники библиотеку 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

Я недавно получил возможность поработать с 7112 Plus, поэтому теперь могу ответить на данный вопрос.

 

Упомянутая мной в соседнем топике библиотека без проблем компилируется под plus-версию контроллера. Даже менять имя устройства в функции открытия таймера не нужно (в отличие от случая с uClinux вариантом). Библиотека работает так как и ожидается. Попытаюсь объяснить, что у вас не так

 

1. Вы переписали функцию wdt_open(), но вызываете не её а стандартную open(). Данная функция не делает запуск таймера вызовом ioctl, следовательно таймер просто не работает.

 

2. Вы работаете не непосредственно с таймером, а с его драйвером. Когда файловый дескриптор закрывается (а именно это происходит при закрытии приложения, вне зависимости от наличия вызова close() в программе), драйвер, очевидно, прекращает требовать сброс таймера со стороны пользовательского приложения.

 

Судя по тому, что написано в доках, сторожевой таймер работает постоянно и сбрасывается драйвером. Но если пользовательское приложение вызывает wdt_open(), то привилегия сброса передается приложению. Когда приложение так или иначе закрывает дескриптор, операционная система возвращается к старому способу работы с таймером. Во всяком случае, эксперимент это подтверждает.

 

Мне самому такая ситуация не нравится - по идее, при аварийном завершении приложения на необслуживаемой машине должна произойти перезагрузка по сторожевому таймеру, но ее просто не будет. Но что есть, то есть. :(

Link to comment

Упс... да по пункту 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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...