Skip to content

Commit c72da66

Browse files
author
Cruz Monrreal
authored
Merge pull request #7371 from kjbracey-arm/itm_block
Improve efficiency and formatting of ITM output
2 parents cec30ae + 0f98338 commit c72da66

File tree

3 files changed

+72
-14
lines changed

3 files changed

+72
-14
lines changed

drivers/SerialWireOutput.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,8 @@ class SerialWireOutput : public FileHandle {
3333

3434
virtual ssize_t write(const void *buffer, size_t size)
3535
{
36-
const unsigned char *buf = static_cast<const unsigned char *>(buffer);
36+
mbed_itm_send_block(ITM_PORT_SWO, buffer, size);
3737

38-
/* Send buffer one character at a time over the ITM SWO port */
39-
for (size_t i = 0; i < size; i++) {
40-
mbed_itm_send(ITM_PORT_SWO, buf[i]);
41-
}
4238
return size;
4339
}
4440

hal/itm_api.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#if defined(DEVICE_ITM)
2323

2424
#include <stdint.h>
25+
#include <stddef.h>
2526

2627
#ifdef __cplusplus
2728
extern "C" {
@@ -68,12 +69,26 @@ void mbed_itm_init(void);
6869
* @brief Send data over ITM stimulus port.
6970
*
7071
* @param[in] port The stimulus port to send data over.
71-
* @param[in] data The data to send.
72+
* @param[in] data The 32-bit data to send.
73+
*
74+
* The data is written as a single 32-bit write to the port.
7275
*
7376
* @return value of data sent.
7477
*/
7578
uint32_t mbed_itm_send(uint32_t port, uint32_t data);
7679

80+
/**
81+
* @brief Send a block of data over ITM stimulus port.
82+
*
83+
* @param[in] port The stimulus port to send data over.
84+
* @param[in] data The block of data to send.
85+
* @param[in] len The number of bytes of data to send.
86+
*
87+
* The data is written using multiple appropriately-sized port accesses for
88+
* efficient transfer.
89+
*/
90+
void mbed_itm_send_block(uint32_t port, const void *data, size_t len);
91+
7792
/**@}*/
7893

7994
#ifdef __cplusplus

hal/mbed_itm_api.c

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121

2222
#include <stdbool.h>
2323

24+
#ifndef ITM_STIM_FIFOREADY_Msk
25+
#define ITM_STIM_FIFOREADY_Msk 1
26+
#endif
27+
2428
#define ITM_ENABLE_WRITE 0xC5ACCE55
2529

2630
#define SWO_NRZ 0x02
@@ -66,21 +70,64 @@ void mbed_itm_init(void)
6670
}
6771
}
6872

73+
static void itm_out8(uint32_t port, uint8_t data)
74+
{
75+
/* Wait until port is available */
76+
while ((ITM->PORT[port].u32 & ITM_STIM_FIFOREADY_Msk) == 0) {
77+
__NOP();
78+
}
79+
80+
/* write data to port */
81+
ITM->PORT[port].u8 = data;
82+
}
83+
84+
static void itm_out32(uint32_t port, uint32_t data)
85+
{
86+
/* Wait until port is available */
87+
while ((ITM->PORT[port].u32 & ITM_STIM_FIFOREADY_Msk) == 0) {
88+
__NOP();
89+
}
90+
91+
/* write data to port */
92+
ITM->PORT[port].u32 = data;
93+
}
94+
6995
uint32_t mbed_itm_send(uint32_t port, uint32_t data)
7096
{
7197
/* Check if ITM and port is enabled */
7298
if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
73-
((ITM->TER & (1UL << port)) != 0UL)) { /* ITM Port enabled */
74-
/* write data to port */
75-
ITM->PORT[port].u32 = data;
76-
77-
/* Wait until data has been clocked out */
78-
while (ITM->PORT[port].u32 == 0UL) {
79-
__NOP();
80-
}
99+
((ITM->TER & (1UL << port)) != 0UL)) { /* ITM Port enabled */
100+
itm_out32(port, data);
81101
}
82102

83103
return data;
84104
}
85105

106+
void mbed_itm_send_block(uint32_t port, const void *data, size_t len)
107+
{
108+
const char *ptr = data;
109+
110+
/* Check if ITM and port is enabled */
111+
if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
112+
((ITM->TER & (1UL << port)) != 0UL)) { /* ITM Port enabled */
113+
/* Output single byte at a time until data is aligned */
114+
while ((((uintptr_t) ptr) & 3) && len != 0) {
115+
itm_out8(port, *ptr++);
116+
len--;
117+
}
118+
119+
/* Output bulk of data one word at a time */
120+
while (len >= 4) {
121+
itm_out32(port, *(const uint32_t *) ptr);
122+
ptr += 4;
123+
len -= 4;
124+
}
125+
126+
/* Output any trailing bytes */
127+
while (len != 0) {
128+
itm_out8(port, *ptr++);
129+
len--;
130+
}
131+
}
132+
}
86133
#endif // defined(DEVICE_ITM)

0 commit comments

Comments
 (0)