Jump to content


Photo

System hangs with SWIRQ

SWIRQ ubuntu14

  • Please log in to reply
58 replies to this topic

#1 LIndigo

LIndigo

    Member

  • Members
  • PipPip
  • 17 posts

Posted 05 May 2015 - 12:44 PM

Hi,

 

I want to use the PCDuino as a tachometer (RPM counter) and it all works nicely except for an annoying glitch every now and then:

the pcduino completely freezes at random moments while using SWIRQ. I have simplified the code of the interrupt handler to the maximum, but nevertheless, the system will freeze after some time. The only way to start the pcDuino is pushing the reset button on the board. (or unplug power...)

 

My test environment is the following: I attached an AC motor via a rectifier (keeping only the positive signal pulses) to the PCDuino. The motor runs at a speed of 250-500 RPM, meaning between 200 and 450 irq pulses / sec.

 

I included below a minimal code sample (a single main.cpp file) that demonstrates the issue: it seems to work but eventually will freeze the machine. The code for IRQ handling comes from the arduinolibs. Note: I had to wait for >64000 pulses before the machine froze.)

 

any help is appreciated - This is the one feature I still miss to complete this project.

 

regards.

 

here the code sample:

#include <QCoreApplication>
#include <inttypes.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/time.h>

static const char *swirq_dev = "/dev/swirq";

#define SWIRQ_START     (0x201)
#define SWIRQ_STOP      (0x202)
#define SWIRQ_SETPID    (0x203)
#define SWIRQ_ENABLE    (0x204)
#define SWIRQ_DISABLE   (0x205)

typedef struct tagSwirq_Config {
    uint8_t channel;
    int mode;
    int pid;
} SWIrq_Config,*pSWIrq_Config;


void pabort(const char *s)
{
    perror(s);
    abort();
}

void attachInterrupt(void (*userFunc)(int))
{
   uint8_t interruptNum = 0;
   int ret = -1, fd = -1;
   int hwmode = 0, pid = 0;  // hwmode 0 means RISING
   SWIrq_Config irqconfig;

   if(userFunc) {
      signal(SIGUSR1, (void (*) (int))userFunc);

      pid = getpid();
      irqconfig.channel = interruptNum;
      irqconfig.mode = hwmode;
      irqconfig.pid = pid;

      fd = open(swirq_dev, O_RDONLY);
      if ( fd < 0 )
         pabort("open swirq device fail");

      ret = ioctl(fd, SWIRQ_STOP, &interruptNum);
      if (ret < 0)
         pabort("can't set SWIRQ_STOP");
      ret = ioctl(fd, SWIRQ_SETPID, &irqconfig);
      if (ret < 0)
         pabort("can't set SWIRQ_SETPID");
      ret = ioctl(fd, SWIRQ_START, &interruptNum);
      if (ret < 0)
         pabort("can't set SWIRQ_START");
      ret = ioctl(fd, SWIRQ_ENABLE, &interruptNum);
      if (ret < 0)
         pabort("can't set interrupt0 SWIRQ_ENABLE");


      printf("ch:%d, mode:%d, pid:%d \r\n", irqconfig.channel, irqconfig.mode, irqconfig.pid);
      if (fd)
         close(fd);
   }
}

void detachInterrupt()
{
    uint8_t interruptNum = 0;

    int fd = open(swirq_dev, O_RDONLY);
    if ( fd < 0 )
       pabort("open swirq device fail");

    int ret = ioctl(fd, SWIRQ_STOP, &interruptNum);
    if (ret < 0)
       pabort("can't set SWIRQ_STOP");
    ret = ioctl(fd, SWIRQ_DISABLE, &interruptNum);
    if (ret < 0)
       pabort("can't set interrupt0 SWIRQ_DISABLE");

    if (fd)
       close(fd);
}

int counter = 0;

void irq_handler(int) {
    counter++;
}

int main(int argc, char *argv[])
{
//    QCoreApplication a(argc, argv);

    attachInterrupt(irq_handler);
    time_t start = time(NULL);
    while ((time(NULL) - start) < 30*60) {
        printf("Counted: %d\n", counter);
        sleep(1);
    }
    detachInterrupt();
    //    return a.exec();
}

 



#2 LIndigo

LIndigo

    Member

  • Members
  • PipPip
  • 17 posts

Posted 05 May 2015 - 12:56 PM

Note: I did find reports on PCDuino freezing at very high IRQ frequencies but I am working with frequencies less than 500 hz.

Failing to count correctly (e.g. skipping some pulses) would also be a much less problematic behaviour than a full system freeze.



#3 cwilt

cwilt

    Advanced Member

  • Members
  • PipPipPip
  • 1,012 posts

Posted 05 May 2015 - 07:08 PM

You are doing this with android OS?

 

Looks like QT developer?

 

Does it happen at approximately the same number of counts?

 

Anything else running in the background?



#4 LIndigo

LIndigo

    Member

  • Members
  • PipPip
  • 17 posts

Posted 06 May 2015 - 06:38 AM

I am working with ubuntu 14, I use the QT IDE, but the example does not contain anything QT specific.

It's very unpredictable when it happens - I ran some trials where it freezes within 2 minutes, sometimes it runs nice for about 15 mins and then freezes.

I tried something extra yesterday - which was to introduce pauzes in the counting: I counted in block of 1000 and pauzed for 2 sec after each block.

In 1 trial it counted to ~200 000 before freezing.

 

Since it is this random, both with higher and lower frequencies (200-500 pulses / sec) I would guess the issue is related to the moment at which an IRQ occurs (with respect to other software/drivers, ....) and the more often this SWIRQ happens, the higher the chance that this bad timing occurs.



#5 LIndigo

LIndigo

    Member

  • Members
  • PipPip
  • 17 posts

Posted 06 May 2015 - 06:57 AM

To answer your last question: I did not run any other process - but I did not stop any processes or drivers either.

 

If I examine the syslog, it always ends with a huge list of entries reporting the SWIRQ, nothing else. e.g.

 

May 5 19:03:55 linaro-alip kernel: [ 1671.269175] sw_keypad_irq status = 0x00000000

May 5 19:03:55 linaro-alip kernel: [ 1671.270175] sw_keypad_irq status = 0x00000000

...

The last line of these messages is typically incomplete and continue with the first event report after the reset of the system (in bold)

May 5 19:03:55 linaro-alip kernel: [ 1671.270875] sw_keypad_irqMay 5 19:03:55 linaro-alip rsyslogd: [origin software="rsyslogd" swVersion="7.4.4 .......



#6 cwilt

cwilt

    Advanced Member

  • Members
  • PipPipPip
  • 1,012 posts

Posted 06 May 2015 - 11:04 AM

A few more questions....

 

What is the input voltage from your motor and rectifier combination? Does it exceed 3v3?

 

Have you tried this with one of the ubuntu releases? 



#7 LIndigo

LIndigo

    Member

  • Members
  • PipPip
  • 17 posts

Posted 06 May 2015 - 11:10 AM

Hi, the voltage should remain below 3.3 but I do not have the hardware to check if a short peak could go higher. I am looking for an oscilloscoop to measure this out to get absolute certainty.

 

As mentioned I am using Ubuntu 14.



#8 cwilt

cwilt

    Advanced Member

  • Members
  • PipPipPip
  • 1,012 posts

Posted 06 May 2015 - 04:04 PM

Hi, the voltage should remain below 3.3 but I do not have the hardware to check if a short peak could go higher. I am looking for an oscilloscoop to measure this out to get absolute certainty.

 

As mentioned I am using Ubuntu 14.

 

I am moving this to the Ubuntu discussion area.



#9 harthenry

harthenry

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts

Posted 30 July 2015 - 01:44 PM

Hi Cwilt:

 

I too seem to be having this same issue (ie: pcDuino hangs on interrupts).  I have a square wave generator running at 50 hz (50 pulses per sec), and the system runs great for about 5 minutes and then poops out.

 

I found a couple of things and if you read this, can you tell me if/did you move this discussion somewhere else.  I would like to post my findings on this effort.

 

Thanks,

HH



#10 LIndigo

LIndigo

    Member

  • Members
  • PipPip
  • 17 posts

Posted 30 July 2015 - 04:25 PM

Hi harthenry,

 

This is now on the Ubuntu area. The status for me is the following: I switched to a 32 bit arduino (due)  for IRQ handling, but note that not all models support it well. For control functions I am still using the PCDuino - this split of responsibilities was in fact a very handy design change for me. An alternative could be to perform polling in function of what frequencies you need to be able to detect.

 

regards,

 

LIndigo



#11 harthenry

harthenry

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts

Posted 30 July 2015 - 05:59 PM

Lindigo:

 

You mentioned this is now on the Ubuntu area.... Do you happen to have an URL?

 

One thing I noticed with my test was with respect to heat.  When my CPU warmed up, It would run for less than 5 minutes.  I placed the pcDuino into an environmental test chamber, and took the temperature down to about 5 Degrees C (40 F).  The unit ran an hour before I shut the system down.  (perhaps coincidence????)

 

I would like to look at the "Ubuntu" area if you have an URL for that info.

 

FYI: the purpose of the interrupt is the Timer Interrupt is not as accurate as the hardware interrupts, and I need a good 50 HZ ISR.

 

Thanks,

HH



#12 cwilt

cwilt

    Advanced Member

  • Members
  • PipPipPip
  • 1,012 posts

Posted 30 July 2015 - 08:07 PM

Accurate timing will always be an issue when an OS is involved. Some RTC chips can provide adjustable output. May be worth a look.

#13 LIndigo

LIndigo

    Member

  • Members
  • PipPip
  • 17 posts

Posted 30 July 2015 - 08:16 PM

the general Ubuntu link:

 

http://forum.linkspr...orum/79-ubuntu/

 

I agree that for accuracy an OS based (except for real time operating systems) is not ideal. What kind of an accuracy do you need ?



#14 harthenry

harthenry

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts

Posted 30 July 2015 - 08:46 PM

I would prefer < 1ms.  Perhaps 500 micro(s).  My testing is the software interrupt is only good +/- 2 mSec. (contingent on what is happening in the ISR).  The issue I have found is the software ISR is accumulative.  If you start with the interrupt running every 20 mSec (and it slips), the timer restarts its "timer" after the Interrupt ISR is complete.  Therefore, you never catch back up to where you should be, you will always be off.

 

thanks for the URL



#15 cwilt

cwilt

    Advanced Member

  • Members
  • PipPipPip
  • 1,012 posts

Posted 30 July 2015 - 09:28 PM

the general Ubuntu link:

 

http://forum.linkspr...orum/79-ubuntu/

 

I agree that for accuracy an OS based (except for real time operating systems) is not ideal. What kind of an accuracy do you need ?

 

RTOS is not without issue in this area either depending on the precision needed.



#16 cwilt

cwilt

    Advanced Member

  • Members
  • PipPipPip
  • 1,012 posts

Posted 30 July 2015 - 09:29 PM

I would prefer < 1ms.  Perhaps 500 micro(s).  My testing is the software interrupt is only good +/- 2 mSec. (contingent on what is happening in the ISR).  The issue I have found is the software ISR is accumulative.  If you start with the interrupt running every 20 mSec (and it slips), the timer restarts its "timer" after the Interrupt ISR is complete.  Therefore, you never catch back up to where you should be, you will always be off.

 

thanks for the URL

 

Which pins are you using?



#17 harthenry

harthenry

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts

Posted 30 July 2015 - 11:05 PM

Hi CW:

 

My current frequency is 5 hz (5 pulses per second).  The pcDuino will run for about 2 minutes and then poop out.  (this is a variable time, sometimes less, sometimes more).  Please dis-regard my previous note about running for a couple hours at 5 deg C in environment test chamber.  I was looking at the "source" blinking lights (3.3 v), and not the pcDuino.  I need new glasses.

 

Tried both on pcDuino Ver 3 and the Nano.  Both come back with similar results.  My next step is to try the C++ version of this -- however, I think the issue might be hardware related and not software.

Here is the code -- I use an external Output (to pcDuino input) to perform a graceful shut down the system -- however, I never use it because the pcDuino poops out < 2min.

Edit - I am not using the PartPulse, only the Oscillator input at this time.

 

Thanks,

HH

#include <core.h>
#include <time.h> 

#define INT_MODE	  FALLING
int iPulse = 0;
int iShutDownPin = 4;
time_t rawtime;
struct tm * timeinfo;

void PartPulse()
{
  printf("PartPulse\r\n");
}

void Oscillator()
{
  iPulse ++;
  if (iPulse == 20)
  {
    iPulse = 0;
    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
    printf ( "Oscillator: %s", asctime (timeinfo) );
  }
}

void setup()
{
  pinMode(iShutDownPin, INPUT);
  attachInterrupt(0, PartPulse, INT_MODE);  // pin 2
  attachInterrupt(1, Oscillator, INT_MODE); // pin 3
}

void loop()
{
  if (digitalRead(iShutDownPin) == LOW)
  {
    detachInterrupt(0);
    detachInterrupt(1);
    exit(0);
  }
}



#18 harthenry

harthenry

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts

Posted 30 July 2015 - 11:12 PM

Followup on this Post -- I wanted to launch my pcDuino straight to Command Prompt mode and bypass the Desktop, just in case the Desktop graphics are getting in the way, however, when I go to  -- sudo board-config.sh -- and place the bootup sequence to Command Line mode, the Command Line mode will not stick.  Continues to boot into desktop mode.

 

Is there some other way to boot only in command line mode?



#19 LS-Support-12

LS-Support-12

    Forum Support

  • Moderators
  • 326 posts

Posted 30 July 2015 - 11:15 PM

Is there some other way to boot only in command line mode?

 

Yes, there is another way. Checkout this topic.



#20 harthenry

harthenry

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts

Posted 30 July 2015 - 11:52 PM

Thanks for the info, however, I tried but I do not have a lxdm.conf file.  This is what I am running:  Also, F8 is not available on startup with "this version" of the Nano

No LSB modules are available.
Distributor ID: Linaro
Description: Linaro 12.11
Release: 12.11
Codename: precise
 







Also tagged with one or more of these keywords: SWIRQ, ubuntu14

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users