Skip to content

Commit

Permalink
driver/syslog: add cdcacm channel
Browse files Browse the repository at this point in the history
Use the CDCACM as a SYSLOG output device, send message to remote proc.
If there are more than one CDCACM devices, then a device minor number
may also need to be provided. Default: 0

Signed-off-by: yangsong8 <[email protected]>
  • Loading branch information
yangsong8-a1 authored and lupyuen committed Mar 10, 2025
1 parent 4641149 commit 9c55a19
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 4 deletions.
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 @@ -134,6 +145,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 @@ -207,7 +237,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 @@ -297,6 +330,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 @@ -234,6 +234,10 @@ static ssize_t cdcuart_sendbuf(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 @@ -2751,6 +2755,76 @@ static void cdcacm_rcvpacket(FAR struct cdcacm_dev_s *priv)
* 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 @@ -2876,6 +2950,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 @@ -2991,6 +3073,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 @@ -411,6 +411,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

0 comments on commit 9c55a19

Please sign in to comment.