The Axis device senses the power supply power good signal, this is exported by the driver into user space via the /proc/axis_00/inputs/power_good entry in the /proc file system.
Once a power failure has been detected a 12 bit millisecond timer is started in the Axis hardware, this can be read via the /proc/axis_00/power_fail_timer.
While the system will report power failures the holdup time between the power supply detecting an external failure and the system finally dying will depend on both the system load and the power supply used.
The changes to the power_good line will trigger interrupts which the kernel driver handles in one of two user selectable ways. Firstly it keeps a track of any processes that have the character device 231,160 (use mknod /dev/axis_0/power_fail -m666 c 231 160 to create an file system entry) open. All the programs on this list will receive a SIGPWR. It should be noted that the kernels default behaviour for an unhandled SIGPWR signal is to terminate the application so applications that request a SIGPWR signal should make preperations to handle the signal. Alternatively the driver can be instructed to issue a single signal to init (pid =1 ). Init will then process the power failure according to the /etc/powerstatus file and the powerfail entries in /etc/inittab.
This behaviour is controlled by a single entry in /proc/axis_00. If the global_power_fail entry returns zero then Axis drivers will only issue SIGPWR signals to applications that have opened /dev/axis_0/power_fail. This is the default setting.
The command:
echo -n 1 > /proc/axis_00/global_power_fail
Will change the behaviour so the driver will issue a SIGPWR to init.
#include <STDIO.H>
#include <SIGNAL.H>
#include <SYS/TYPES.H>
#include <SYS/STAT.H>
#include <FCNTL.H>
#include <UNISTD.H>
volatile int power_fail= 0;
static void power_fail_handler(int sig_number)
{
if (sig_number==SIGPWR)
power_fail =1 ;
}
int main(int argc ,char ** argv)
{
int handle ;
struct sigaction power_fail_handler_signal ;
memset(&power_fail_handler_signal,0,sizeof(power_fail_handler_signal));
power_fail_handler_signal.sa_handler = power_fail_handler ;
sigaction(SIGPWR,&power_fail_handler_signal,NULL);
handle = open("/dev/axis_0/power_fail",O_RDONLY);
if (handle)
{
while (!power_fail)
{
usleep(1000);
}
}
close(handle);
printf("Exited after signal\n");
return 0 ;
}