microchip-pic-avr-tools / pymcuprog

a Python utility for programming various Microchip MCU devices using Microchip CMSIS-DAP based debuggers
MIT License
96 stars 22 forks source link

Upload time #10

Closed paulskirk53 closed 2 years ago

paulskirk53 commented 2 years ago

Hi, just to flag this. I have a project which uses an AVR4809 and I program it using pyUPDI. My 13k program takes 34 seconds to upload. For preference I would like to use pymcuprog, but the same code upload takes approx 3 minutes. I am using windows 10 and an FTDI chip as the USB to serial converter. The maximum value I can use for the -c parameter is -c 250k and the command line I use is:

pymcuprog write -d atmega4809 -t uart -u COM17 -c 250k -f .pio\build\ATmega4809\firmware.hex

Any suggestions for how I could improve the upload time would be welcome.

Thanks for considering this

maxgerhardt commented 2 years ago

(see related discussion at https://community.platformio.org/t/using-pymcuprog-for-upload/24514/12?u=maxgerhardt)

xedbg commented 2 years ago

Hi folks, Thanks for this input. I think I know what is missing - will get back to you on that. (Some background for the record: we test serialUPDI functionality in a CI/CD setup, which runs in the night with nobody watching, so it (naïvely) does not care about performance. It runs on CNANO boards which use their own CDC, which is optimized for full USB frames, and thus has poor latency with multiple, short transfers.)

xedbg commented 2 years ago

Logged as DSG-4172

xedbg commented 2 years ago

Indeed - the ACK disable is the trick. There is no need to wait for ACK on each 16-bit write to NVM - this is a huge penalty when running on UART. Simple testing has it 6X faster (on my non-optimised CNANO) this appears to match your figures @paulskirk53

xedbg commented 2 years ago

@paulskirk53 @maxgerhardt I have built a new package and put it on pypi test server: pip install -i https://test.pypi.org/simple/ pymcuprog==3.10.4.136 Note: this has not been fully qualified yet, but bench tested on mega4809 and AVR-DA

paulskirk53 commented 2 years ago

great, thanks for this analysis and for providing a fix so quickly, much appreciated, I'll give it a try.

edit:

I got this error:

pip install -i https://test.pypi.org/simple/ pymcuprog==3.10.4.136
Looking in indexes: https://test.pypi.org/simple/
Collecting pymcuprog==3.10.4.136
  Downloading https://test-files.pythonhosted.org/packages/4b/b1/2e92ea51d1d052092c0fbf0916b6c061f5a3b31716bf49c2f9865c935453/pymcuprog-3.10.4.136-py3-none-any.whl (218 kB)
     |████████████████████████████████| 218 kB 3.3 MB/s
ERROR: Could not find a version that satisfies the requirement pyedbglib>=2.19.5 (from pymcuprog) (from versions: 2.8.39, 2.9.0.40, 2.10.0.43, 2.15.2.58, 2.17.7.70, 2.18.0.73, 2.18.1.74, 2.18.2.75, 2.19.3.86)
ERROR: No matching distribution found for pyedbglib>=2.19.5
xedbg commented 2 years ago

Ah, of course - this build is dependent on other additions in lib. I have pushed pyedbglib 2.19.6.89 out to test.pypi - i think it will be picked up now

paulskirk53 commented 2 years ago

Brill - 20 seconds to upload my 13k bytes, thanks, much appreciate your help with this. :)

maxgerhardt commented 2 years ago

There is no need to wait for ACK on each 16-bit write to NVM - this is a huge penalty when running on UART.

But it still verifies correct firmware transmission at the end with a verify run through either complete readout and comparison or having the MCU compute a hash and send it back?

Is a 2-byte write the largest write size possible in the UPDI protocol? Would strike me as odd. 20 sec for 13K still seems far below other microcontrollers -- that's an effective transfer rate of 0.66 kByte/s.

xedbg commented 2 years ago

@maxgerhardt - verify is done by readback after programming (--verify in pymcuprog). AVR NVM has 'traditionally' been done this way. Yes, there are CRC mechanisms on the device, but they are not intended for verification 'externally'. The ACK mechanism is really for clock-domain crossing (from UPDI to internal bus). Flash is a 16-bit data space, so all writes are word-oriented. I suspect the largest delays are in the python/serial stack - writing 16k using a debugger takes about 2 seconds.

Voncky commented 2 years ago

Hello,

It seems I have also similar problems. I am using self made programmer based on FTDI chip described by attached schematic. Using it on Windows 10 machine. I observed a difference between pymcuprog (slower) and pyUPDI (faster) regardless whether they are launched from within Microchip studio or from command line. In my case I flash Attiny1614 with ~52% of flash memory. I took some measurements, see following: pymcuprog: (command: pymcuprog.exe -d attiny1614 -t uart -u COM8 -b xxxxxx -i updi write -f "linkToFlashHexFile") where xxxxxx is (in mm:ss): 230400: 1:50 115200: 1:50 57600: 1:50 38400: 1:50 19200: 1:50 9600: 3:28 puUPDI: (command: py.exe pyupdi.py -d attiny1614 -c COM8 -b xxxxxx -f "linkToFlashHexFile") where xxxxxx is (in mm:ss): 230400: 0:46 115200: 0:47 57600: 0:50 38400: 0:50 19200: 0:58 9600: 1:32

Baud rates lower than 9600 were not tested by me, but if necessary I can conduct them. May I ask for support - is there something wrong in the commands I have chosen, or is this a general issue which is being solved right now? updi_FT232_with_switch

xedbg commented 2 years ago

@Voncky are you using 3.10 or 3.11? We have not yet qualified 3.11 for release, so its still on test.pypi.org.

Voncky commented 2 years ago

Hi @xedbg - now is much better, similar code has been flashed in ~40 seconds :). Thanks a lot!! One additional question - what is the effect of adding '-i updi' switch in the command? I did not see any difference whether I use it or not. Best regards!

xedbg commented 2 years ago

Hi @Voncky Good to hear its faster - and reminds me we are overdue on releasing that version :/

-i is used to specify the physical interface, although many devices have only one.
pymcuprog can drive any of the EDBG-based tools like atmel-ice, so there are more options available down that track. For example when using ARM parts one has to specify JTAG or SWD, and also the experimental mega328 driver needs ISP or debugWIRE specified.

xedbg commented 2 years ago

fixed in 3.13