Skip to content

Commit

Permalink
imxrt-multi: change RTT initialization
Browse files Browse the repository at this point in the history
Remove hard-coded RTT address and get it from memory map.
Change RTT initialization to keep existing buffer contents if buffers
are valid.

JIRA: RTOS-754
  • Loading branch information
jmaksymowicz committed Sep 26, 2024
1 parent 05e9866 commit 133fd0e
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 43 deletions.
70 changes: 59 additions & 11 deletions librtt/librtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,37 +289,85 @@ int librtt_txCheckReaderAttached(unsigned int ch)
}


int librtt_init(void *addr, librtt_cacheOp_t invalFn, librtt_cacheOp_t cleanFn)
static int librtt_verifyChannel(volatile struct rtt_desc *rtt, unsigned int ch, unsigned char *buffers, size_t buffersSize)
{
if ((LIBRTT_DESC_SIZE < sizeof(struct rtt_desc)) || (librtt_common.rtt != NULL)) {
unsigned char *bufEnd = buffers + buffersSize;
size_t sz = rtt->channel[ch].sz;
/* Check buffer size is non-zero and power of 2 */
if ((sz == 0) || ((sz & (sz - 1)) != 0)) {
return -EINVAL;
}

librtt_common.invalFn = invalFn;
librtt_common.cleanFn = cleanFn;
if ((rtt->channel[ch].ptr < buffers) || (rtt->channel[ch].ptr >= bufEnd)) {
return -EINVAL;
}

volatile struct rtt_desc *rtt = addr;
if (((rtt->channel[ch].ptr + rtt->channel[ch].sz) <= buffers) || ((rtt->channel[ch].ptr + rtt->channel[ch].sz) > bufEnd)) {
return -EINVAL;
}

return 0;
}


int librtt_verify(void *addr, size_t cbSize, void *buffers, size_t buffersSize, librtt_cacheOp_t invalFn, librtt_cacheOp_t cleanFn)
{
int n, ret;
if ((cbSize < sizeof(struct rtt_desc))) {
return -EINVAL;
}

int n;
volatile struct rtt_desc *rtt = addr;
for (n = 0; n < librtt_tagLength; n++) {
if (librtt_tagReversed[n] != rtt->tag[librtt_tagLength - 1 - n]) {
break;
}
}

if (n == librtt_tagLength) {
if ((rtt->txChannels + rtt->rxChannels) <= (LIBRTT_TXCHANNELS + LIBRTT_RXCHANNELS)) {
librtt_common.rtt = rtt;
return 0;
if (n != librtt_tagLength) {
return -EINVAL;
}

if ((rtt->txChannels > LIBRTT_TXCHANNELS) || (rtt->rxChannels > LIBRTT_RXCHANNELS)) {
return -EINVAL;
}

int totalChannels = rtt->txChannels + rtt->rxChannels;
for (n = 0; n < totalChannels; n++) {
ret = librtt_verifyChannel(rtt, n, buffers, buffersSize);
if (ret != 0) {
return ret;
}

if (n < LIBRTT_TXCHANNELS) {
librtt_common.lastRd[n] = rtt->channel[n].rd;
}
}

librtt_common.invalFn = invalFn;
librtt_common.cleanFn = cleanFn;
librtt_common.rtt = rtt;
return 0;
}


int librtt_init(void *addr, librtt_cacheOp_t invalFn, librtt_cacheOp_t cleanFn)
{
if ((LIBRTT_DESC_SIZE < sizeof(struct rtt_desc)) || (librtt_common.rtt != NULL)) {
return -EINVAL;
}

librtt_common.invalFn = invalFn;
librtt_common.cleanFn = cleanFn;

volatile struct rtt_desc *rtt = addr;

memset((void *)rtt, 0, sizeof(*rtt));

rtt->txChannels = LIBRTT_TXCHANNELS;
rtt->rxChannels = LIBRTT_RXCHANNELS;

for (n = 0; n < librtt_tagLength; n++) {
for (int n = 0; n < librtt_tagLength; n++) {
rtt->tag[librtt_tagLength - 1 - n] = librtt_tagReversed[n];
}

Expand Down
6 changes: 5 additions & 1 deletion librtt/librtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
typedef int (*librtt_cacheOp_t)(void *addr, unsigned int sz);


/* Initialize rtt descriptor if it is not initialized already */
/* Verify contents of rtt descriptor and initialize data structure if successful */
int librtt_verify(void *addr, size_t cbSize, void *buffers, size_t buffersSize, librtt_cacheOp_t invalFn, librtt_cacheOp_t cleanFn);


/* Initialize rtt descriptor */
int librtt_init(void *addr, librtt_cacheOp_t invalFn, librtt_cacheOp_t cleanFn);


Expand Down
102 changes: 71 additions & 31 deletions multi/imxrt-multi/rtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@
#include "rtt.h"


#ifndef RTT_ADDR
/* RTT descriptors location, last 256 bytes of DTCM */
#define RTT_ADDR (0x20040000 - 0x100)
#endif

#define RTT_MAP_NAME "rtt"
#define RTT_TX_BUF_SIZE 1024
#define RTT_RX_BUF_SIZE 256
#define RTT_POLLING_RATE_MS 20
Expand Down Expand Up @@ -147,8 +143,11 @@ static int rtt_initOne(rtt_t *uart, int chn, unsigned char *buf)
uart->chn = chn;

int ret = 0;
ret = (ret == 0) ? librtt_initChannel(1, chn, buf, RTT_TX_BUF_SIZE) : ret;
ret = (ret == 0) ? librtt_initChannel(0, chn, buf + RTT_TX_BUF_SIZE, RTT_RX_BUF_SIZE) : ret;
if (buf != NULL) {
ret = (ret == 0) ? librtt_initChannel(1, chn, buf, RTT_TX_BUF_SIZE) : ret;
ret = (ret == 0) ? librtt_initChannel(0, chn, buf + RTT_TX_BUF_SIZE, RTT_RX_BUF_SIZE) : ret;
}

ret = (ret == 0) ? mutexCreate(&uart->lock) : ret;
/* TODO: calculate approx. baud rate based on buffer size and polling rate */
ret = (ret == 0) ? libtty_init(&uart->tty_common, &callbacks, TTY_BUF_SIZE, libtty_int_to_baudrate(115200)) : ret;
Expand All @@ -157,49 +156,90 @@ static int rtt_initOne(rtt_t *uart, int chn, unsigned char *buf)
}


int rtt_init(void)
static int rtt_getMemInfo(void **rttMemPtr_out, size_t *rttMemSz_out)
{
if (RTT_ACTIVE_CNT == 0) {
return EOK;
void *rttMemPtr = NULL;
size_t rttMemSz = 0;
meminfo_t mi;
mi.page.mapsz = -1;
mi.entry.kmapsz = -1;
mi.entry.mapsz = -1;
mi.maps.mapsz = 0;
mi.maps.map = NULL;
meminfo(&mi);

mi.maps.map = malloc(mi.maps.mapsz * sizeof(mapinfo_t));
if (mi.maps.map == NULL) {
return -ENOMEM;
}

/* Reserve memory for the descriptor and buffers */
intptr_t startAddr = (RTT_ADDR - (RTT_ACTIVE_CNT * (RTT_TX_BUF_SIZE + RTT_RX_BUF_SIZE))) & ~(_PAGE_SIZE - 1);
size_t mapSize = RTT_ADDR + LIBRTT_DESC_SIZE - startAddr;
unsigned char *rttBuffer = mmap(
NULL,
mapSize,
PROT_WRITE | PROT_READ,
MAP_ANONYMOUS | MAP_UNCACHED | MAP_PHYSMEM,
-1,
startAddr);
meminfo(&mi);
for (int i = 0; i < mi.maps.mapsz; i++) {
if (strcmp(mi.maps.map[i].name, RTT_MAP_NAME) == 0) {

Check failure on line 178 in multi/imxrt-multi/rtt.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt105x-evk)

'mapinfo_t' {aka 'struct <anonymous>'} has no member named 'name'

Check failure on line 178 in multi/imxrt-multi/rtt.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt106x-evk)

'mapinfo_t' {aka 'struct <anonymous>'} has no member named 'name'

Check failure on line 178 in multi/imxrt-multi/rtt.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt117x-evk)

'mapinfo_t' {aka 'struct <anonymous>'} has no member named 'name'
rttMemPtr = (void *)mi.maps.map[i].vstart;
rttMemSz = mi.maps.map[i].vend - mi.maps.map[i].vstart;
break;
}
}

if (rttBuffer == MAP_FAILED) {
return -ENOMEM;
free(mi.maps.map);
if (rttMemPtr == NULL) {
return -ENODEV;
}

int ret = librtt_init((void *)RTT_ADDR, NULL, NULL);
*rttMemPtr_out = rttMemPtr;
*rttMemSz_out = rttMemSz;
return EOK;
}


int rtt_init(void)
{
int doInit = 0;
void *rttMemPtr = NULL;
size_t rttMemSz = 0;
int ret = rtt_getMemInfo(&rttMemPtr, &rttMemSz);
if (ret != 0) {
librtt_done();
munmap(rttBuffer, mapSize);
return ret;
}

unsigned char *buf = rttBuffer;
for (int i = 0, chn = 0; chn < RTT_CHANNEL_CNT; ++chn) {
size_t bufSz = rttMemSz - LIBRTT_DESC_SIZE;
void *cbAddr = rttMemPtr + bufSz;
ret = librtt_verify(
cbAddr,
LIBRTT_DESC_SIZE,
rttMemPtr,
bufSz,
NULL,
NULL);
if (ret != 0) {
doInit = 1;
ret = librtt_init(cbAddr, NULL, NULL);
if (ret != 0) {
return ret;
}
}

unsigned char *buf = (doInit != 0) ? rttMemPtr : NULL;
unsigned char *nextBuf = buf;
for (int i = 0, chn = 0; chn < RTT_CHANNEL_CNT; chn++, buf = nextBuf) {
if (rttConfig[chn] == 0) {
continue;
}

rtt_t *uart = &rtt_common.uarts[i++];
int ret = rtt_initOne(uart, chn, buf);
if (buf != NULL) {
nextBuf = buf + RTT_TX_BUF_SIZE + RTT_RX_BUF_SIZE;
if ((nextBuf - (unsigned char *)rttMemPtr) > bufSz) {
break;
}
}

ret = rtt_initOne(uart, chn, buf);
if (ret != 0) {
librtt_done();
munmap(rttBuffer, mapSize);
return ret;
}

buf += RTT_RX_BUF_SIZE + RTT_TX_BUF_SIZE;
}

beginthread(rtt_thread, IMXRT_MULTI_PRIO, rtt_common.stack, sizeof(rtt_common.stack), NULL);
Expand Down

0 comments on commit 133fd0e

Please sign in to comment.