LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   LInux crashes on RTC Alarm Interrupt (https://www.linuxquestions.org/questions/programming-9/linux-crashes-on-rtc-alarm-interrupt-4175437827/)

asad_asrar 11-19-2012 01:30 PM

LInux crashes on RTC Alarm Interrupt
 
Hi,
I am using Linux Kernel 2.6 on AT91SAM9XE. I was able to successfully load the driver for SPI based RTC DS1305 on SPI0 CS0.
I am albe to read time from RTC using this RTC test application.

/*
* Real Time Clock Driver Test/Example Program
*
* Compile with:
* gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
*
* Copyright (C) 1996, Paul Gortmaker.
*
* Released under the GNU General Public License, version 2,
* included herein by reference.
*
*/

#include <stdio.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>


/*
* This expects the new RTC class driver framework, working with
* clocks that will often not be clones of what the PC-AT had.
* Use the command line to specify another RTC if you need one.
*/
static const char default_rtc[] = "/dev/rtc0";


int main(int argc, char **argv)
{
int i, fd, retval, irqcount = 0;
unsigned long tmp, data;
struct rtc_time rtc_tm;
const char *rtc = default_rtc;
printf("\n**Main Entered**\n");
switch (argc) {
case 2:
rtc = argv[1];
/* FALLTHROUGH */
case 1:
break;
default:
fprintf(stderr, "usage: rtctest [rtcdev]\n");
return 1;
}

fd = open(rtc, O_RDONLY);

if (fd == -1) {
perror(rtc);
exit(errno);
}

fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n");

/* Turn on update interrupts (one per second) */
goto test_READ;
retval = ioctl(fd, RTC_UIE_ON, 0);
if (retval == -1) {
if (errno == ENOTTY) {
fprintf(stderr,
"\n...Update IRQs not supported.\n");
goto test_READ;
}
perror("RTC_UIE_ON ioctl");
exit(errno);
}

fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:",
rtc);
fflush(stderr);
for (i=1; i<6; i++) {
/* This read will block */
retval = read(fd, &data, sizeof(unsigned long));
if (retval == -1) {
perror("read");
exit(errno);
}
fprintf(stderr, " %d",i);
fflush(stderr);
irqcount++;
}

fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:");
fflush(stderr);
for (i=1; i<6; i++) {
struct timeval tv = {5, 0}; /* 5 second timeout on select */
fd_set readfds;

FD_ZERO(&readfds);
FD_SET(fd, &readfds);
/* The select will wait until an RTC interrupt happens. */
retval = select(fd+1, &readfds, NULL, NULL, &tv);
if (retval == -1) {
perror("select");
exit(errno);
}
/* This read won't block unlike the select-less case above. */
retval = read(fd, &data, sizeof(unsigned long));
if (retval == -1) {
perror("read");
exit(errno);
}
fprintf(stderr, " %d",i);
fflush(stderr);
irqcount++;
}

/* Turn off update interrupts */
retval = ioctl(fd, RTC_UIE_OFF, 0);
if (retval == -1) {
perror("RTC_UIE_OFF ioctl");
exit(errno);
}

test_READ:
/* Read the RTC time/date */
printf("\n**Jumped**\n");
retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
if (retval == -1) {
perror("RTC_RD_TIME ioctl");
exit(errno);
}

fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);

/* Set the alarm to 5 sec in the future, and check for rollover */
rtc_tm.tm_sec += 5;
if (rtc_tm.tm_sec >= 60) {
rtc_tm.tm_sec %= 60;
rtc_tm.tm_min++;
}
if (rtc_tm.tm_min == 60) {
rtc_tm.tm_min = 0;
rtc_tm.tm_hour++;
}
if (rtc_tm.tm_hour == 24)
rtc_tm.tm_hour = 0;

retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
if (retval == -1) {
if (errno == ENOTTY) {
fprintf(stderr,
"\n...Alarm IRQs not supported.\n");
goto test_PIE;
}
perror("RTC_ALM_SET ioctl");
exit(errno);
}

/* Read the current alarm settings */
retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
if (retval == -1) {
perror("RTC_ALM_READ ioctl");
exit(errno);
}

fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n",
rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);

/* Enable alarm interrupts */
retval = ioctl(fd, RTC_AIE_ON, 0);
if (retval == -1) {
perror("RTC_AIE_ON ioctl");
exit(errno);
}

fprintf(stderr, "Waiting 5 seconds for alarm...");
fflush(stderr);
/* This blocks until the alarm ring causes an interrupt */

retval = read(fd, &data, sizeof(unsigned long));
if (retval == -1) {
perror("read");
exit(errno);
}
irqcount++;
fprintf(stderr, " okay. Alarm rang.\n");

/* Disable alarm interrupts */
retval = ioctl(fd, RTC_AIE_OFF, 0);
if (retval == -1) {
perror("RTC_AIE_OFF ioctl");
exit(errno);
}

test_PIE:
/* Read periodic IRQ rate */
retval = ioctl(fd, RTC_IRQP_READ, &tmp);
if (retval == -1) {
/* not all RTCs support periodic IRQs */
if (errno == ENOTTY) {
fprintf(stderr, "\nNo periodic IRQ support\n");
goto done;
}
perror("RTC_IRQP_READ ioctl");
exit(errno);
}
fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp);

fprintf(stderr, "Counting 20 interrupts at:");
fflush(stderr);

/* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
for (tmp=2; tmp<=64; tmp*=2) {

retval = ioctl(fd, RTC_IRQP_SET, tmp);
if (retval == -1) {
/* not all RTCs can change their periodic IRQ rate */
if (errno == ENOTTY) {
fprintf(stderr,
"\n...Periodic IRQ rate is fixed\n");
goto done;
}
perror("RTC_IRQP_SET ioctl");
exit(errno);
}

fprintf(stderr, "\n%ldHz:\t", tmp);
fflush(stderr);

/* Enable periodic interrupts */
retval = ioctl(fd, RTC_PIE_ON, 0);
if (retval == -1) {
perror("RTC_PIE_ON ioctl");
exit(errno);
}

for (i=1; i<21; i++) {
/* This blocks */
retval = read(fd, &data, sizeof(unsigned long));
if (retval == -1) {
perror("read");
exit(errno);
}
fprintf(stderr, " %d",i);
fflush(stderr);
irqcount++;
}

/* Disable periodic interrupts */
retval = ioctl(fd, RTC_PIE_OFF, 0);
if (retval == -1) {
perror("RTC_PIE_OFF ioctl");
exit(errno);
}
}

done:
fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");

close(fd);

return 0;
}

but when ever a RTC alarm interrupt is triggerred Linux crashes with following messages

# cat /proc/interrupts
CPU0
1: 3612 AIC at91_tick, ttyS0
12: 8 AIC atmel_spi.0
21: 1 AIC eth0
63: 1 GPIO rtc0
Err: 0

**Main Entered**

RTC Driver Test Example.


**Jumped**


Current RTC date/time is 1-1-2000, 04:45:11.
Alarm time now set to 04:45:16.
Waiting 5 seconds for alarm...BUG: soft lockup - CPU#0 stuck for 61s! [swapper:0]
Modules linked in:

Pid: 0, comm: swapper
CPU: 0 Not tainted (2.6.30.4-uc0 #203)
PC is at synchronize_irq+0x20/0xd0
LR is at synchronize_irq+0x14/0xd0
pc : [<c005e8dc>] lr : [<c005e8d0>] psr: 00000013
sp : c0293e68 ip : c0293e68 fp : c0293e9c
r10: 00000002 r9 : c0299d30 r8 : fefff400
r7 : 0000003f r6 : c029b040 r5 : 0000003f r4 : c029b040
r3 : 00020300 r2 : 00000050 r1 : 0000003f r0 : c029b040
Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 0005317f Table: 209fc000 DAC: 00000017
[<c00232c4>] (show_regs+0x0/0x50) from [<c005d658>] (softlockup_tick+0x10c/0x150)
r5:0000007e r4:00000041
[<c005d54c>] (softlockup_tick+0x0/0x150) from [<c0043bdc>] (run_local_timers+0x1c/0x20)
r8:c02969d8 r7:00000001 r6:00000000 r5:c0295000 r4:00000000
[<c0043bc0>] (run_local_timers+0x0/0x20) from [<c0043c10>] (update_process_times+0x30/0x60)
[<c0043be0>] (update_process_times+0x0/0x60) from [<c00568a8>] (tick_periodic+0xa4/0xc0)
r5:00000000 r4:00000001
[<c0056804>] (tick_periodic+0x0/0xc0) from [<c00568e0>] (tick_handle_periodic+0x1c/0xfc)
[<c00568c4>] (tick_handle_periodic+0x0/0xfc) from [<c002c67c>] (at91sam926x_pit_interrupt+0x54/0x74)
r8:fefff400 r7:00000001 r6:00000000 r5:00000000 r4:00000001
[<c002c628>] (at91sam926x_pit_interrupt+0x0/0x74) from [<c005deac>] (handle_IRQ_event+0x44/0x114)
r5:00000000 r4:c0296a98
[<c005de68>] (handle_IRQ_event+0x0/0x114) from [<c005f7d4>] (handle_level_irq+0x90/0xe4)
r7:0000003f r6:00000001 r5:00000001 r4:c0299ce0
[<c005f744>] (handle_level_irq+0x0/0xe4) from [<c0021054>] (_text+0x54/0x78)
r5:c0293f50 r4:00000001
[<c0021000>] (_text+0x0/0x78) from [<c0021a34>] (__irq_svc+0x34/0x60)
Exception stack(0xc0293e20 to 0xc0293e68)
3e20: c029b040 0000003f 00000050 00020300 c029b040 0000003f c029b040 0000003f
3e40: fefff400 c0299d30 00000002 c0293e9c c0293e68 c0293e68 c005e8d0 c005e8dc
3e60: 00000013 ffffffff
r5:fefff000 r4:ffffffff
[<c005e8bc>] (synchronize_irq+0x0/0xd0) from [<c005eb6c>] (disable_irq+0x38/0x3c)
r6:00000000 r5:0000003f r4:c029b040
[<c005eb34>] (disable_irq+0x0/0x3c) from [<c0186bb8>] (ds1305_irq+0x14/0x24)
r5:00000000 r4:c0a098e0
[<c0186ba4>] (ds1305_irq+0x0/0x24) from [<c005deac>] (handle_IRQ_event+0x44/0x114)
r5:00000000 r4:c1c54720
[<c005de68>] (handle_IRQ_event+0x0/0x114) from [<c005f884>] (handle_simple_irq+0x5c/0x90)
r7:c02961a0 r6:c029b040 r5:0000003f r4:c029b040
[<c005f828>] (handle_simple_irq+0x0/0x90) from [<c002c0b4>] (gpio_irq_handler+0x9c/0xc8)
r5:00000001 r4:0000003f
[<c002c018>] (gpio_irq_handler+0x0/0xc8) from [<c0021054>] (_text+0x54/0x78)
[<c0021000>] (_text+0x0/0x78) from [<c0021a34>] (__irq_svc+0x34/0x60)
Exception stack(0xc0293f50 to 0xc0293f98)
3f40: 00000000 0005317f 0005217f 60000013
3f60: c0023370 c0292000 c001eee8 c0295c68 2001cea0 41069265 2001ce6c c0293fa4
3f80: 600000d3 c0293f98 c00233b8 c00233c4 60000013 ffffffff
r5:fefff000 r4:ffffffff
[<c0023370>] (default_idle+0x0/0x5c) from [<c0023354>] (cpu_idle+0x40/0x5c)
[<c0023314>] (cpu_idle+0x0/0x5c) from [<c01e55e8>] (rest_init+0x5c/0x70)
r5:c02a9540 r4:c02b0c7c
[<c01e558c>] (rest_init+0x0/0x70) from [<c0008ae8>] (start_kernel+0x248/0x298)
[<c00088a0>] (start_kernel+0x0/0x298) from [<20008034>] (0x20008034)
r5:c02a95ec r4:00053175

Can any please help what is the issue as I am stuck here...


All times are GMT -5. The time now is 07:12 PM.