avatartwo / avatar2

Python core of avatar²
Apache License 2.0
518 stars 98 forks source link

Fix JLink Target and JLink Protocol. #96

Closed TheSilentDawn closed 2 years ago

TheSilentDawn commented 2 years ago

JLink Target has a lot of bugs and does not work as expected. I have fixed these bugs and tested them by using the Segger JLink EDU emulator and FRDMK64F. Hope this upgrade could help more researchers.

Here is an example using JLinkTarget, and the firmware project could be downloaded from uart_jlink_firmware.zip

from os.path import abspath
from time import sleep
import sys
import time
import datetime

from avatar2 import *

def main():
    finish = 0x554 
    # Configure the location of various files
    fw = abspath('./avatar_uart.bin')

    # Initiate the avatar-object
    avatar = Avatar(arch=ARM_CORTEX_M3, output_directory='/tmp/avatar')

    # Create the target-objects
    k64f = avatar.add_target(JLinkTarget, serial="", device="MK64FN1M0XXX12") # serial number should be your jlink emulator number

    qemu = avatar.add_target(QemuTarget, firmware=fw, gdb_port=1234)

    # Define the various memory ranges and store references to them
    rom  = avatar.add_memory_range(0x0, 0x100000, file=fw)
    ram  = avatar.add_memory_range(0x20000000, 0x30000)
    ram2 = avatar.add_memory_range(0x1fff0000, 0x10000)
    ram3 = avatar.add_memory_range(0x14000000, 0x1000)

    mmio = avatar.add_memory_range(0x40000000, 0x100000, forwarded=True, forwarded_to=k64f)
    mmio2 = avatar.add_memory_range(0xE0000000, 0x100000, forwarded=True, forwarded_to=k64f)

    # Initialize the targets
    avatar.init_targets()
    k64f.reset(halt=True)
    avatar.transfer_state(k64f, qemu, synced_ranges=[])

    qemu.set_breakpoint(finish)
    print(qemu.get_status())
    pc_addr = qemu.read_register('pc')
    print("PC addr is {:#x}".format(pc_addr))

    qemu.cont()
    qemu.wait()
    pc_addr = qemu.read_register('pc')
    if pc_addr == None:
        print("Unable to read PC")
        avatar.shutdown()
    else:
        print("PC addr is {:#x}".format(pc_addr))
        avatar.shutdown()

if __name__ == '__main__':
    main()
mariusmue commented 2 years ago

Hi @TheSilentDawn,

Thank you so much for your PR! Especially appreciated is the test case - unfortunately, we don't have a FRDMK64F around to verify the test case (and chip shortage disallows us to get one in timely manner).

Nonetheless, @rawsample will try to verify that all works with another board+jlink setup, and then we should be able to merge it.

Thank you again!

mariusmue commented 2 years ago

I could finally get hand on a FRDM K64F board verify that the fixes are working as expected! Thank you for your contribution! Merged in, and part of the next release.

PS: I will provide an additional commit to have "serial" defaulting to None, it seems pylink handles the case quite well if only one debugger is connected.