Programming: Uploading Firmware (Was: Cannot Move Uploaded File)

Running Legacy on Windows with WAMP. This is a new installation so the issue could be anywhere, I’m just looking for a tip to trace it down.

When I try to program via the web interface I instantly get a pop-up saying:

brewpi says:

Error while programming: cannot move uploaded file

So far I have checked in phpinfo() that upload_tmp_dir is set to c:/wamp64/tmp and this directory has ‘Everyone’ set to Full Access.

I’m hoping someone else has seen this … ?

Okay … I’ll answer myself.

So far it looks like a permissions issue related to the $instanceRoot/uploads/ directory. I have to manually delete the file from there from a previous attempt, then it will go.

Now it does nothing. I expect it to try to open the port but all I get is a blank screen.

Should this work on Windows?

On windows, I would just use xloader the load the hex file on your Arduino.

Thanks for the reply.

I can do that - and I have other ways to flash the Arduino. What I’m curious about however is whether it should work, or if it’s just an untested thing. If it’s not supposed to work on Windows I’ll quit banging my head against it, but if it’s supposed to work I’d like to figure it out.

Right now the whole open a socket thing seems to not do a thing (in that part of the code). I get nothing in the logs at all.

Try running it as admin?

WAMP configures itself to run as Admin via the parameters on the shortcut. Explicitly running as Administrator has no effect on the result.

The log window will show old log entries, but the programming button will not spawn AVRDude.

OK, my bad. I know you said manually deleting the file allows it to work, so maybe the issue is in the overwrite line. Phone posting so I can’t look at the code, sorry, but I know interpreted languages on windows tend to be finicky about absolute paths. Maybe there’s an execution path vs absolute path issue in the rotation logic or a missing // instead of / that turns into an escape character?

The log files are created by piping the python output to files in the cron job that starts the script.
If the script is started manually, the log files won’t be created and you’ll just have to look at the python output directly.

Understood. I’ve been stepping through the code and I can’t see where programming the Arduino would create any output so I’m no longer using that as an indication of success or failure.

I have been using this to start my script under Windows to emulate the crontab entry/functionality so I am creating logs:

@ECHO OFF

python brewpi.py --checkstartuponly --dontrunfile
IF %ERRORLEVEL% NEQ 1 GOTO END

:STARTUP
python -u brewpi.py --config "%~dp0settings\config.cfg" 1>"%~dp0logs\stdout.txt" 2>>"%~dp0logs\stderr.txt"

:END

Not that the logs are the issue of course.

No bad about it - I appreciate you kicking it around with me.

So here are some things I know. If I intentionally generate an error - by clicking “Program” before selecting a Hex file for instance, I get the expected pop-up and the stderr.txt from a previous run of the brewpi.py script becomes visible. So, I know I am reading my config_user.php file, and I know it’s pointing to the right place.

Looking at the program_arduino.php file, this is where the error “cannot move uploaded file” is raised. If I delete the hex file from a previous try in the $instanceRoot/uploads/ directory, I avoid the error. Immediately after that it attempts to open a socket with $sock = open_socket();. Dropping in a debug message popup after if($sock !== false){ works, leading me to believe we successfully create a socket.

All good so far right?

Well the rest is concatenating the $cmd string and then finally doing the socket_write.

When we come back we look at socket_read($sock, 1024); to check success:

	// script will return 1 on success and 0 on failure. This blocks the post request until done
	$programmingResult = socket_read($sock, 1024);
	if(strlen($programmingResult)<1){
		$programmingResult = 0;
	}
	socket_close($sock);

From this I am getting 0 so it’s failing. I don’t know why.

On Windows the script will default to using a port socket on localhost:6332.
I am not sure if you have changed anything that would prevent that from happening.

Hmm … I do have McAfee running (controlled by Corporate) and Windows Firewall (also centrally controlled) but when I use PortQry I can see that nothing else is listening there and it’s not blocked:

Starting portqry.exe -n 127.0.0.1 -e 6338 -p BOTH ...

Querying target system called:
 127.0.0.1
Attempting to resolve IP address to a name...

IP address resolved to brewpi
querying...
TCP port 6338 (unknown service): NOT LISTENING
UDP port 6338 (unknown service): NOT LISTENING
portqry.exe -n 127.0.0.1 -e 6338 -p BOTH exits with return code 0x00000001.

It’s an interesting line of thought though. I don’t know that McAfee is not blocking it in some way. I’ll try this on a different computer upon which I can control the firewall and AV and see if there’s any change.

To be sure about this: I don’t have to make any changes to the config.cfg? This section is commented out:

# on Windows, the scripts defaults to an Internet socket instead of a system socket.
# useInetSocket=true
# socketPort=6332
# socketHost=127.0.0.1

I don’t have to uncomment that do I?

6338 != 6332

It should detect windows and switch to port based communication automatically.

Doh!

I had a new contact lens prescription in yesterday, I guess I saw/typed it incorrectly. :slight_smile: Oddly enough, I get much different results when checking the correct port:

Starting portqry.exe -n 127.0.0.1 -e 6332 -p BOTH ...

Querying target system called:
 127.0.0.1
Attempting to resolve IP address to a name...

IP address resolved to brewpi
querying...
TCP port 6332 (unknown service): NOT LISTENING
UDP port 6332 (unknown service): LISTENING or FILTERED
portqry.exe -n 127.0.0.1 -e 6332 -p BOTH exits with return code 0x00000002.

Checking with netstat gives me nothing.

This is still on my work laptop. I’ve not had a chance to try it on one of my home systems where I control the AV and firewall.

I put this on my home computer. Verified the ports were clear. Questionable results:

**** Arduino Program script started ****
Settings will not be restored
Devices will not be restored
Oct 22 2016 13:01:27 Opening serial port
Loading programming settings from board.txt
Could not read boards.txt from Arduino, probably because Arduino has not been installed
Please install it with: sudo apt-get install arduino-core

Now this is Windows of course, Arduino is installed. Config.cfg has the following configuration for the Arduino:

arduinoHome = C:\Arduino\
avrdudeHome = C:\Arduino\hardware\tools\avr\bin
avrsizeHome = C:\Arduino\hardware\tools\avr\bin
avrConf = C:\Arduino\hardware\tools\avr\etc

I verified Boards.txt is in the installation in C:\Arduino\hardware\arduino\avr

After that message I have to shut down the script and re-start it in order to get anything to happen.

To get this far I had to have the script running, is that expected behavior? It seems to me that would be a conflict but I guess I’m wrong.

Anyway, it feels like I am closer. Maybe my config is off somehow?

I would forget about trying to program the Arduino via the web interface. Just flash it with xloader, then try to run the script.

I can do that Elco, and I have done it as well as used AVRDude and other tools. This is really just about trying to make it all work under Windows so I can say I made it work under Windows. I’ve been documenting the process here and figured it could serve as a template for others to follow.

I just have to believe I’m close somehow. I’ll keep banging my head against it. I know it’s got to be a config or path thing.

I know, but there is no point in getting programming to work. There will be no updates for the Arduino version, so you only have to program it once.

Elco