Runprogram() under Linux

Just starting out? Need help? Post your questions and find answers here.
jfbguhamel
New User
New User
Posts: 5
Joined: Wed Mar 27, 2019 7:17 pm
Location: Tarapoto Peru

Runprogram() under Linux

Post by jfbguhamel »

Good morning from Peru
I am currently working on an avrdude interface under Linux with Purebasic. (Fuse calculator almost working)
I have a trouble with obtaining messages display from AVRdude, which works fine in commandline on my system, but I cannot obtain any message from this app with PureBasic, I find the doc is not sufficiently explicit and tried various examples working on this forum, but do not work with AVRdude.
The final objective is to intercept the infos strings sent and displayed in the terminal by AVRdude while programming the chip (and the next step will consist in displaying them in an editorgadget), but I cannot reach any result exept obtaining the exitcode to 0.
I tried this following code, which gives the exitcode only BUT does not display the avrdude help lines as requested (/usr/bin/avrdude -?). The interrogation mark is the help request in this program, not "-h" or "--help"
The code I use to do this trial comes from the PB forum and is:

Code: Select all

Prog = RunProgram("/usr/bin/avrdude", "-?", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_UTF8)
;Prog = RunProgram("/usr/bin/purebasic", "-h", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_UTF8)
If Prog
  While ProgramRunning(Prog)
    If AvailableProgramOutput(Prog)
      Output$ + ReadProgramString(Prog) + #LF$
    EndIf
  Wend

  Output$ + "Exitcode: " + Str(ProgramExitCode(Prog))

  CloseProgram(Prog)

  Debug Output$
EndIf

- This same code applied with the call to purebasic help works fine (in remark), the PB help is displayed.
- I do not need to run as admin as I am already in the dialout goup.
- I made successfully some months ago an graphic interface to program various arduinos and AVR based system to interface with Geany which does its uploading task correctly, but has the same problem: It displays the compile results from GCC/arduino compiler BUT NOT THE avrdude results. (It anyways uploads the program correctly).
- The problem for me is to intercept the commandline messages, not only the exitCode.
- The AVRdude version I use is 6.3. Linux version is Linux Mint 19.1
- Executing "avrdude -?" in a terminal works well and displays its help as well as the real programming results in the terminal, OR the same in a logfile if the" -l" flag is used
The standard Command line result for this help request is:
  • kuki@kuki-HP-14-Notebook-PC:~$ avrdude -?
    Usage: avrdude [options]
    Options:
    -p <partno> Required. Specify AVR device.
    -b <baudrate> Override RS-232 baud rate.
    -B <bitclock> Specify JTAG/STK500v2 bit clock period (us).
    -C <config-file> Specify location of configuration file.
    -c <programmer> Specify programmer type.
    -D Disable auto erase for flash memory
    -i <delay> ISP Clock Delay [in microseconds]
    -P <port> Specify connection port.
    -F Override invalid signature check.
    -e Perform a chip erase.
    -O Perform RC oscillator calibration (see AVR053).
    -U <memtype>:r|w|v:<filename>[:format]
    Memory operation specification.
    Multiple -U options are allowed, each request
    is performed in the order specified.
    -n Do not write anything to the device.
    -V Do not verify.
    -u Disable safemode, default when running from a script.
    -s Silent safemode operation, will not ask you if
    fuses should be changed back.
    -t Enter terminal mode.
    -E <exitspec>[,<exitspec>] List programmer exit specifications.
    -x <extended_param> Pass <extended_param> to programmer.
    -y Count # erase cycles in EEPROM.
    -Y <number> Initialize erase cycle # in EEPROM.
    -v Verbose output. -v -v for more.
    -q Quell progress output. -q -q for less.
    -l logfile Use logfile rather than stderr for diagnostics.
    -? Display this usage.

    avrdude version 6.3-20171130, URL: <http://savannah.nongnu.org/projects/avrdude/>
Any help would be welcomed, as I am having headache with this.
Best regards
Why do it simple when it can be done complicated
infratec
Always Here
Always Here
Posts: 6874
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Runprogram() under Linux

Post by infratec »

If you look into the source code of avrdude you will find

Code: Select all

int avrdude_message(const int msglvl, const char *format, ...)
{
    int rc = 0;
    va_list ap;
    if (verbose >= msglvl) {
        va_start(ap, format);
        rc = vfprintf(stderr, format, ap);
        va_end(ap);
    }
    return rc;
} 
Here you can see that avrdude writes his output to stderr and not to stdout.
So, you have to read in stderr (also).
Look at

Code: Select all

ReadProgramError()
You can also look at an example from me, where I check both.

Bernd
jfbguhamel
New User
New User
Posts: 5
Joined: Wed Mar 27, 2019 7:17 pm
Location: Tarapoto Peru

Re: Runprogram() under Linux

Post by jfbguhamel »

Hi Bernd, thank you for answering.
I have tried the following example, which works, but has apparently speed flows in displaying the strings, and the message comes uncomplete to the messagerequester.

Code: Select all

;runprogram (AVRDUDE)

exe$="/usr/bin/avrdude" : param$="-?" 
;exe$="dir" : param$="c:" ; Output returned correctly for this.

;p=RunProgram(exe$,param$,"",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Read|#PB_Program_Error)
p=RunProgram(exe$,param$,"",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Error)

If p

  While ProgramRunning(p)
      err$ = ReadProgramError(p)
    If err$
      o$ + "<err> " + err$ +Chr(13)
    EndIf
;     ElseIf AvailableProgramOutput(p)
;       o$+ReadProgramString(p)+Chr(13)
;     EndIf

  Wend
  CloseProgram(p)

  MessageRequester("Output",o$)
EndIf
I had to remove the "#PB_Program_Read" flag as well as the StdOut test loop in order to obtain the completeness of the help messages of avrdude, because elsewise, it comes truncated in the messagerequester. I think the stderr has no control of the text flow and the program ends before the strings are completely displayed. The solution would consist in a buffer to store temporarily the strings until I can give then to eat to the editorgadget, but I do not know how to do it, so I will try an array.
Best regards
Last edited by jfbguhamel on Mon Apr 15, 2019 11:56 pm, edited 1 time in total.
Why do it simple when it can be done complicated
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: Runprogram() under Linux

Post by vwidmer »

You can always redirect stderr to stdout :)

Code: Select all

Procedure.s BashRun(prun.s)
  Program = RunProgram("bash", "-c "+#DQUOTE$+prun.s+#DQUOTE$+"","", #PB_Program_Open|#PB_Program_Read|#PB_Program_Write|#PB_Program_Error|#PB_Program_UTF8)
  If Program
    While ProgramRunning(Program)
      If AvailableProgramOutput(Program)
        Output$ + ReadProgramString(Program) + Chr(13)
      EndIf
    Wend
   
    CloseProgram(Program) ; Close the connection to the program
  EndIf
  ProcedureReturn Output$
EndProcedure

OpenConsole()
Result$ = BashRun("avrdude -? 2>&1")
PrintN(Result$)
Debug Result$
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
jfbguhamel
New User
New User
Posts: 5
Joined: Wed Mar 27, 2019 7:17 pm
Location: Tarapoto Peru

Re: Runprogram() under Linux

Post by jfbguhamel »

@vwidmer,
Your solution works very nicely and all the time !
Thank you very much, I is a very clever way to do so. I did not know it was possible to redirect fm stderr to stdout, this prevents "eating" the messages. I do not understand why the avrdude guys did go the stderr way.
Best regards and thanks a lot. I will post the arrangements I will make. I was even thinking recompiling avrdude!
Why do it simple when it can be done complicated
Post Reply