-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
hal/imxrt: Support RTT as a HAL console
UART is enabled by default (current behavior), but can be turned off by defining UART_CONSOLE_KERNEL with an empty value. RTT is enabled by defining RTT_ENABLED with a truthy value and (optionally) selecting a channel to use by RTT_CONSOLE_KERNEL (0-based). UART and RTT may be used at the same time. RTT driver reuses the control block configured by plo, which must also create a map named via RTT_SYSPAGE_MAP_NAME (default: "rtt"). Channel configuration is not altered at all, so RTT will work even when user-mode driver takes control - exception dumps will still be printed. JIRA: RTOS-754
- Loading branch information
Showing
6 changed files
with
375 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/* | ||
* Phoenix-RTOS | ||
* | ||
* SEGGER's Real Time Transfer - simplified driver | ||
* | ||
* Copyright 2023-2024 Phoenix Systems | ||
* Author: Gerard Swiderski, Daniel Sawka | ||
* | ||
* This file is part of Phoenix-RTOS. | ||
* | ||
* %LICENSE% | ||
*/ | ||
|
||
#include "include/errno.h" | ||
#include "syspage.h" | ||
#include "hal/arm/barriers.h" | ||
|
||
#include <board_config.h> | ||
#include "rtt.h" | ||
|
||
#ifndef RTT_SYSPAGE_MAP_NAME | ||
#define RTT_SYSPAGE_MAP_NAME "rtt" | ||
#endif | ||
|
||
#ifndef RTT_CB_SIZE | ||
#define RTT_CB_SIZE 256 | ||
#endif | ||
|
||
|
||
struct rtt_pipe { | ||
const char *name; | ||
volatile unsigned char *ptr; | ||
unsigned int sz; | ||
volatile unsigned int wr; | ||
volatile unsigned int rd; | ||
unsigned int flags; | ||
}; | ||
|
||
|
||
struct rtt_desc { | ||
char tag[16]; | ||
unsigned int txChannels; | ||
unsigned int rxChannels; | ||
struct rtt_pipe channels[]; | ||
}; | ||
|
||
|
||
static struct { | ||
volatile struct rtt_desc *rtt; | ||
} common; | ||
|
||
|
||
int rtt_check(int chan, rtt_dir_t dir) | ||
{ | ||
if (chan < 0) { | ||
return -EINVAL; | ||
} | ||
|
||
if (common.rtt == NULL) { | ||
return -ENODEV; | ||
} | ||
|
||
if ((dir == rtt_dir_up) && (chan >= common.rtt->txChannels)) { | ||
return -ENODEV; | ||
} | ||
|
||
if ((dir == rtt_dir_down) && (chan >= common.rtt->rxChannels)) { | ||
return -ENODEV; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
|
||
int _hal_rttRead(int chan, void *buf, unsigned int count) | ||
{ | ||
if (rtt_check(chan, rtt_dir_down) < 0) { | ||
return -ENODEV; | ||
} | ||
|
||
volatile struct rtt_desc *rtt = common.rtt; | ||
|
||
hal_cpuDataMemoryBarrier(); | ||
chan = rtt->txChannels + chan; | ||
volatile unsigned char *srcBuf = rtt->channels[chan].ptr; | ||
unsigned char *dstBuf = (unsigned char *)buf; | ||
unsigned int sz = rtt->channels[chan].sz - 1; | ||
unsigned int rd = rtt->channels[chan].rd & sz; | ||
unsigned int wr = rtt->channels[chan].wr & sz; | ||
unsigned int todo = count; | ||
|
||
while ((todo != 0) && (rd != wr)) { | ||
*dstBuf++ = srcBuf[rd]; | ||
rd = (rd + 1) & sz; | ||
todo--; | ||
} | ||
|
||
hal_cpuDataMemoryBarrier(); | ||
rtt->channels[chan].rd = rd; | ||
|
||
return count - todo; | ||
} | ||
|
||
|
||
int _hal_rttWrite(int chan, const void *buf, unsigned int count) | ||
{ | ||
if (rtt_check(chan, rtt_dir_up) < 0) { | ||
return -ENODEV; | ||
} | ||
|
||
volatile struct rtt_desc *rtt = common.rtt; | ||
|
||
hal_cpuDataMemoryBarrier(); | ||
const unsigned char *srcBuf = (const unsigned char *)buf; | ||
volatile unsigned char *dstBuf = rtt->channels[chan].ptr; | ||
unsigned int sz = rtt->channels[chan].sz - 1; | ||
unsigned int rd = (rtt->channels[chan].rd + sz) & sz; | ||
unsigned int wr = rtt->channels[chan].wr & sz; | ||
unsigned int todo = count; | ||
|
||
/* TODO: Support all buffer modes (currently only trim is used, regardless of flags) */ | ||
while ((todo != 0) && (rd != wr)) { | ||
dstBuf[wr] = *srcBuf++; | ||
wr = (wr + 1) & sz; | ||
todo--; | ||
} | ||
|
||
hal_cpuDataMemoryBarrier(); | ||
rtt->channels[chan].wr = wr; | ||
|
||
return count - todo; | ||
} | ||
|
||
|
||
int _hal_rttTxAvail(int chan) | ||
{ | ||
if (rtt_check(chan, rtt_dir_up) < 0) { | ||
return -ENODEV; | ||
} | ||
|
||
volatile struct rtt_desc *rtt = common.rtt; | ||
|
||
hal_cpuDataMemoryBarrier(); | ||
unsigned int sz = rtt->channels[chan].sz - 1; | ||
unsigned int rd = (rtt->channels[chan].rd + sz) & sz; | ||
unsigned int wr = rtt->channels[chan].wr & sz; | ||
|
||
if (wr > rd) { | ||
return sz + 1 - (wr - rd); | ||
} | ||
else { | ||
return rd - wr; | ||
} | ||
} | ||
|
||
|
||
void _hal_rttReset(int chan, rtt_dir_t dir) | ||
{ | ||
if (rtt_check(chan, dir) < 0) { | ||
return -ENODEV; | ||
Check warning on line 160 in hal/arm/rtt.c GitHub Actions / call-ci / build (armv8m33-mcxn94x-frdm)
Check warning on line 160 in hal/arm/rtt.c GitHub Actions / call-ci / build (armv7m7-imxrt117x-evk)
Check warning on line 160 in hal/arm/rtt.c GitHub Actions / call-ci / build (armv7m4-stm32l4x6-nucleo)
Check warning on line 160 in hal/arm/rtt.c GitHub Actions / call-ci / build (armv7m7-imxrt105x-evk)
|
||
} | ||
|
||
volatile struct rtt_desc *rtt = common.rtt; | ||
|
||
hal_cpuDataMemoryBarrier(); | ||
if (dir == rtt_dir_up) { | ||
common.rtt->channels[chan].wr = common.rtt->channels[chan].rd; | ||
} | ||
else { | ||
chan = rtt->txChannels + chan; | ||
common.rtt->channels[chan].rd = common.rtt->channels[chan].wr; | ||
} | ||
hal_cpuDataMemoryBarrier(); | ||
} | ||
|
||
|
||
int _hal_rttInit(unsigned int enable) | ||
{ | ||
const syspage_map_t *map; | ||
common.rtt = NULL; | ||
|
||
if (enable != 0u) { | ||
map = syspage_mapNameResolve(RTT_SYSPAGE_MAP_NAME); | ||
if (map == NULL) { | ||
return -ENOENT; | ||
} | ||
|
||
/* TODO: Place CB always at the start of the map? */ | ||
common.rtt = (void *)(map->end - RTT_CB_SIZE); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Phoenix-RTOS | ||
* | ||
* SEGGER's Real Time Transfer - simplified driver | ||
* | ||
* Copyright 2023-2024 Phoenix Systems | ||
* Author: Gerard Swiderski, Daniel Sawka | ||
* | ||
* This file is part of Phoenix-RTOS. | ||
* | ||
* %LICENSE% | ||
*/ | ||
|
||
#ifndef HAL_ARMV_RTT_H_ | ||
#define HAL_ARMV_RTT_H_ | ||
|
||
|
||
typedef enum { | ||
rtt_dir_up, /* tx: target -> host */ | ||
rtt_dir_down, /* rx: host -> target */ | ||
} rtt_dir_t; | ||
|
||
|
||
typedef enum { | ||
rtt_mode_skip = 0, /* write if the whole message can be written at once; discard the message otherwise */ | ||
rtt_mode_trim = 1, /* write anything if possible; discard the remaining unwritten data otherwise */ | ||
rtt_mode_blocking = 2, /* wait until writable */ | ||
} rtt_mode_t; | ||
|
||
|
||
/* Initialize rtt internal structures */ | ||
int _hal_rttInit(unsigned int enable); | ||
|
||
|
||
/* Non-blocking read from channel */ | ||
int _hal_rttRead(int chan, void *buf, unsigned int count); | ||
|
||
|
||
/* Non-blocking write to channel */ | ||
int _hal_rttWrite(int chan, const void *buf, unsigned int count); | ||
|
||
|
||
/* Check for available space in tx */ | ||
int _hal_rttTxAvail(int chan); | ||
|
||
|
||
/* Reset fifo pointers */ | ||
void _hal_rttReset(int chan, rtt_dir_t dir); | ||
|
||
|
||
#endif /* end of HAL_ARMV_RTT_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.