Does VEXcode IQ support breakpoints, single-stepping, and inspecting variables?

Does VEXcode IQ support any of the following debug features?

  • Being able to set breakpoints
  • Single step through code lines
  • Inspect the value of variables

These three features would help a lot when kids are trying to write debug their code.

Doing it wirelessly might be a bit of a stretch (without a USB smart radio or something) but doing it with the USB cable attached seems plausible.

As someone who has worked with a lot of other embedded development environments, those kinds of features are fairly standard, and not having them makes debug an order of magnitude harder.

As far as I am aware right now, the only way we can debug right now is to print stuff to the screen and put statements that pause until a button is pushed. Those methods can work OK, but they have their limits, especially if the kids are still trying to figure out how to even print to the screen or write a wait loop.

4 Likes

No.

Then you would know that without using JTAG or other means, it’s difficult.

RobotC had the luxury of running inside a VM, it had the ability to stop execution at any point and report status back to the application. That’s pretty difficult to do when running native code as a bare metal application.

2 Likes

JTAG is useful for debug but it’s not the only way.

There have been times where I had to write my own debug code or bootloaders for custom hardware that didn’t have off the shelf tools, so I have some idea of what’s involved.

Just looking at the capabilities of the existing VEX IQ hardware, it seems quite possible to implement breakpoints purely in software. If the team developing VEXcode IQ has the time and willingness to do it, I have faith that they could.

The main requirements for implementing breakpoints in software are as follows…

  1. The processor can run code from a memory which can be easily changed (usually RAM). I believe the VEX IQ hardware runs an ARM processor internally, and ARM can typically run code from RAM. Provided they have enough RAM, this can work.

  2. The communications link with the PC should be able to interrupt the executing code. It appears that the VEX IQ USB data link is interrupt based, since I can stop a running program from the IDE.

  3. The processor has some sort of instruction that can be used to jump to the debug handler. This could be a software interrupt, illegal instruction trap, a call instruction, a dedicated debug instruction, etc. Nearly all processors have at least one of these.

To implement the breakpoints…

  1. Run the code from RAM.

  2. To set a breakpoint the IDE sends a message to the hardware via USB. The code will be interrupted to process the message. At which point the interrupt handler will see that it’s a breakpoint message and insert the breakpoint. To insert the breakpoint, the handler would just swap out a particular machine instruction in RAM with an instruction that jumps to a debug handler. The message processor then returns from the interrupt and lets the user code continue.

  3. If the user code executes the modified instruction at the break point address, it will jump to the debug handler. The debug handler then interacts, via USB, with the IDE on the PC.

  4. When the user tells the program to resume, the IDE send a message to the debug handler code. The debug handler finds a way to splice in the “missing” instruction that it removed from RAM, and then jumps back to the user program.

Also, depending on which version of ARM processor they are running, I believe one can interact with the onboard debug hardware via code to set hardware breakpoints (which simplifies the process a lot).

2 Likes

The different VEX platforms run code in different ways.

IQ generation 1 runs all code from flash, there is very little RAM available and at this stage in its life almost no available flash for further development. The user program is running in cooperation with the rest of vexos so simply stopping the processor is not an option.

IQ generation 2 runs user code from RAM, there may be some future possibility to do something here, but again, user code is running on the same cpu as the rest of vexos so it’s a bit harder than just dealing with breakpoints where the entire application can be stopped.

V5 runs all code from RAM and user program is also running on a separate processor, depending on what the user code is doing the primary processor running vexos may not be able to interrupt the code beyond using full reset of the processor which is how we stop user code on V5.

4 Likes

Thank you for taking time to discuss this with me.

If its any use, there is one other option I thought of here that could work, even when executing from flash. Make a “Break()” function that the user can explicity put in their code at certain points. That function compiles into their code like any other.

It would allow the user to inspect the general flow of the program by pausing it a certain points. Worst case they recreate “single stepping” by putting in a lot of Break() functions. Also while in the breakpoint, the OS has control, so reading RAM to inspect variables is probably possible.

It could work as follows…

  1. The user puts the Break() function at various points in their code where they think they need debug. When they run their code, they get debug at these points, and these points only. They can’t change the position of the breakpoints without reloading code.

  2. Because the Break() function is explicitly compiled in with the other code, no need to modify the program at run time. So now we can have breakpoints in flash.

  3. Let the user change the enabled/disabled state of the breakpoints, but only while the code is not running. This is either when stopped at a breakpoint (meaning the OS has control), or before the code is compiled. This solves the problem of having to interrupt running code. The enable/disable state can be set just like other IDEs by clicking on the left side of the text editor.

  4. While at the breakpoint, the OS has control. At that point the OS can communicate with the IDE over USB, so inspecting variables in RAM should be possible.

  5. Each “breakpoint” would have its own state (enabled or disabled). The same Breakpoint() function gets called in every case. To manage state the call stack is examined to get the return_address. A table of breakpoint_enabled values is maintained using the return_address to lookup the enabled/disabled state. This could be as simple as looking up weather the return address appears (enabled) or not(disabled) in an array, hash table, binary tree, etc.

  6. If the breakpoint is enabled, then the OS has control until a USB message is received saying to resume. If the breakpoint is disabled, the function just returns and continues the user code.

  7. If USB is not connected, the breakpoint function just continues. This allows the user to leave the breakpoints in and run the code as normal if they are not on USB. I presume the OS has a way of detecting that USB is not attached.

  8. The breakpoint state-table should have initial enabled/disabled values that are compiled in. When the user clicks download/build the IDE would generate a header file in the background to initialize the breakpoint state table. That header would just get compiled in like normal with the rest of the code and the user doesn’t really have to even know it exists.

This seems possible on IQ (which is my focus for now). Weather it would work on V5 depends on what communication paths you have between the two processors.

4 Likes

no worries, happy to do that.

VexIQ generation 1 was designed over 10 years ago, it was first used for competition in 2012. Over the years there have been a number of different programming options for it, EasyC, RobotC, RobotMesh studio, ModKit, VEX coding studio and most recently VEXcode. I believe there are one or two other hobbyist solutions as well. IQ generation 1 is pretty much in a maintenance mode at this point, bugs will get fixed and any new sensors added when appropriate, but it’s unlikely to get any major other changes to vexos.

VEXcode programs use some core firmware that goes back to 2015 when we were looking at alternatives to the RobotC virtual machine. It uses a cooperative scheduler (as does V5, IQ2 and EXP when used with VEXcode) that has similar features to the scheduler that RobotC used, that is, although implementation is very different from RobotC it had to tolerate the mistakes and misuse that students typically make that would break most traditional implementations.

One of the features I implemented at that time was similar to you are describing, breakpoints could be set via a serial protocol, statements could be added to the code that would trigger the breakpoint. The plan was to give each breakpoint a hash based on file name and a id code that would be the file line number. VCS (predecessor to VEXcode) would have inserted the “vexBreak” call into the code behind the scenes before compiling it to try and make it transparent to the user. When a vexBreak was reached in the code that matched one of the enabled breakpoints, the scheduler could suspend all program tasks, the program could be restarted via serial control. We never made it past proof of concept in the firmware, nothing was ever developed for VCS.

IQ generation 1 is very tight on memory, so all of that functionality was stripped out 2 or 3 years ago to allow other features, it’s unlikely to ever make it back into the firmware.

IQ generation 2 may be able implement something like this in the future, it has more resources (although still pretty tight) and vexos and user code are more tightly coupled as we only support development using VEXcode, we don’t have to worry about breaking compatibility with third party development options which is always a concern with V5 and IQ generation 1. We have nothing on the roadmap for development in this area, so I have no idea if or when we could even begin to consider something like this.

5 Likes

Thanks for the long post about the internals of the V1 brain.

So I guess this means no more RobotMesh? One of the things that I liked about the environment is we had choices.

3 Likes