2

I am looking at the STM32f4xx project template, generated by the GNU ARM Eclipse plugin, with semihosting enabled. The main function is defined with both argc and argv parameters, which is pretty useless in a freestanding embedded program, but in case of semi-hosted debugged program they can be passed used some mechanism. So my question is how do I access this mechanism? Right now, without any changes to the template and the project settings, the argv[0] equals to a string "foobar", which I have no idea where it came from. And I have no idea how to pass some other string to it. Some more information:
- IDE: Eclipse + GNU Arm Eclipse plugin
- Toolchain: GCC ARM Embedded
- Debug: Eclipse + OpenOCD + GDB from the toolchain
- Hardware: STM32f401vC

Update: I am starting to suspect the constant is buried deeply in the newlib code. I can see where the args reading is triggered (it's in _syscals.c) by call_host (SEMIHOSTING_SYS_GET_CMDLINE, &cmdBlock);, but I can't figure out where it is handled. It is then transformed to a bkpt 0xAB and from there I am lost.

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
  • The standard does not define a "semihosted" environment, so it is actually a freestanding, thus the implementation is free to define `main` and its arguments. However, I would have a look into the startup code which calls `main`. Normally, it makes no sense to pass arguments; just a `const char [] = "...";` in a module seems to be the better and easier way (why would you waste code to parse an argument string which is constant anyway?) – too honest for this site Sep 15 '15 at 17:18
  • The most mysterious thing for me here is the string "foobar". I just can't grep it out of the sources. – Eugene Sh. Sep 15 '15 at 17:20
  • Did you check the startup? Sorry, I work with STM32F4, but I use all my own code - partly to avoid such "surprises";-) – too honest for this site Sep 15 '15 at 17:42
  • I would grep for `0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x00`. That's *"foobar"* in hex, and would be one way to write it in assembly. – user3386109 Sep 15 '15 at 17:43
  • @user3386109 Interesting idea. Didn't think of searching arrays. – Eugene Sh. Sep 15 '15 at 17:51
  • I am starting to suspect the constant is buried deeply in the `newlib` code. I can see where the args reading is triggered (it's in `_syscals.c`) by `call_host (SEMIHOSTING_SYS_GET_CMDLINE, &cmdBlock);`, but I can't figure out where it is handled. – Eugene Sh. Sep 15 '15 at 19:41
  • @Olaf, see my answer below, if interested. – Eugene Sh. Sep 15 '15 at 20:23

2 Answers2

0

It's the name of your executable. You probably set it when you created the project and forgot about it.

The semihosted environment simulates an application running as a normal executable in a UNIX-like operating system by passing it an argc and argv[] when it's run, and allowing it to use certain system calls to communicate with the host. The libraries required to link a semihosted application include a few calls which retrieve this information from the host over JTAG during startup. (If your target is not connected to JTAG, or the debugger is not running on the host, this will cause your application to hang indefinitely. Don't link with semihosting libraries in production!)

For more information on semihosting, see the "Semihosting" section of ARM's documentation:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0471g/Bgbjjgij.html

0

Figured it out after digging in all of the available source files. As OpenOCD is used as debug server, it is servicing the host call requests. For the SEMIHOSTING_SYS_GET_CMDLINE (0x15) request it is filling the argv buffer with a hardcoded foobar string, which can be observed in the OpenOCD src/arm_semihosting.c source file.

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
  • Hmm... so this is meant by "semihosting". I read something about exchanging data using the DCRDR (IIRC - am I right?), but was not sure how this worked, so I used something "homebrew". Did you find any information this runs with interrupt or polling? Just wonder what this is worth. `printf` is useful, but `argv` ...? – too honest for this site Sep 15 '15 at 20:29
  • If I read the code correctly, it is just returning the fixed string without possibility to set it in any way, so looks completely useless. Perhaps on some other debug servers it is implemented differently. The host requests are handled by software interrupts (`SWI/SVC`) on ARM. – Eugene Sh. Sep 15 '15 at 20:40
  • So it will not work with an OS installed which uses `SVC`. Ok, I'll stick with my own version. Anyway, thanks for all the fish;-) – too honest for this site Sep 15 '15 at 20:42
  • @Olaf Actually on ARMv6-M and ARMv7-M it is implemented using `BKPT` rather than `SVC`. So it is handled by OpenOCD as a software breakpoint. – Eugene Sh. Sep 15 '15 at 20:48
  • Still not good. I use `BKPT` for run-time assertions. Hmm, this is even worse, as it stops the MCU when I print data; sounds - ehm - unfavourable to me. Well, I do not use standard `printf` anyway; just few codes transfered are sufficient. – too honest for this site Sep 15 '15 at 20:57