driver/syslog: add cdcacm channel

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 <yangsong8@xiaomi.com>
This commit is contained in:
yangsong8
2024-09-14 14:39:43 +08:00
committed by Lup Yuen Lee
parent 46411495ef
commit 9c55a19238
4 changed files with 196 additions and 4 deletions
+17 -2
View File
@@ -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
@@ -269,7 +284,7 @@ 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---
@@ -277,7 +292,7 @@ config SYSLOG_CONSOLE
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).
+56 -2
View File
@@ -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
@@ -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
****************************************************************************/
@@ -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 =
{
@@ -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
};
@@ -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
****************************************************************************/
+89
View File
@@ -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 =
@@ -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
*
@@ -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:
@@ -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);
+34
View File
@@ -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)
}