Skip to content

Improve efficiency and formatting of ITM output #7371

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

Merged
merged 1 commit into from
Jul 5, 2018

Conversation

kjbracey
Copy link
Contributor

@kjbracey kjbracey commented Jun 29, 2018

Description

SerialWireOutput was outputting 1 character per 32-bit write to the ITM stimulus port. This is inefficient, and causes processing problems with some viewers due to them receiving 3 NUL bytes between each desired character.

Rework to allow us to be more efficient, and eliminate those NUL bytes:

  • Retain existing mbed_itm_send() and clarify it's a single 32-bit write.
  • Add new mbed_itm_send_block() that is appropriate for sending character data, and modify SerialWireOutput to use it.
  • Move "wait for FIFO ready" check to before the write, rather than after.

One minor correction - FIFOREADY is a single bit of the register read. Don't interpret reserved bits.

Fixes #7373

Pull request type

[ ] Fix
[X] Refactor
[ ] New target
[ ] Feature
[ ] Breaking change

@kjbracey
Copy link
Contributor Author

@RobMeades - something for you to test. I don't have any ITM boards handy.

@kjbracey kjbracey force-pushed the itm_block branch 2 times, most recently from b88cbca to 0129895 Compare June 29, 2018 09:58
@RobMeades RobMeades mentioned this pull request Jun 29, 2018
@kjbracey
Copy link
Contributor Author

Revised a couple of times - now compiles, at least.

@RobMeades
Copy link
Contributor

Sweet. Performing printf("Hello world %d.\n", x); in a loop now produces the following output in JLink SWO Viewer and in GDB's SWO console:

Hello world 0.
Hello world 1.
Hello world 2.
Hello world 3.
Hello world 4.

@kjbracey
Copy link
Contributor Author

kjbracey commented Jun 29, 2018

I'd be interested to see if you could actually measure a performance boost. Or is the port so fast it doesn't really matter?

It may be that it's not really worth the extra code size of doing the 32-bit writes for the block operation.

@kjbracey
Copy link
Contributor Author

Fixed doxygen - no functional change.

RobMeades added a commit to u-blox/infinite-iot that referenced this pull request Jun 29, 2018
@kjbracey
Copy link
Contributor Author

On efficiency, it's possible the C library doesn't end up doing anything more than single-character write() calls anyway. I believe IAR's C library can't be persuaded to do otherwise, and the other libraries may default to non-buffered and need to be explicitly switched to line- or fully-buffered.

You could perhaps test theoretical throughtput more directly with some manual write(STDOUT_FILENO).

@RobMeades
Copy link
Contributor

For pure printf() output it appears to work quite fast enough: it didn't really work at all in any of the clients available to me before so I can't easily see what the performance improvement might be. If I sit in a tight loop printf()ing 10 characters at a time I notice no loss in GDB and lines go past way faster than I can read; at a very rough estimate 150 kbytes/s.

marcuschangarm
marcuschangarm previously approved these changes Jun 29, 2018
Copy link
Contributor

@marcuschangarm marcuschangarm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

cmonr
cmonr previously approved these changes Jun 30, 2018
Copy link
Contributor

@cmonr cmonr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excited for the changes!

@cmonr
Copy link
Contributor

cmonr commented Jun 30, 2018

/morph build

@cmonr
Copy link
Contributor

cmonr commented Jun 30, 2018

@ARMmbed/mbed-os-maintainers Heads up that this PR adds a new function to HAL.
However, I've marked this as for a patch because 1) this is fixing behavior that should be working, and 2) the API addition does not regress user functionality.

@mbed-ci
Copy link

mbed-ci commented Jun 30, 2018

Build : SUCCESS

Build number : 2486
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/7371/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented Jun 30, 2018

@mbed-ci
Copy link

mbed-ci commented Jun 30, 2018

@kjbracey
Copy link
Contributor Author

kjbracey commented Jul 2, 2018

Sorry - need to correct this. The last commit ca45797 I added was wrong - we do still need the "enabled" checks.

Rereading documentation indicates that writing to the stimulus register is safe when disabled, but we will be getting "not ready" indications when we read, causing us to block indefinitely if disabled.

Removed that commit, leaving just the commit @RobMeades tested.

@0xc0170
Copy link
Contributor

0xc0170 commented Jul 2, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Jul 2, 2018

Build : SUCCESS

Build number : 2494
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/7371/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented Jul 2, 2018

@mbed-ci
Copy link

mbed-ci commented Jul 2, 2018

@cmonr
Copy link
Contributor

cmonr commented Jul 3, 2018

Rebase is needed.

/* Check if ITM and port is enabled */
if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
((ITM->TER & (1UL << port)) != 0UL)) { /* ITM Port enabled */
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra curly brace.

SerialWireOutput was outputting 1 character per 32-bit write to the
ITM stimulus port. This is inefficient, and causes processing problems
with some viewers due to them receiving 3 NUL bytes between each
desired character.

Rework to allow us to be more efficient, and eliminate those NUL bytes:

* Retain existing mbed_itm_send() and clarify it's a single 32-bit write.
* Add new mbed_itm_send_block() that is appropriate for sending
  character data, and modify SerialWireOutput to use it.
* Move "wait for FIFO ready" check to before the write, rather than
  after.

One minor correction - FIFOREADY is a single bit of the register read.
Don't interpret reserved bits.
@kjbracey
Copy link
Contributor Author

kjbracey commented Jul 5, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Jul 5, 2018

Build : SUCCESS

Build number : 2532
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/7371/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented Jul 5, 2018

@mbed-ci
Copy link

mbed-ci commented Jul 5, 2018

@cmonr cmonr merged commit c72da66 into ARMmbed:master Jul 5, 2018
@cmonr cmonr removed the needs: CI label Jul 5, 2018
@kjbracey kjbracey deleted the itm_block branch July 6, 2018 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants