Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

Grand Central M4 - timers, delays and debugging
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Grand Central M4 - timers, delays and debugging

by RCohenQubiq on Wed Jul 15, 2020 1:52 pm

Hi folks,

I'm sorry if this is a newbie question.

I've just purchased a Grand Central M4, and Segger J-Link. Using VS Code with PlatformIO as my IDE, I compiled the classic Arduino "blink" program and downloaded it to the GC over the J-Link connection (using SWD). In the loop() function, this blink program turns on the built-in LED, inserts a delay (I tried various numbers, the classic example used 1000 ms), turns off the LED, inserts another delay.

If I run the program by itself (not in the debugger), everything works just fine. I ran this way by simply pressing the reset button on the GC. If I run the program within the debugger, I can step through and see the code executing, but the delay() seems to return immediately. So the LED appears to be on continuously (but it is probably blinking very very fast).

I created a similar blink program, but using the millis() function to check the time in the loop() function, rather than using the delay() function. Again, this program runs fine outside of the debugger, but within the debugger millis() always returns 0.

Is there some known interaction between the debugging system and the timer on the GC? And is there a setting or workaround to allow debugging with delays and timers? If this question is answered elsewhere in the forums, a link or a search string to find that answer would be great.

Thanks in advance for your help,

- Rick

RCohenQubiq
 
Posts: 9
Joined: Wed Jul 15, 2020 1:38 pm

Re: Grand Central M4 - timers, delays and debugging

by westfw on Wed Jul 15, 2020 5:15 pm

There's a control bit in most of the SAMD51 peripherals (DBGRUN) that you can set if the peripheral should continue to run when the system is otherwise halted in debug states.
But I don't think it explains your symptoms of delay() returning immediately (since delay involves a bunch of code running in timer interrupts, not just the timer itself.) (also, I don't think the Adafruit code turns the bit on.)
As for millis() "always returns zero" - are you sure you let it run long enough? if you're "stepping", there are 10s of thousands of steps between each millisecond tick...

westfw
 
Posts: 1720
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Grand Central M4 - timers, delays and debugging

by RCohenQubiq on Wed Jul 15, 2020 5:35 pm

Hello @westfw,

Thanks very much for your reply.

westfw wrote:There's a control bit in most of the SAMD51 peripherals (DBGRUN) that you can set if the peripheral should continue to run when the system is otherwise halted in debug states.


This is interesting. Would this be set in the source code or in gdb?

westfw wrote:But I don't think it explains your symptoms of delay() returning immediately (since delay involves a bunch of code running in timer interrupts, not just the timer itself.) (also, I don't think the Adafruit code turns the bit on.)


Yes, I think this is strange too.

westfw wrote:As for millis() "always returns zero" - are you sure you let it run long enough? if you're "stepping", there are 10s of thousands of steps between each millisecond tick...


For most of my testing of this version of the program, I had no breakpoints enabled, and simply pressed the "run" button in the platformIO debug interface. I only set a breakpoint on the line following my call to millis() after I suspected a problem. Whenever I hit that breakpoint, the result from millis() was 0.

Take care,

- Rick

RCohenQubiq
 
Posts: 9
Joined: Wed Jul 15, 2020 1:38 pm

Re: Grand Central M4 - timers, delays and debugging

by User_UMjT7KxnxP8YN8 on Thu Jul 16, 2020 12:08 pm

How are you looking at the value returned by millis()? Would you post sample code?

I use a Segger J-Link with their Ozone debugger and will repeat your test to see if I can reproduce your results.

User_UMjT7KxnxP8YN8
 
Posts: 153
Joined: Tue Jul 17, 2018 1:28 pm

Re: Grand Central M4 - timers, delays and debugging

by RCohenQubiq on Thu Jul 16, 2020 1:19 pm

Hello Adafruit_UMjT7KxnxP8YN8,

Here's the code I used. In the loop() function you can change from delayLED() to checkTime() and back, then recompile. To see the value returned from millis(), I set a breakpoint in platformIO at the line just after millis() is called, and viewed the value of currentMillis and previousMillis.

Code: Select all | TOGGLE FULL SIZE
/*
 * Blink
 * Turns on an LED on for one second,
 * then off for one second, repeatedly.
 */

#include <Arduino.h>

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void delayLED()
{
  // turn the LED on (HIGH is the voltage level)
  digitalWrite(LED_BUILTIN, HIGH);
  // wait for 2 seconds
  delay(2000);
  // turn the LED off by making the voltage LOW
  digitalWrite(LED_BUILTIN, LOW);
   // wait for a second
  delay(1000);

}
void checkTime()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

void loop()
{
  //delayLED();
  checkTime();
}


Take care and thanks for taking a look at this.

RCohenQubiq
 
Posts: 9
Joined: Wed Jul 15, 2020 1:38 pm

Re: Grand Central M4 - timers, delays and debugging

by User_UMjT7KxnxP8YN8 on Thu Jul 16, 2020 2:41 pm

Runs fine for me using Segger Ozone. Both previousMillis and currentMillis have non-zero values and the LED blinks once per second while running freely in debugger.

If I set a breakpoint at the statement that changes the LED state, when it breaks the LED has switched states each time. I can also single-step through it and it works fine.

The other version, using delayLED(), behaves a bit more strangely. The function is inlined in loop() and looks like this:

Code: Select all | TOGGLE FULL SIZE
void loop()
{
  delayLED();
     000042AE   MOVS           R1, #1
     000042B0   MOVS           R0, #13
     000042B2   BL             digitalWrite                  ; 0x000047E4
     000042B6   MOV.W          R0, #0x7D0
     000042BA   BL             delay                         ; 0x00004460
     000042BE   MOVS           R0, #13
     000042C0   MOVS           R1, #0
     000042C2   BL             digitalWrite                  ; 0x000047E4
     000042C6   MOV.W          R0, #0x3E8
  //checkTime();
}


If I set a breakpoint in it and hit run it behaves the same as the other version. But if I single-step through it Ozone loses its connection to the J-Link. However, delay() takes just as long as you'd expect to return.

Ozone can be used for free for evaluation purposes. If you buy a J-Link Plus or higher, the Ozone license is included in the price. I found a reasonably priced used one on eBay.

User_UMjT7KxnxP8YN8
 
Posts: 153
Joined: Tue Jul 17, 2018 1:28 pm

Please be positive and constructive with your questions and comments.