Skip to content

Commit

Permalink
hal/imxrt: Support RTT as a HAL console
Browse files Browse the repository at this point in the history
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
Darchiv committed Sep 27, 2024
1 parent 52e5cf1 commit 65425ed
Show file tree
Hide file tree
Showing 6 changed files with 375 additions and 15 deletions.
2 changes: 1 addition & 1 deletion hal/arm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
# TODO handle other common ARM stuff (e.g GIC) and
# select relevant components here

OBJS += $(addprefix $(PREFIX_O)hal/arm/, nvic.o scb.o)
OBJS += $(addprefix $(PREFIX_O)hal/arm/, nvic.o scb.o rtt.o)
193 changes: 193 additions & 0 deletions hal/arm/rtt.c
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

View workflow job for this annotation

GitHub Actions / call-ci / build (armv8m33-mcxn94x-frdm)

'return' with a value, in function returning void [-Wreturn-type]

Check warning on line 160 in hal/arm/rtt.c

View workflow job for this annotation

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

'return' with a value, in function returning void [-Wreturn-type]

Check warning on line 160 in hal/arm/rtt.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m4-stm32l4x6-nucleo)

'return' with a value, in function returning void [-Wreturn-type]

Check warning on line 160 in hal/arm/rtt.c

View workflow job for this annotation

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

'return' with a value, in function returning void [-Wreturn-type]

Check warning on line 160 in hal/arm/rtt.c

View workflow job for this annotation

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

'return' with a value, in function returning void [-Wreturn-type]
}

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;
}
51 changes: 51 additions & 0 deletions hal/arm/rtt.h
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_ */
52 changes: 45 additions & 7 deletions hal/armv7m/imxrt/10xx/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Operating system kernel
*
* HAL console (iMXRT USART)
* HAL console (iMXRT USART + RTT)
*
* Copyright 2016-2017 Phoenix Systems
* Author: Pawel Pisarczyk, Artur Wodejko, Aleksander Kaminski
Expand All @@ -14,21 +14,35 @@
*/

#include "hal/console.h"
#include "hal/arm/rtt.h"
#include "include/arch/armv7m/imxrt/10xx/imxrt10xx.h"
#include "imxrt10xx.h"
#include "lib/helpers.h"
#include <arch/cpu.h>

#include <board_config.h>

#ifndef UART_CONSOLE
#define UART_CONSOLE 1
#ifndef UART_CONSOLE_KERNEL
#ifdef UART_CONSOLE
#define UART_CONSOLE_KERNEL UART_CONSOLE
#else
#define UART_CONSOLE_KERNEL 1
#endif
#endif

#ifndef RTT_CONSOLE_KERNEL
#if RTT_ENABLED
#define RTT_CONSOLE_KERNEL 0
#else
#define RTT_CONSOLE_KERNEL
#endif
#endif

#define CONCAT3(a, b, c) a##b##c
#define CONSOLE_BAUD(n) (CONCAT3(UART, n, _BAUDRATE))

#if CONSOLE_BAUD(UART_CONSOLE)
#define CONSOLE_BAUDRATE CONSOLE_BAUD(UART_CONSOLE)
#if !ISEMPTY(UART_CONSOLE_KERNEL) && CONSOLE_BAUD(UART_CONSOLE_KERNEL)
#define CONSOLE_BAUDRATE CONSOLE_BAUD(UART_CONSOLE_KERNEL)
#else
#define CONSOLE_BAUDRATE 115200
#endif
Expand Down Expand Up @@ -63,16 +77,23 @@ void hal_consolePrint(int attr, const char *s)

void hal_consolePutch(char c)
{
#if RTT_ENABLED && !ISEMPTY(RTT_CONSOLE_KERNEL)
_hal_rttWrite(RTT_CONSOLE_KERNEL, &c, 1);
#endif

#if !ISEMPTY(UART_CONSOLE_KERNEL)
while (!(*(console_common.uart + uart_stat) & (1 << 23)))
;

*(console_common.uart + uart_data) = c;
#endif
}


void _hal_consoleInit(void)
#if !ISEMPTY(UART_CONSOLE_KERNEL)
static void _hal_uartInit(void)
{
u32 t, console = UART_CONSOLE - 1;
u32 t, console = UART_CONSOLE_KERNEL - 1;

static const struct {
volatile u32 *base;
Expand Down Expand Up @@ -155,3 +176,20 @@ void _hal_consoleInit(void)
/* Enable TX and RX */
*(console_common.uart + uart_ctrl) |= (1 << 19) | (1 << 18);
}
#endif


void _hal_consoleInit(void)
{
unsigned int rtt_enable = 0u;

#if RTT_ENABLED && !ISEMPTY(RTT_CONSOLE_KERNEL)
rtt_enable = 1u;
#endif

_hal_rttInit(rtt_enable);

#if !ISEMPTY(UART_CONSOLE_KERNEL)
_hal_uartInit();
#endif
}
Loading

0 comments on commit 65425ed

Please sign in to comment.