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. |