Local development and gdb debugging with NetBeans, a step by step guide

I think I have a fix! Branch feature/hal seems problematic, switching on the master branch, modifying firmware to disable JTAG and enable SWD makes it work! Hooray. Also COM port is working, which I had issues with before.

Im using OpenOCD 0.8.0 instead of st-link util (way faster upload) and updated my STLINK debugger to version: V2.J23.S4 STM32+STM8 Debugger. This is the configuration file that im using to start OpenOCD:

source [find interface/stlink-v2.cfg]
set WORKAREASIZE 0x5000
source [find target/stm32f1x_stlink.cfg]
reset_config srst_only srst_nogate

I copy this into /scripts/board directory as spark_core.cfg. Compiled OpenOCD binaries can be found here:

http://www.freddiechopin.info/en/download/category/4-openocd

Im running x64 Windows 8.1, so i run 64 bit version of openocd:

openocd-x64-0.8.0 -f board/spark_core.cfg

(Just start this instead of st-util)

Maybe I could commit the change? How do I do that, provided that I have the change comited in my local branch?

Sorry to hear you’re having trouble with feature/hal branch - it is a development branch so there may be unresolved issues, but I and a few other developers are using it successfully. If there’s any way we can dig in and find out more about the cause, I’d be happy to help.

To make your change to the master branch available to others, you submit a pull request. Please see https://help.github.com/articles/creating-a-pull-request/

One thing that’s not immediately clear is that the PR should be in it’s own branch, which you then push to your github repo. From there, you can create the pull request.

The first time you make a PR it can seem a bit daunting, but is much easier the second time. Also tools like SourceTree make the process much easier.

You don’t write to the spark repository directly so there’s no chance of doing anything harmful.

Best of luck, I hope that helps! :slight_smile:

Thanks for the AWESOME tutorial!

I followed it and had no real problems. But now I have run into something that I have been unable to figure out with the linking of the project. Where are the libraries specified that need to be linked into the final binary output? I’m trying to utilize functions in <time.h> but it’s failing at the link stage because it can’t find the functions I’ve used.

Being completely unfamiliar with how the Spark project is laid out and how the ARM GCC toolset works I was unable to find where this is done.

If you use the HAL branch, it all taken care of by the makefile. I do not have any experience with compiling the master branch, so I hope someone else can help you out.

@Elco

Can you share your schematic for your debugging board? I finally have my ST-Link/V2 but I don’t know what to connect where. Thanks!

I tried downloading the schematic from the Spark Git repo but the version of Eagle that I have complains that the schematic is not a valid Eagle file.

Please see this post for the layout of the board:

Thanks for reiterating that! I thought I had seen it before but my eyes failed to find it. (I guess a simple “find in page” would have worked well!)

I’m playing around with my ST-Link and I can get it to connect to my board from the ST-Link Utility but when using the st-util from the command line it seems to be having problems. It also won’t program the chip. Here is the output from st-util:

C:\Users\xxxxx>st-util -m -p 9025
STLINK GDB Server v0.5.6 (Mar 24 2013 10:29:19)
Many thanks to the STLINK development team.
(https://github.com/texane/stlink)

2014-12-17T11:32:06 INFO src/stlink-common.c: Loading device parameters....
2014-12-17T11:32:06 WARN src/stlink-common.c: unknown chip id! 0xe0042000
Chip ID is 00000000, Core ID is  00000000.
KARL - should read back as 0x03, not 60 02 00 00
Listening at *:9025...

So I did some digging to see if there was something similar to the “hold in reset” for the st-util but no luck.

However, there was one lucky find in my digging. I solved the need for the patch file to keep restarting st-util. There is a command line option -m that causes the server to keep running after a disconnect and listen for another connection.

Any ideas on why the st-util is not able to properly connect? Thanks!

It sounds like you have not recompiled the core with USE_SWD_JTAG=y.
If you merge my pull request for just SWD support, you can use USE_SWD=y
See https://github.com/spark/firmware/pull/337

You need to compile the code with that flag and flash it via DFU before you can connect via SWD.
St-util will then find a Core ID that is not zero.

Thanks! Getting much closer now! The problem was that I had not uploaded firmware that I had compiled with the USE_SWD_JTAG=y with DFU.

Now my problem is when I try to attach the debugger I used the command that you showed and I get the following error:

Undefined target command: \"target remote localhost:9025\".  Try \"help target\".

I have no idea where I could even try “help target” because it gives me an error if I try setting that in the target text box. I also tried Google and it did not turn up anything.

I tried it without the leading “target” since the gdbserver plugin suggested a target of “remote host:port” when I first started the attach. However this appears to do nothing as I don’t see anything happen in the st-util window and I don’t seem to be able to interact with the board from NetBeans.

Thanks again for all of your help!

Do you have the quotes (") in the command?

Originally I did not have quotes in the command. I just tried it with the quotes and it behaves the same way.

@Elco, i’m trying to setup the same environment on my MAC so that i can dig a little deeper on issues. However, i’m getting the exact same warning for the chip id. :stuck_out_tongue:

I have the JTAG shield and STlink V2 so hardware should be fine. If i found anything i’ll update this post :wink:

UPDATE

If you hold on the RST button before invoking st-util -p 9025, the correct core id is displayed but the user firmware does not run.

@kennethlimcp, sounds like you have not enabled debugging in your firmware build:

@Sailing_Nut
Try without ‘target’: just remote localhost:9025
That’s how I have it set up now.

I’ve tried it with the command being just:

remote localhost:9025

and it looks like NetBeans never tries to attach to the GDB server. I see that it is listening on port 9025 and nothing happens.

I have also noticed that my “Run” command seems to stay attached to the DGB server so I am pressing the X to stop the run before I try to attach the debugger. (I also tried it without stopping the run before attaching and still nothing.)

I left NetBeans in the “attach to GDB” mode and I came back a while later and saw that an error had popped up. It states:

Malformed response to offset query, timeout

Not sure if that helps anything but wanted to report just in case!

In the meantime I figured out how to get the GDB output from NetBeans. Hope this helps! (I did not get anything significant from Google)

This log is saved to: C:\Users\********\AppData\Local\Temp\gdb-cmds8972465870749292784.log

NB build: 201411181905

=thread-group-added,id="i1"
~"GNU gdb (GNU Tools for ARM Embedded Processors) 7.6.0.20140529-cvs\n"
~"Copyright (C) 2013 Free Software Foundation, Inc.\n"
~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.  Type \"show copying\"\nand \"show warranty\" for details.\n"
~"This GDB was configured as \"--host=i686-w64-mingw32 --target=arm-none-eabi\".\nFor bug reporting instructions, please see:\n"
~"<http://www.gnu.org/software/gdb/bugs/>.\n"
=cmd-param-changed,param="remote hardware-watchpoint-limit",value="6"
=cmd-param-changed,param="remote hardware-breakpoint-limit",value="4"
&"C:\\\\Users\\\\********\\\\Documents\\\\SparkDev\\\\WirelessGague1\\\\firmware\\\\gdbattach.txt:6: Error in sourced command file:\n"
&"The program is not being run.\n"
(gdb) 
2-list-features
3info signals
4-gdb-set print repeat 0
5-gdb-set backtrace limit 1024
6-gdb-set print elements 400
7-gdb-set follow-fork-mode parent
8-gdb-set detach-on-fork on
9-enable-pretty-printing
10-file-exec-and-symbols  "C:/Users/********/Documents/SparkDev/WirelessGague1/firmware/build/target/main/prod-0/main.elf"
2^done,features=["frozen-varobjs","pending-breakpoints","thread-info","data-read-memory-bytes","breakpoint-notifications","ada-task-info"]
(gdb) 
&"info signals\n"
~"Signal        Stop\tPrint\tPass to program\tDescription\n"
~"\n"
~"SIGHUP        Yes\tYes\tYes\t\tHangup\n"
~"SIGINT        Yes\tYes\tNo\t\tInterrupt\n"
~"SIGQUIT       Yes\tYes\tYes\t\tQuit\n"
~"SIGILL        Yes\tYes\tYes\t\tIllegal instruction\n"
~"SIGTRAP       Yes\tYes\tNo\t\tTrace/breakpoint trap\n"
~"SIGABRT       Yes\tYes\tYes\t\tAborted\n"
~"SIGEMT        Yes\tYes\tYes\t\tEmulation trap\n"
~"SIGFPE        Yes\tYes\tYes\t\tArithmetic exception\n"
~"SIGKILL       Yes\tYes\tYes\t\tKilled\n"
~"SIGBUS        Yes\tYes\tYes\t\tBus error\n"
~"SIGSEGV       Yes\tYes\tYes\t\tSegmentation fault\n"
~"SIGSYS        Yes\tYes\tYes\t\tBad system call\n"
~"SIGPIPE       Yes\tYes\tYes\t\tBroken pipe\n"
~"SIGALRM       No\tNo\tYes\t\tAlarm clock\n"
~"SIGTERM       Yes\tYes\tYes\t\tTerminated\n"
~"SIGURG        No\tNo\tYes\t\tUrgent I/O condition\n"
~"SIGSTOP       Yes\tYes\tYes\t\tStopped (signal)\n"
~"SIGTSTP       Yes\tYes\tYes\t\tStopped (user)\n"
~"SIGCONT       Yes\tYes\tYes\t\tContinued\n"
~"SIGCHLD       No\tNo\tYes\t\tChild status changed\n"
~"SIGTTIN       Yes\tYes\tYes\t\tStopped (tty input)\n"
~"SIGTTOU       Yes\tYes\tYes\t\tStopped (tty output)\n"
~"SIGIO         No\tNo\tYes\t\tI/O possible\n"
~"SIGXCPU       Yes\tYes\tYes\t\tCPU time limit exceeded\n"
~"SIGXFSZ       Yes\tYes\tYes\t\tFile size limit exceeded\n"
~"SIGVTALRM     No\tNo\tYes\t\tVirtual timer expired\n"
~"SIGPROF       No\tNo\tYes\t\tProfiling timer expired\n"
~"SIGWINCH      No\tNo\tYes\t\tWindow size changed\n"
~"SIGLOST       Yes\tYes\tYes\t\tResource lost\n"
~"SIGUSR1       Yes\tYes\tYes\t\tUser defined signal 1\n"
~"SIGUSR2       Yes\tYes\tYes\t\tUser defined signal 2\n"
~"SIGPWR        Yes\tYes\tYes\t\tPower fail/restart\n"
~"SIGPOLL       No\tNo\tYes\t\tPollable event occurred\n"
~"SIGWIND       Yes\tYes\tYes\t\tSIGWIND\n"
~"SIGPHONE      Yes\tYes\tYes\t\tSIGPHONE\n"
~"SIGWAITING    No\tNo\tYes\t\tProcess's LWPs are blocked\n"
~"SIGLWP        No\tNo\tYes\t\tSignal LWP\n"
~"SIGDANGER     Yes\tYes\tYes\t\tSwap space dangerously low\n"
~"SIGGRANT      Yes\tYes\tYes\t\tMonitor mode granted\n"
~"SIGRETRACT    Yes\tYes\tYes\t\tNeed to relinquish monitor mode\n"
~"SIGMSG        Yes\tYes\tYes\t\tMonitor mode data available\n"
~"SIGSOUND      Yes\tYes\tYes\t\tSound completed\n"
~"SIGSAK        Yes\tYes\tYes\t\tSecure attention\n"
~"SIGPRIO       No\tNo\tYes\t\tSIGPRIO\n"
~"SIG33         Yes\tYes\tYes\t\tReal-time event 33\n"
~"SIG34         Yes\tYes\tYes\t\tReal-time event 34\n"
~"SIG35         Yes\tYes\tYes\t\tReal-time event 35\n"
~"SIG36         Yes\tYes\tYes\t\tReal-time event 36\n"
~"SIG37         Yes\tYes\tYes\t\tReal-time event 37\n"
~"SIG38         Yes\tYes\tYes\t\tReal-time event 38\n"
~"SIG39         Yes\tYes\tYes\t\tReal-time event 39\n"
~"SIG40         Yes\tYes\tYes\t\tReal-time event 40\n"
~"SIG41         Yes\tYes\tYes\t\tReal-time event 41\n"
~"SIG42         Yes\tYes\tYes\t\tReal-time event 42\n"
~"SIG43         Yes\tYes\tYes\t\tReal-time event 43\n"
~"SIG44         Yes\tYes\tYes\t\tReal-time event 44\n"
~"SIG45         Yes\tYes\tYes\t\tReal-time event 45\n"
~"SIG46         Yes\tYes\tYes\t\tReal-time event 46\n"
~"SIG47         Yes\tYes\tYes\t\tReal-time event 47\n"
~"SIG48         Yes\tYes\tYes\t\tReal-time event 48\n"
~"SIG49         Yes\tYes\tYes\t\tReal-time event 49\n"
~"SIG50         Yes\tYes\tYes\t\tReal-time event 50\n"
~"SIG51         Yes\tYes\tYes\t\tReal-time event 51\n"
~"SIG52         Yes\tYes\tYes\t\tReal-time event 52\n"
~"SIG53         Yes\tYes\tYes\t\tReal-time event 53\n"
~"SIG54         Yes\tYes\tYes\t\tReal-time event 54\n"
~"SIG55         Yes\tYes\tYes\t\tReal-time event 55\n"
~"SIG56         Yes\tYes\tYes\t\tReal-time event 56\n"
~"SIG57         Yes\tYes\tYes\t\tReal-time event 57\n"
~"SIG58         Yes\tYes\tYes\t\tReal-time event 58\n"
~"SIG59         Yes\tYes\tYes\t\tReal-time event 59\n"
~"SIG60         Yes\tYes\tYes\t\tReal-time event 60\n"
~"SIG61         Yes\tYes\tYes\t\tReal-time event 61\n"
~"SIG62         Yes\tYes\tYes\t\tReal-time event 62\n"
~"SIG63         Yes\tYes\tYes\t\tReal-time event 63\n"
~"SIGCANCEL     No\tNo\tYes\t\tLWP internal signal\n"
~"SIG32         Yes\tYes\tYes\t\tReal-time event 32\n"
~"SIG64         Yes\tYes\tYes\t\tReal-time event 64\n"
~"SIG65         Yes\tYes\tYes\t\tReal-time event 65\n"
~"SIG66         Yes\tYes\tYes\t\tReal-time event 66\n"
~"SIG67         Yes\tYes\tYes\t\tReal-time event 67\n"
~"SIG68         Yes\tYes\tYes\t\tReal-time event 68\n"
~"SIG69         Yes\tYes\tYes\t\tReal-time event 69\n"
~"SIG70         Yes\tYes\tYes\t\tReal-time event 70\n"
~"SIG71         Yes\tYes\tYes\t\tReal-time event 71\n"
~"SIG72         Yes\tYes\tYes\t\tReal-time event 72\n"
~"SIG73         Yes\tYes\tYes\t\tReal-time event 73\n"
~"SIG74         Yes\tYes\tYes\t\tReal-time event 74\n"
~"SIG75         Yes\tYes\tYes\t\tReal-time event 75\n"
~"SIG76         Yes\tYes\tYes\t\tReal-time event 76\n"
~"SIG77         Yes\tYes\tYes\t\tReal-time event 77\n"
~"SIG78         Yes\tYes\tYes\t\tReal-time event 78\n"
~"SIG79         Yes\tYes\tYes\t\tReal-time event 79\n"
~"SIG80         Yes\tYes\tYes\t\tReal-time event 80\n"
~"SIG81         Yes\tYes\tYes\t\tReal-time event 81\n"
~"SIG82         Yes\tYes\tYes\t\tReal-time event 82\n"
~"SIG83         Yes\tYes\tYes\t\tReal-time event 83\n"
~"SIG84         Yes\tYes\tYes\t\tReal-time event 84\n"
~"SIG85         Yes\tYes\tYes\t\tReal-time event 85\n"
~"SIG86         Yes\tYes\tYes\t\tReal-time event 86\n"
~"SIG87         Yes\tYes\tYes\t\tReal-time event 87\n"
~"SIG88         Yes\tYes\tYes\t\tReal-time event 88\n"
~"SIG89         Yes\tYes\tYes\t\tReal-time event 89\n"
~"SIG90         Yes\tYes\tYes\t\tReal-time event 90\n"
~"SIG91         Yes\tYes\tYes\t\tReal-time event 91\n"
~"SIG92         Yes\tYes\tYes\t\tReal-time event 92\n"
~"SIG93         Yes\tYes\tYes\t\tReal-time event 93\n"
~"SIG94         Yes\tYes\tYes\t\tReal-time event 94\n"
~"SIG95         Yes\tYes\tYes\t\tReal-time event 95\n"
~"SIG96         Yes\tYes\tYes\t\tReal-time event 96\n"
~"SIG97         Yes\tYes\tYes\t\tReal-time event 97\n"
~"SIG98         Yes\tYes\tYes\t\tReal-time event 98\n"
~"SIG99         Yes\tYes\tYes\t\tReal-time event 99\n"
~"SIG100        Yes\tYes\tYes\t\tReal-time event 100\n"
~"SIG101        Yes\tYes\tYes\t\tReal-time event 101\n"
~"SIG102        Yes\tYes\tYes\t\tReal-time event 102\n"
~"SIG103        Yes\tYes\tYes\t\tReal-time event 103\n"
~"SIG104        Yes\tYes\tYes\t\tReal-time event 104\n"
~"SIG105        Yes\tYes\tYes\t\tReal-time event 105\n"
~"SIG106        Yes\tYes\tYes\t\tReal-time event 106\n"
~"SIG107        Yes\tYes\tYes\t\tReal-time event 107\n"
~"SIG108        Yes\tYes\tYes\t\tReal-time event 108\n"
~"SIG109        Yes\tYes\tYes\t\tReal-time event 109\n"
~"SIG110        Yes\tYes\tYes\t\tReal-time event 110\n"
~"SIG111        Yes\tYes\tYes\t\tReal-time event 111\n"
~"SIG112        Yes\tYes\tYes\t\tReal-time event 112\n"
~"SIG113        Yes\tYes\tYes\t\tReal-time event 113\n"
~"SIG114        Yes\tYes\tYes\t\tReal-time event 114\n"
~"SIG115        Yes\tYes\tYes\t\tReal-time event 115\n"
~"SIG116        Yes\tYes\tYes\t\tReal-time event 116\n"
~"SIG117        Yes\tYes\tYes\t\tReal-time event 117\n"
~"SIG118        Yes\tYes\tYes\t\tReal-time event 118\n"
~"SIG119        Yes\tYes\tYes\t\tReal-time event 119\n"
~"SIG120        Yes\tYes\tYes\t\tReal-time event 120\n"
~"SIG121        Yes\tYes\tYes\t\tReal-time event 121\n"
~"SIG122        Yes\tYes\tYes\t\tReal-time event 122\n"
~"SIG123        Yes\tYes\tYes\t\tReal-time event 123\n"
~"SIG124        Yes\tYes\tYes\t\tReal-time event 124\n"
~"SIG125        Yes\tYes\tYes\t\tReal-time event 125\n"
~"SIG126        Yes\tYes\tYes\t\tReal-time event 126\n"
~"SIG127        Yes\tYes\tYes\t\tReal-time event 127\n"
~"SIGINFO       Yes\tYes\tYes\t\tInformation request\n"
~"EXC_BAD_ACCESS Yes\tYes\tYes\t\tCould not access memory\n"
~"EXC_BAD_INSTRUCTION Yes\tYes\tYes\t\tIllegal instruction/operand\n"
~"EXC_ARITHMETIC Yes\tYes\tYes\t\tArithmetic exception\n"
~"EXC_EMULATION Yes\tYes\tYes\t\tEmulation instruction\n"
~"EXC_SOFTWARE  Yes\tYes\tYes\t\tSoftware generated exception\n"
~"EXC_BREAKPOINT Yes\tYes\tYes\t\tBreakpoint\n"
~"\nUse the \"handle\" command to change these tables.\n"
3^done
(gdb) 
4^done
(gdb) 
5^done
(gdb) 
6^done
(gdb) 
7^done
(gdb) 
8^done
(gdb) 
9^done
(gdb) 
10^done
11cd C:\Users\********\Documents\SparkDev\WirelessGague1\firmware\build\target\main\prod-0
12-exec-arguments main.elf -x C:\Users\********\Documents\SparkDev\WirelessGague1\firmware\gdbprogram.txt
(gdb) 
&"cd C:\\Users\\********\\Documents\\SparkDev\\WirelessGague1\\firmware\\build\\target\\main\\prod-0\n"
~"Working directory C:\\Users\\********\\Documents\\SparkDev\\WirelessGague1\\firmware\\build\\target\\main\\prod-0.\n"
11^done
(gdb) 
=cmd-param-changed,param="args",value="main.elf -x C:\\\\Users\\\\********\\\\Documents\\\\SparkDev\\\\WirelessGague1\\\\firmware\\\\gdbprogram.txt"
12^done
(gdb) 
13target remote localhost:9025
&"target remote localhost:9025\n"
~"Remote debugging using localhost:9025\n"
~"Ignoring packet error, continuing...\n"
&"warning: unrecognized item \"timeout\" in \"qSupported\" response\n"
~"Ignoring packet error, continuing...\n"
~"Ignoring packet error, continuing...\n"
~"Ignoring packet error, continuing...\n"
~"Ignoring packet error, continuing...\n"
~"Ignoring packet error, continuing...\n"
=thread-group-started,id="i1",pid="42000"
=thread-created,id="1",group-id="i1"
~"Ignoring packet error, continuing...\n"
=thread-group-exited,id="i1"
&"Malformed response to offset query, timeout\n"
13^error,msg="Malformed response to offset query, timeout"
(gdb)

Yes, you have to make sure you have no old processes running in the background, or you will not be able to attach.

OK, so I found out that my little -m discovery was my undoing!

I ran a test without first doing the “run” command just to see if my firewall was getting in the way. Well, the debug session attached! So I terminated that and then tried a “run” but that failed to attach to the GDB server.

So, the problem is that st-util.exe is not actually accepting connections after a process detaches even though it looks like it is waiting.

I revised my “process” to use the batch file and all is happy now!

Thanks for all of your help!

@mdma notified me that there is an open bug report for not being able to pause execution in Netbeans.

Please help give the bug priority by creating an account and voting on the issue:
https://netbeans.org/bugzilla/show_bug.cgi?id=224840

I wrote a shell script for easy and reliable programming via GDB:

Please see:
https://github.com/BrewPi/firmware/blob/develop/tools/hardware_debugging.md
and

This script will start st-util, then fork it to the background and start arm gdb to connect to it and upload the code. After that it does a clean exit: no lingering processes that you should remember to close.

You can just set this script as the run command in NetBeans and it will upload the code with 1 click. The output of the script will be printed in the embedded terminal.

After you have uploaded the code, if needed, you can start st-util again and connect the debugger.

I think the process is great now, it just misses the ability to pause. This is related to the bug report I posted above, don’t forget to vote for it!

1 Like