Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers/syslog: add cdcacm channel #15925

Merged
merged 1 commit into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions drivers/syslog/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,21 @@ config SYSLOG_RPMSG
---help---
Use the RPMSG as a SYSLOG output device, send message to remote proc.

config SYSLOG_CDCACM
bool "Log to CDCACM"
depends on CDCACM
default n
---help---
Use the CDCACM as a SYSLOG output device, send message to remote proc.

config SYSLOG_CDCACM_MINOR
int "The syslog CDCACM minor number"
depends on SYSLOG_CDCACM
default 0
---help---
If there are more than one CDCACM devices, then a device minor number
may also need to be provided. Default: 0

config SYSLOG_STREAM
bool "Log to stream"
default n
Expand All @@ -269,15 +284,15 @@ config SYSLOG_STREAM

config SYSLOG_CONSOLE
bool "Log to /dev/console"
default !ARCH_LOWPUTC && !SYSLOG_CHAR && !RAMLOG_SYSLOG && !SYSLOG_RPMSG && !SYSLOG_RTT
default !ARCH_LOWPUTC && !SYSLOG_CHAR && !RAMLOG_SYSLOG && !SYSLOG_RPMSG && !SYSLOG_RTT && !SYSLOG_CDCACM
depends on DEV_CONSOLE
select SYSLOG_REGISTER
---help---
Use the system console as a SYSLOG output device.

config SYSLOG_DEFAULT
bool "Default SYSLOG device"
default ARCH_LOWPUTC && !SYSLOG_CHAR && !RAMLOG_SYSLOG && !SYSLOG_RPMSG && !SYSLOG_RTT && !SYSLOG_CONSOLE
default ARCH_LOWPUTC && !SYSLOG_CHAR && !RAMLOG_SYSLOG && !SYSLOG_RPMSG && !SYSLOG_RTT && !SYSLOG_CDCACM && !SYSLOG_CONSOLE
---help---
syslog() interfaces will be present, but all output will go to the
up_putc(ARCH_LOWPUTC == y) or bit-bucket(ARCH_LOWPUTC == n).
Expand Down
58 changes: 56 additions & 2 deletions drivers/syslog/syslog_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
# include <nuttx/segger/rtt.h>
#endif

#ifdef CONFIG_SYSLOG_CDCACM
# include <nuttx/usb/cdcacm.h>
#endif

#ifdef CONFIG_ARCH_LOWPUTC
# include <nuttx/arch.h>
#endif
Expand All @@ -57,13 +61,20 @@
* Private Function Prototypes
****************************************************************************/

#if defined(CONFIG_SYSLOG_DEFAULT)
#ifdef CONFIG_SYSLOG_DEFAULT
static int syslog_default_putc(FAR syslog_channel_t *channel,
int ch);
static ssize_t syslog_default_write(FAR syslog_channel_t *channel,
FAR const char *buffer, size_t buflen);
#endif

#ifdef CONFIG_SYSLOG_CDCACM
static int syslog_cdcacm_putc(FAR struct syslog_channel_s *channel,
int ch);
static ssize_t syslog_cdcacm_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen);
#endif

/****************************************************************************
* Private Data
****************************************************************************/
Expand Down Expand Up @@ -133,6 +144,25 @@ static syslog_channel_t g_rtt_channel =
};
#endif

#ifdef CONFIG_SYSLOG_CDCACM
static const struct syslog_channel_ops_s g_cdcacm_channel_ops =
{
syslog_cdcacm_putc,
syslog_cdcacm_putc,
NULL,
syslog_cdcacm_write,
syslog_cdcacm_write
};

static struct syslog_channel_s g_cdcacm_channel =
{
&g_cdcacm_channel_ops
# ifdef CONFIG_SYSLOG_IOCTL
, "cdcacm"
# endif
};
#endif

#ifdef CONFIG_SYSLOG_DEFAULT
static const struct syslog_channel_ops_s g_default_channel_ops =
{
Expand Down Expand Up @@ -206,7 +236,10 @@ g_syslog_channel[CONFIG_SYSLOG_MAX_CHANNELS] =
&g_rpmsg_channel,
#endif
#ifdef CONFIG_SYSLOG_RTT
&g_rtt_channel
&g_rtt_channel,
#endif
#ifdef CONFIG_SYSLOG_CDCACM
&g_cdcacm_channel
#endif
};

Expand Down Expand Up @@ -296,6 +329,27 @@ static ssize_t syslog_default_write(FAR syslog_channel_t *channel,
}
#endif

#ifdef CONFIG_SYSLOG_CDCACM
static int syslog_cdcacm_putc(FAR struct syslog_channel_s *channel, int ch)
{
char tmp;

tmp = ch;
cdcacm_write(&tmp, 1);

UNUSED(channel);
return ch;
}

static ssize_t syslog_cdcacm_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen)
{
UNUSED(channel);

return cdcacm_write(buffer, buflen);
}
#endif

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down
89 changes: 89 additions & 0 deletions drivers/usbdev/cdcacm.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ static void cdcuart_dmareceive(FAR struct uart_dev_s *dev);
* Private Data
****************************************************************************/

#ifdef CONFIG_SYSLOG_CDCACM
static FAR struct cdcacm_dev_s *g_syslog_cdcacm;
#endif

/* USB class device *********************************************************/

static const struct usbdevclass_driverops_s g_driverops =
Expand Down Expand Up @@ -2775,6 +2779,76 @@ static void cdcuart_dmareceive(FAR struct uart_dev_s *dev)
* Public Functions
****************************************************************************/

#ifdef CONFIG_SYSLOG_CDCACM
/****************************************************************************
* Name: cdcacm_write
*
* Description:
* This provides a cdcacm write method for syslog devices that support
* multiple byte writes
*
* Input Parameters:
* buffer - The buffer containing the data to be output
* buflen - The number of bytes in the buffer
*
* Returned Value:
* On success, the number of characters written is returned. A negated
* errno value is returned on any failure.
*
****************************************************************************/

ssize_t cdcacm_write(FAR const char *buffer, size_t buflen)
{
FAR struct cdcacm_dev_s *priv = g_syslog_cdcacm;
size_t len = 0;

while (len < buflen)
{
irqstate_t flags;

if (!priv || !priv->ctrlline)
{
return -EINVAL;
}

flags = enter_critical_section();

if (cdcuart_txready(&priv->serdev))
{
ssize_t ret = cdcuart_sendbuf(&priv->serdev,
buffer + len,
buflen - len);
if (ret < 0)
{
leave_critical_section(flags);
return ret;
}

len += ret;
}

leave_critical_section(flags);
}

return buflen;
}

/****************************************************************************
* Name: cdcacm_disable_syslog
*
* Description:
* Disable CDCACM syslog channel by clearing the globle pointer.
* This function is used in specific situation, such as must disable
* cdcacm log printing when usb re-enumeration.
*
****************************************************************************/

void cdcacm_disable_syslog(void)
{
g_syslog_cdcacm = NULL;
}
#endif

/****************************************************************************
* Name: cdcacm_classobject
*
Expand Down Expand Up @@ -2904,6 +2978,14 @@ int cdcacm_classobject(int minor, FAR struct usbdev_devinfo_s *devinfo,
}

*classdev = &drvr->drvr;

#ifdef CONFIG_SYSLOG_CDCACM
if (minor == CONFIG_SYSLOG_CDCACM_MINOR)
{
g_syslog_cdcacm = priv;
}
#endif

return OK;

errout_with_class:
Expand Down Expand Up @@ -3019,6 +3101,13 @@ void cdcacm_uninitialize(FAR struct usbdevclass_driver_s *classdev)
char devname[CDCACM_DEVNAME_SIZE];
int ret;

#ifdef CONFIG_SYSLOG_CDCACM
if (g_syslog_cdcacm == priv)
{
g_syslog_cdcacm = NULL;
}
#endif

/* Disconnect in case we are connected */

cdcacm_disconnect(classdev, priv->usbdev);
Expand Down
34 changes: 34 additions & 0 deletions include/nuttx/usb/cdcacm.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,40 @@ struct composite_devdesc_s;
void cdcacm_get_composite_devdesc(struct composite_devdesc_s *dev);
#endif

/****************************************************************************
* Name: cdcacm_write
*
* Description:
* This provides a cdcacm write method for syslog devices that support
* multiple byte writes.
*
* Input Parameters:
* buffer - The buffer containing the data to be output
* buflen - The number of bytes in the buffer
*
* Returned Value:
* On success, the number of characters written is returned. A negated
* errno value is returned on any failure.
*
****************************************************************************/

#ifdef CONFIG_SYSLOG_CDCACM
ssize_t cdcacm_write(FAR const char *buffer, size_t buflen);
#endif

/****************************************************************************
* Name: cdcacm_disable_syslog
*
* Description:
* Disable CDCACM syslog channel by clearing the globle pointer.
* This function is used in specific situation, such as must disable
* cdcacm log printing when usb re-enumeration.
*
****************************************************************************/
#ifdef CONFIG_SYSLOG_CDCACM
void cdcacm_disable_syslog(void);
#endif

#undef EXTERN
#if defined(__cplusplus)
}
Expand Down
Loading