7 years, 11 months ago.

program dying in a while loop

I have something strange happening in my program and would like to know if it sounds familiar to any of you

I have a loop (while) which depends on the value of a pin. (the pin is also an InterruptIn pin) If the pin does not change, it goes for ever. If it changes it exists. At least in theory

 while(spi_irq_state != 0)
        {
          spi_irq_state=_spi.wlan_irq_read();   
        printf("*");    //<-------GETS STUCKED HERE!!!
        }
        printf("\n OUT\n");

my problem is that neither of those things seems to happen. The program just get stucked. It is not an infinite loop because no more "*"s get printed. The program prints a particular number of "*"s and then finish , stop. of course "OUT" is not printed.

Any idea what could be happening?

2 Answers

7 years, 11 months ago.

Some context would help but my first two thoughts are either:

1: The program is hanging after a finite number of calls to wlan_irq_read() 2: The program is hanging after a fixed time interval that is the time taken to print that many stars.

I looked at the source for wlan_irq_read() and it appears to be a wrapper for a perfectly ordinary "read()" operation on an InterruptIn pin so for the time being I'd assume its OK unless there turned out to be an unusually deep bug in InterruptIn.

If it is hanging after a time interval then if you change the star to two characters it should still print out the same number of characters. A time interval problem might be a problem with the real IRQ handler, it seems like what I'd expect to see if the interrupt handler executed but never returned.

Thanks for your comment. It is the second option: it hangs after a fixed time interval. I experimented as you indicate (putting two or three stars). The characters printed are the same. so the number of times wlan_irq_read is read is different.

You talk about the "real IRQ handler". What are you refering to? the handler of the InteruptIn? Well, I put a printf there too, to see if it is jumping there but it does not print anything....

posted by Cristian Fuentes 20 May 2016

By "real IRQ handler" what I meant was that you pass the library a pinname, and it constructs an "InterruptIn" using the pin you passed. I think it then registers its own handler for a "rise" or "fall" event, can't remember which, so that handler gets called for a transition on the pin. The simplest explanation for the device stopping is if it went into an endless loop inside the interrupt handler. Post-mortem debug might help here?

I suppose it might be worth making a test program that just registers that pin as InterruptIn without the library and adds a trivial handler just to check it isn't broken?

posted by Oliver Broad 20 May 2016

I assume it calls this: https://developer.mbed.org/users/Kojto/code/cc3000_hostdriver_mbedsocket/docs/192e2fde71e9/classmbed__cc3000_1_1cc3000__spi.html#a599e143f007c4c65a2346af8282a14af

I had the URL of a fork before not the original. I assume we are talking about cc3000_hostdriver_mbedsocket since that is about as near as I can get based on that code fragment.

posted by Oliver Broad 20 May 2016

So I tried reading the code of the handler and I found this:

if (received_buffer[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { while (1); }

If I'm reading this correctly then if there is a read operation and it doesn't end in a specific value then it will deliberately go into an infinite loop.

posted by Oliver Broad 20 May 2016

Thanks for the help. Yes, I suspected that, so at the very start of that function I put a printf

void cc3000_spi::WLAN_IRQHandler() {
    printf("I");
    if (_process_irq) {
...

but I dont see that printed when the program dies... Still wondering what is happening here...

posted by Cristian Fuentes 23 May 2016
7 years, 11 months ago.

Did you respect the rules about interruptin ?

Have a look to this : https://developer.mbed.org/handbook/InterruptIn

Thank you for your answer. What rules specifically are you referring to?

Btw, this is not my code. This is inside the CC3000 library that is published here in mbed. It seems to work for some people but it does not work for me. So I analyzed the code and identify the problem (which is what I wrote in the question) (of course the print '*'s etc are put by me to analyze what is happening)

I never knew you could "read" an interruptin but apparently you can.

Wonder why it is hanging up....

posted by Cristian Fuentes 20 May 2016