Skip to content
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

--debug output not printingon nrf52840dk #561

Open
bkettle opened this issue Oct 21, 2022 · 11 comments
Open

--debug output not printingon nrf52840dk #561

bkettle opened this issue Oct 21, 2022 · 11 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@bkettle
Copy link

bkettle commented Oct 21, 2022

Hi,

I am hoping to do some work based on OpenSK but am having some difficulty getting the debug printouts to work. Is there something that I am missing in this process?

When I use an unmodified (non-opensk) version of tock, I am able to see the "Initialization complete. Entering main loop'" printout as well as extra printouts made by userspace apps (such as the libtock-c button-print example). Using OpenSK, when I do not have the OpenSK connected to my computer via the USB peripheral cable, I can see this message as well as an explicit print statement that I added in the main loop. When I have the USB peripheral cable connected, I cannot see any of these printouts.

edit: I am now thinking that the issue may be just that pressing the reset button (even without the peripheral usb attached) stops the console writes from showing up. Is this expected behavior?

Expected Behavior

When I start a server in one terminal with:

JLinkExe -device nrf52 -if swd -speed 1000 -autoconnect 1

And a client in another with:

JLinkRTTClient

and then deploy opensk to my board with:

./deploy.py --board=nrf52840dk --opensk --debug --panic-console

I see the Tock initialization printout and additional opensk debug output when going through an example setup flow.

Actual Behavior

There is no output in the RTT terminal beyond the following when the peripheral USB cable is connected and after pushing the reset button to connect:

SEGGER J-Link V7.80b - Real time terminal output
J-Link OB-nRF5340-NordicSemi compiled Dec  3 2021 15:46:49 V1.0, SN=1050271190
Process: JLinkExe

When the peripheral USB cable is not connected, I can see other outputs but cannot see debug print statements (though this could be because I am not able to initiate an authentication flow without the second USB connected)

Steps to Reproduce the Problem

As above.

Specifications

  • Version: stable branch 1b70583
  • Platform: x1 carbon gen 6 running manjaro linux
@bkettle bkettle changed the title --debug output not printing --debug output not printingon nrf52840dk Oct 21, 2022
@kaczmarczyck
Copy link
Collaborator

Following your exact steps, I can't reproduce. The reset button for me does not disconnect RTT, and I still see all prints. I have no guess why the USB cable could be related, or why reset would disable prints.

@kaczmarczyck
Copy link
Collaborator

@jmichelp any ideas?
Otherwise you might have to check your cables again if anything is going on there. Is the behavior consistent across host machines (if you have another to test)? Does the same happen on the develop branch of OpenSK? If you want to try, the deploy command changed a bit, the board name is now nrf52840dk_opensk.

@bkettle
Copy link
Author

bkettle commented Oct 21, 2022

Thanks for the ideas. Unfortunately on the develop branch I was unable to run the deploy script---I got a message about "fatal: No device to configure found" after the apps are written to the device.

@kaczmarczyck
Copy link
Collaborator

If you got that message, it means that you might have flashed OpenSK successfully. As the last step, we try to send a CTAP command to the board to configure it. This last step is performed over the USB port, not the debug port.

There could be different reasons why OpenSK wouldn't properly work after you flashed it:

  1. Your storage is incompatible with develop. You can test that with /deploy.py --board=nrf52840dk_opensk --erase_storage, but be aware that it erases all existing credentials. Then, you deploy again OpenSK.
  2. Maybe it already works, if you connect a USB cable. You can try e.g. https://webauthn.io/ .
  3. You have some of the switches in the wrong position.
    There are 3 switches that need to be in the correct position:
    • Power (bottom left): On
    • nRF power source (center left): VDD
    • SW6 (top right): DEFAULT

There are probably more options, but let's try those first.

@bkettle
Copy link
Author

bkettle commented Oct 21, 2022

When I install the erase_storage app with the command you gave above, I get the same "no device to configure found" message---but I assume this is expected because there is no app to receive the CTAP2 command? After running this, I receive the same message when I try to flash OpenSK normally.

All the switches are in the right place, and unfortunately as far as I can tell the device does not work on webauthn.io (but deploying stable does).

I also periodically get messages from JLinkExe about "CTRL-AP indicates that the device is secured. For debugger connection the device needs to be unsecured. Note: Unsecuring will trigger a mass erase of the internal flash." Is this expected? I recently bought this dev kit, so I'm wondering if I have a newer hardware revision that is inconsistent in some way, and that's causing all my problems.

@kaczmarczyck
Copy link
Collaborator

Having only stable working and not develop is unusual. Usually, erasing the storage before you switch would be the solution for that, since it indicates that hardware is okay.

Could it be that you configured the device to be protected? You can use our configure script with --lock-device and that might be related. It should act as you describe afterwards, not allowing debugging. It doesn't explain the reset behavior though.

@jmichelp Does

CTRL-AP indicates that the device is secured.

sound familiar?

@bkettle
Copy link
Author

bkettle commented Oct 21, 2022

So, to confirm---in the develop branch, I need to have both the debug USB cable and the peripheral USB cable connected, correct? While on stable it works fine to program with only the debug USB cable attached?

@bkettle
Copy link
Author

bkettle commented Oct 21, 2022

OK, I was able to get the develop branch working and somewhat fix the CTRL-AP thing. For future reference in case anyone else has the same problem, I had to download nRF command line tools and run:

nrfjprog -f NRF52 --recover

I'm not sure how I got into the locked state (I think it is called APPROTECT, and I don't think I ever ran a command to lock the device), but this command writes to the registers to disable it as far as I can tell.

If I run this command and then run ./deploy.py --board=nrf52840dk_opensk --debug --opensk, it still says "No device to configure found". However, after the script completes, I am able to see print output from print statements that I added with writeln!(Console::new(), "msg").unwrap(); in the RTT console. If I then connect the non-debug USB cable and press the reset button, the JLink disconnects and reconnects and printouts stop (I added one per iteration of the main loop), but I am then able to successfully go through a registration/authentication flow on webauthn.io.

Interestingly, though, if I then try to re-deploy with ./deploy.py --board=nrf52840dk_opensk --debug --opensk (without first running the nrfjprog command), I get prompted with the JLinkExe prompt from above asking me to unsecure the device during the deployment process. If I do so and allow the script to finish, I cannot see my added printouts and if I connect the USB cable and reset, I am unable to go through the WebAuthn flow (the USB device is not recognized in lsusb).

To me, this seems like OpenSK is securing the device even though I did not instruct it to, and since RST is disconnecting and reconnecting JLink, I am thinking that it doesn't take effect until then. I am also thinking along these lines because if I exit and reconnect JLinkExe after pressing reset, it tells me that I need to unsecure the device. Does this seem at all possible/is there any part of the code that sets this APPROTECT option? According to this article, it is address 0x208 in the UICR. The only place I could find was src/ctap/mod.rs:1389 but I don't think that should be triggered with what I'm doing, so I'm not sure.

Edit: I found this, which definitely seems like it may explain my issues: https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/working-with-the-nrf52-series-improved-approtect. It sounds like the 2022 version of the chip behaves a bit differently than older ones---In particular, the default is now that debugging is disabled, except "after an ERASEALL operation is executed via the CTRL-AP the device should be accessible to a debugger until it executes a pin, power, or brownout reset"

So perhaps this explains the reset behavior. Are you aware of anyone that has developed with OpenSK on this year's version of the board? It sounds like there is some extra register than needs to be set by firmware to unlock debugging after each reset.

@kaczmarczyck
Copy link
Collaborator

Thanks for the investigation, we don't have a 2022 edition dev board, so we haven't been able to reproduce yet. But it's nice that your manual is here for other people who might stumble upon this.

So, to confirm---in the develop branch, I need to have both the debug USB cable and the peripheral USB cable connected, correct? While on stable it works fine to program with only the debug USB cable attached?

You can deploy on both stable and develop with just the debugger cable, but it won't confiure the device with an optional attestation certificate. Which means U2F won't work.

The only place I could find was src/ctap/mod.rs:1389

Correct, we lock the device if you call the configure script with a specific set of parameters. But since you don't do that, your explanation is better :) We should update our documentation to account for 2022 edition hardware.

@kaczmarczyck kaczmarczyck self-assigned this Oct 24, 2022
@kaczmarczyck kaczmarczyck added the documentation Improvements or additions to documentation label Oct 24, 2022
@bkettle
Copy link
Author

bkettle commented Oct 25, 2022

I think there are some code changes necessary in order to support the 2022 boards as well in addition to documentation---in particular:

  1. The APPROTECT register in UICR (0x1000_1208) needs to be set to 0x5A. Currently, it is getting set to 0xFF, which is the APPROTECT DISABLE value for older boards. Newer boards need it to be set to HWDISABLE. I haven't figured out where it is set to 0xFF yet to change it, but running a manual nrfjprog --memwr 0x10001208 --val 0x5a after running the deploy.py command worked for me (could obviously be integrated into deploy.py). This is documented at https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fuicr.html&anchor=register.APPROTECT.
  2. On every reset, the firmware needs to write 0x5a to 0x4000_0558. I wrote some very gross code to achieve this, This is documented at https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fdif.html&cp=4_0_0_3_7_1&anchor=register.DISABLE
    • Also, 0x4000_0550 must not be set to 0x0.

I have debug output working after a reset now with these two changes. I'm happy to try to clean up and share my code if it would be useful, but not sure if I will have time to fully production-ize it to work across revisions (especially since I don't have an older one to test on). And I'm sure there is a much nicer way to do it than what I hacked together with my very limited knowledge of Tock/OpenSK. Relatedly, most of these changes are in third_party/tock. Is there a supported way to export these changes as patches on top of the patches already included in OpenSK?

@ia0
Copy link
Member

ia0 commented Oct 25, 2022

Is there a supported way to export these changes as patches on top of the patches already included in OpenSK?

Assuming third_party/tock contains the changes, you can follow these steps:

  • (cd third_party/tock && git add . && git commit -msave && git branch tmp) to save your changes in the tock submodule.
  • ./maintainers/patches apply to structure the submodules history according to the patches. WARNING: this will erase any unsaved state in the submodules. The output should be Done: Applied the patches to the submodules..
  • (cd third_party/tock && git cherry-pick tmp) to get back your changes.
  • Fix any conflicts in third_party/tock.
  • (optional) Change commit message 14-good-name or merge the change into 04-update-uicr.
  • ./maintainers/patches save to overwrite the patches according to the structure of the submodules history.
  • (optional) (cd third_party/tock && git branch -D tmp) to delete the temporary branch.

The process is simpler if you do ./maintainers/patches apply before doing any changes. Because then it suffices to commit (and possibly rearrange the commit history) and run ./maintainers/patches save to update the patches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

3 participants