Using Live Variables in Embedded Projects

This tutorial shows how to use VisualGDB Live Variables feature to examine the state of your embedded program without interrupting it. Live Variables are supported in VisualGDB starting from version 5.0.

  1. Start with creating a normal Embedded Project with Visual Studio:01-prj
  2. On the first page of the wizard select “Embedded Binary”:02-binary
  3. Select your device. In this example we will use the STM32F4 Discovery board with the STM32F407VG microcontroller:03-device
  4. Select the LEDBLink (HAL) sample in the sample list:04-halIf you are using a different board than STM32F4Discovery, select the LED group/port that matches your board schematics.
  5. On the last page of the wizard select the debug method. Live variables are currently supported only with OpenOCD and Segger J-Link:05-openocd
  6. Build and start your project. Ensure that the LED is blinking:06-build
  7. Before you can start using the live variables, ensure that you are using the latest debug packages, as the older versions don’t support the live variable interfaces. Go to Tools->Embedded Tools Manager and click “Check now”. If any updates are found, install them:07-updates
  8. We will now change the program to produce the “breathing LED effect” by gradually modifying the duty cycle instead of just turning it on and off:08-pwmFor simplicity we will avoid the use of hardware PWMs and will simply use a basic loop containing the following actions:
    • Turn the LED on
    • Wait a variable amount of cycles (proportional to the duty cycle)
    • Turn the LED off
    • Wait a until the end of period

    Here is the code implementing that loop:

    #include<math.h>
    float g_Arg, g_Sin, g_Cos;
    
    int main(void)
    {
       //<...>
        HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
    
       for (g_Arg = 0; ;g_Arg += 0.01F)
        {
            g_Sin = sinf(g_Arg);
            g_Cos = cosf(g_Arg);
    
           int totalCycles = 5000;
           int onCycles = (int)(totalCycles * (g_Sin + 1)) / 2;
           int offCycles = totalCycles - onCycles;
    
            HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
           for (int i = 0; i < onCycles; i++)
               asm("nop");
            HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
           for (int i = 0; i < offCycles; i++)
               asm("nop");
        }
    }

    We have declared the variables as global so that they will always have the same address and can be evaluated by checknig that address without stopping the program. Local variables would be overwritten with something else as soon as the function containing them exits and another one is called (not the case in this example).

  9. Build and run your program. While the program is running, open the Live Variables window (Debug->Windows->Live variables):09-livevarsIf the window is not displayed, ensure that you are using VisualGDB 5.0+ and that your OpenOCD or Segger package is up to date.
  10. The Live Variables window is similar to the Watch window. Simply type “g_Sin” and “g_Cos” to add those variables to the list:10-sincosVisualGDB will normally detect the variable types automatically, but you can also modify it explicitly.
    Warning: while evaluating live variables does not stop your program, adding them briefly pauses it.
  11. Click at the “Plot” column of each variable. VisualGDB will show a graph containing the variable values:11-plot
  12. You can examine the values of the variables by pausing the graph updating and hovering the mouse over the graph:12-values
  13. You can also set virtual breakpoints that will be triggered once the variable value approaches the specified trigger. To demonstrate this we will set a breakpoint when g_Sin becomes greater than 0.9. Click in the “BP” field of g_Sin and enter the condition:13-condition
  14. The breakpoint will soon trigger:14-bpNote that the breakpoint will be triggered when VisualGDB refreshes the variable value and not when it’s actually changed. If you want to track the exact moment of the variable change, use conditional data breakpoints. They will reveal the exact code line accessing the variable, but will pause your program each time the variable is modified to compare its value.
  15. You can modify various settings related to the Live Variables window via Tools->Options->VisualGDB->Embedded:15-options