zephyr/drivers/console/rtt_console.c
Andy Ross 32bb2395c2 timeout: Fix up API usage
Kernel timeouts have always been a 32 bit integer despite the
existence of generation macros, and existing code has been
inconsistent about using them.  Upcoming commits are going to make the
timeout arguments opaque, so fix things up to be rigorously correct.
Changes include:

+ Adding a K_TIMEOUT_EQ() macro for code that needs to compare timeout
  values for equality (e.g. with K_FOREVER or K_NO_WAIT).

+ Adding a k_msleep() synonym for k_sleep() which can continue to take
  integral arguments as k_sleep() moves away to timeout arguments.

+ Pervasively using the K_MSEC(), K_SECONDS(), et. al. macros to
  generate timeout arguments.

+ Removing the usage of K_NO_WAIT as the final argument to
  K_THREAD_DEFINE().  This is just a count of milliseconds and we need
  to use a zero.

This patch include no logic changes and should not affect generated
code at all.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
2020-03-31 19:40:47 -04:00

92 lines
2.1 KiB
C

/* rtt_console.c - Console messages to a RAM buffer that is then read by
* the Segger J-Link debugger
*/
/*
* Copyright (c) 2016 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <sys/printk.h>
#include <device.h>
#include <init.h>
#include <SEGGER_RTT.h>
extern void __printk_hook_install(int (*fn)(int));
extern void __stdout_hook_install(int (*fn)(int));
static bool host_present;
/** @brief Wait for fixed period.
*
*/
static void wait(void)
{
if (k_is_in_isr()) {
if (IS_ENABLED(CONFIG_RTT_TX_RETRY_IN_INTERRUPT)) {
k_busy_wait(1000*CONFIG_RTT_TX_RETRY_DELAY_MS);
}
} else {
k_msleep(CONFIG_RTT_TX_RETRY_DELAY_MS);
}
}
static int rtt_console_out(int character)
{
char c = (char)character;
unsigned int cnt;
int max_cnt = CONFIG_RTT_TX_RETRY_CNT;
do {
SEGGER_RTT_LOCK();
cnt = SEGGER_RTT_WriteNoLock(0, &c, 1);
SEGGER_RTT_UNLOCK();
/* There are two possible reasons for not writing any data to
* RTT:
* - The host is not connected and not reading the data.
* - The buffer got full and will be read by the host.
* These two situations are distinguished using the following
* algorithm:
* At the beginning, the module assumes that the host is active,
* so when no data is read, it busy waits and retries.
* If, after retrying, the host reads the data, the module
* assumes that the host is active. If it fails, the module
* assumes that the host is inactive and stores that
* information. On next call, only one attempt takes place.
* The host is marked as active if the attempt is successful.
*/
if (cnt) {
/* byte processed - host is present. */
host_present = true;
} else if (host_present) {
if (max_cnt) {
wait();
max_cnt--;
continue;
} else {
host_present = false;
}
}
break;
} while (1);
return character;
}
static int rtt_console_init(struct device *d)
{
ARG_UNUSED(d);
__printk_hook_install(rtt_console_out);
__stdout_hook_install(rtt_console_out);
return 0;
}
SYS_INIT(rtt_console_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);