square / pylink

Python Library for device debugging/programming via J-Link
https://pylink.readthedocs.io/en/latest/
Other
352 stars 128 forks source link

Old buffer contents #26

Open tj57 opened 6 years ago

tj57 commented 6 years ago

I have found small issue, When I use flash_file function or bigger buffer and next flash function with small buffer contents of the old buffer are still programmed. jtag_flush() don't help. Is there another function to flush buffer ? Please check last bytes after memory_read8

Here is my log

>>> import pylink
>>> jlink = pylink.JLink()
>>> serial_no = 'xxxxxxxx'
>>> jlink.open(serial_no)
>>> jlink.product_name
'SEGGER J-Link ARM'
>>> jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
True
>>> jlink.connect('STM32F405RG', verbose=True)
>>> jlink.erase()
0
>>> jlink.memory_read8(0x8000000, 20)
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> data1 = [ 11, 11, 11, 11, 11, 11, 11]
>>> jlink.flash(data1, 0x8000000)
16384
>>> jlink.memory_read8(0x8000000, 20)
[11, 11, 11, 11, 11, 11, 11, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> data2 = [ 22, 22, 22, 22, 22, 22, 22]
>>> jlink.flash(data2, 0x8000001)
16384
>>> jlink.memory_read8(0x8000000, 20)
[11, 22, 22, 22, 22, 22, 22, 22, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> jlink.flash_file('/root/ch.bin', 0x8000000)
0
>>> jlink.memory_read8(0x8000000, 20)
[0, 4, 0, 32, 185, 2, 0, 8, 187, 2, 0, 8, 81, 26, 0, 8, 186, 2, 0, 8]
>>> jlink.erase()
0
>>> jlink.memory_read8(0x8000000, 20)
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> jlink.flash(data1, 0x8000000)
16384
>>> jlink.memory_read8(0x8000000, 20)
[11, 11, 11, 11, 11, 11, 11, 8, 187, 2, 0, 8, 81, 26, 0, 8, 186, 2, 0, 8]
>>> jlink.jtag_flush()
>>> jlink.erase()
0
>>> jlink.memory_read8(0x8000000, 20)
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> data1
[11, 11, 11, 11, 11, 11, 11]
>>> jlink.flash(data1, 0x8000000)
16384
>>> jlink.memory_read8(0x8000000, 20)
[11, 11, 11, 11, 11, 11, 11, 8, 187, 2, 0, 8, 81, 26, 0, 8, 186, 2, 0, 8]
>>> data3 = [33, 33, 33]
>>> jlink.jtag_flush()
>>> jlink.erase()
0
>>> jlink.memory_read8(0x8000000, 20)
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> jlink.flash(data3, 0x8000000)
16384
>>> jlink.memory_read8(0x8000000, 20)
[33, 33, 33, 11, 11, 11, 11, 8, 187, 2, 0, 8, 81, 26, 0, 8, 186, 2, 0, 8]
hkpeprah commented 6 years ago

This sounds like the internal buffer still hasn't finished flashing. You might want to use the progress callback to check for the flash having completed before proceeding with flashing the next set of data.

import threading

sem = threading.Semaphore(0)

def on_progress(action, progress_string, percentage):
    if round(percentage) == 100 and action.lower() == 'verify':
        # Finished verification, so flashing is done.
        sem.release()
    return None

jlink.flash(data, address, on_progress=on_progress)
sem.acquire()  # Block until flashing is done

This functionality also might be good to add as a new feature as well.

tj57 commented 6 years ago

I have tested with this function and wait for semaphore, but I got the same effect old buffer is flashed.

tj57 commented 6 years ago

I tested this scenario with Jlink Commander script, it work correctly. Problem with internal buffer exist in pylink.

hkpeprah commented 6 years ago

The flashing here is a bit different than the one that occurs by the commander. The DLL stores the data into an internal buffer, and writes it over flash, so a subsequent call could come in before that buffer has been flushed.

Could you try putting a large-ish sleep after you flash the large data, and see if it helps. If so, I'd check what is being printed by the progress callback, and see what the last action you get is; I may have been wrong in the 'verify' action. If I have some cycles later, I can look into creating a large-ish image, and see what happens.

tj57 commented 6 years ago

I have added time.sleep(60) after each step, it did't help, the same effect. Callback function printed all steps, log looks correctly.