- 
                Notifications
    
You must be signed in to change notification settings  - Fork 141
 
Add unlock IDCODE support using indirect API #231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution! Left some comments when you have a chance to take a look.
| callback_override = ctypes.CFUNCTYPE(None, ctypes.c_void_p) | ||
| function = ctypes.cast(function_ptr, callback_override) | ||
| function(self.unlock_idcode_cb) | ||
| return | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return | 
NIT: No need for the return at the very end.
| import ctypes | ||
| 
               | 
          ||
| # Global variable to store the ID code | ||
| global_id_code = None | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A global won't play well with multiple instances (e.g. if someone is debugging two chips at the same time). It looks like we need it for the callback in the dialog. Could we pass a partial function instead? That would allow us to prepopulate the id_code:
import functools
def set_unloock_idcode(self, id_code):
    partial = functools.partial(unlock_idcode_hook_dialog, id_code)
    unlock_idcode_cb = enums.JLinkFunctions.UNLOCK_IDCODE_HOOK_PROTOTYPE(partial)
| global_id_code = None | ||
| 
               | 
          ||
| 
               | 
          ||
| def set_unlock_idcode(self, id_code): | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rename the self -> jlink like in unlock_kinetis?
| global_id_code = id_code | ||
| 
               | 
          ||
| self._dll.JLINK_GetpFunc.restype = ctypes.c_void_p | ||
| self.unlock_idcode_cb = enums.JLinkFunctions.UNLOCK_IDCODE_HOOK_PROTOTYPE(unlock_idcode_hook_dialog) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have to bind the callback to the passed instance? It looks like we pass the value to the SET_HOOK_DIALOG function.
This PR adds support for unlock
IDCODEwhich is one of J-Link indirect API functions. A number of Renesas devices can restrict debug access using a hexadecimal code known as anIDCODE. When a device is locked, the J-Link driver will provide a dialog to enter anIDCODEwhen connecting to the device:With this PR, a user can set the
IDCODEwhich will automatically unlock the device when connecting. There will be no dialog prompt.Usage Example:
When
jlink.set_unlock_idcode()is omitted, the user will get the default J-Link dialog prompt.This was validated on a Renesas S3A7 device using Windows 11 x64 with J-Link V8.12f and an Intel macOS Sequoia with J-Link V8.14.
I tried to follow the contribution guidelines as best I could. I am all ears if you would like something changed. I ended up using a global string to store the
IDCODEdue to the hook callback. I didn't know how else to handle it.Development was performed in Windows. I noticed a few issues with testing:
setuptoolsmust be 71.1.0 or older. Otherwise I seecoveragemust be 4.5.2 or newer to show actual coverage. With current version 4.4.1, coverage isn't detected correctly. For example,pylink\unlockers\unlock_idcode.pyis 36%. 4.5.2 is 96%.