Hello,
I want to record the execution trace on our STM32H753 (all the time, in circular buffer mode) and, in some particular cases, output this trace to an external peripheral through SPI (no dedicated tool like Lauterbach).
I understood that I can do this thanks to ETM and ETF, however I couldn't find enough details in the various ARM documentation to make it work.
I tried the following code
volatile uint32_t *ETM_PRGCTRL = (volatile uint32_t *)(0xE0041000 + 4); volatile uint32_t *ETM_LAR = (volatile uint32_t *)(0xE0041000 + 0xFB0); volatile uint32_t *ETM_STAT = (volatile uint32_t *)(0xE0041000 + 0xC); volatile uint32_t *ETM_CONFIG = (volatile uint32_t *)(0xE0041000 + 0x10); #define ETF_BASE_ADDR 0x5C014000 volatile uint32_t *ETF_RRD = (volatile uint32_t *)(ETF_BASE_ADDR + 0x10); volatile uint32_t *ETF_CTL = (volatile uint32_t *)(ETF_BASE_ADDR + 0x20); volatile uint32_t *ETF_FFCR = (volatile uint32_t *)(ETF_BASE_ADDR + 0x304); volatile uint32_t *ETF_TRG = (volatile uint32_t *)(ETF_BASE_ADDR + 0x1C); volatile uint32_t *ETF_STS = (volatile uint32_t *)(ETF_BASE_ADDR + 0x0C); volatile uint32_t *ETF_LAR = (volatile uint32_t *)(ETF_BASE_ADDR + 0xFB0); //volatile uint32_t *CTI_LAR = (volatile uint32_t *)(0xE00F1000 + 0xFB0); //volatile uint32_t *CTI_CTRL = (volatile uint32_t *)(0xE00F1000); //volatile uint32_t *DBGMCU_CR = (volatile uint32_t *)(0xE00E1000 + 0x4); #define DWT_BASE_ADDR 0xE0001000 volatile uint32_t *DWT_CTRL = (volatile uint32_t *)(DWT_BASE_ADDR + 0x0); volatile uint32_t *DWT_COMP0 = (volatile uint32_t *)(DWT_BASE_ADDR + 0x20); volatile uint32_t *DWT_MASK0 = (volatile uint32_t *)(DWT_BASE_ADDR + 0x24); volatile uint32_t *DWT_FUNCT0 = (volatile uint32_t *)(DWT_BASE_ADDR + 0x28); volatile uint32_t *DEMCR = (volatile uint32_t *)(0xE000EDFC); printf("test etm\r\n"); // enable DWT in Debug Exception and Monitor Control Register *DEMCR |= 1<<24; // trace enable // Generates CMPMATCH event: from Archiecture Ref Manual of ARM v7 -> "the CMPMATCH[N] signals // from the DWT unit are available as control inputs to the ETM unit" *DWT_COMP0 = 0x00000000; // adress comparator *DWT_MASK0 = 24; *DWT_FUNCT0 = 0x00000008; // generate CMPMATCH[0] event // setup ETM *ETM_LAR = 0xC5ACCE55; // unlock periph *ETM_CONFIG = (*ETM_CONFIG) | 0x00031F30; // enable all traces *ETM_PRGCTRL = 1; // enable ETM // setup ETF (by default in circular mode) *ETF_LAR = 0xC5ACCE55; // unlock periph *ETF_FFCR = 0x00001123; // ARM recommends to set bits TRIGONTRIGIN FONTRIGEVT STOPONFL ENTI AND ENFT *ETF_TRG = 16; // number of 32 words to capture *ETF_CTL = 1; // enable trace // bullshit processing just to fill the trace U4_INDEX = 1000; while(U4_INDEX--) __asm("nop"); // wait for bit READY while ( ((*ETF_STS) & (1<<2)) == 0 ); // read trace printf("*ETF_RRD=0x%x\r\n", *ETF_RRD); printf("*ETF_RRD=0x%x\r\n", *ETF_RRD); printf("*ETF_RRD=0x%x\r\n", *ETF_RRD); printf("*ETF_RRD=0x%x\r\n", *ETF_RRD); *ETF_CTL = 0; // disable trace
But the bit ready of ETF_STS never raises.
Would you have resources (specific documentation or even better sample code) to share ?
Best regards