diff options
| author | HubretXie <[email protected]> | 2019-11-26 09:30:21 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-11-26 09:30:21 +0800 |
| commit | 17f7f1c7ca2581b2e308888f8acb99ca8a541422 (patch) | |
| tree | 5236e93ab1e4e24508d4ebf4540b6743dd7c9a41 /components | |
| parent | 9662e18c3688681cd95ebd65242773dbe7c1366b (diff) | |
| parent | e459084fe028c837762d40326a9be3dfdc179894 (diff) | |
Merge pull request #8 from RT-Thread/master
sync
Diffstat (limited to 'components')
85 files changed, 3874 insertions, 1289 deletions
diff --git a/components/Kconfig b/components/Kconfig index e47abb9756..9a9efa8434 100644 --- a/components/Kconfig +++ b/components/Kconfig @@ -1,14 +1,13 @@ menu "RT-Thread Components" config RT_USING_COMPONENTS_INIT - bool "Use components automatically initialization" - default y - -if RT_USING_COMPONENTS_INIT - config RT_USING_USER_MAIN - bool "The main() function as user entry function" - default y - + bool + default n + +config RT_USING_USER_MAIN + bool + default n + if RT_USING_USER_MAIN config RT_MAIN_THREAD_STACK_SIZE int "Set main thread stack size" @@ -19,7 +18,6 @@ if RT_USING_COMPONENTS_INIT default 10 if RT_THREAD_PRIORITY_32 default 85 if RT_THREAD_PRIORITY_256 endif -endif source "$RTT_DIR/components/cplusplus/Kconfig" diff --git a/components/cplusplus/Queue.h b/components/cplusplus/Queue.h index 351e3ec66b..23a4638798 100644 --- a/components/cplusplus/Queue.h +++ b/components/cplusplus/Queue.h @@ -68,7 +68,7 @@ public: private: struct rt_messagequeue mID; - char mPool[(sizeof(struct rt_messagequeue) + sizeof(T)) * queue_sz]; + char mPool[(sizeof(void *) + RT_ALIGN(sizeof(T), RT_ALIGN_SIZE)) * queue_sz]; }; } diff --git a/components/dfs/filesystems/elmfat/dfs_elm.c b/components/dfs/filesystems/elmfat/dfs_elm.c index 3825fd9108..b4c4c627aa 100644 --- a/components/dfs/filesystems/elmfat/dfs_elm.c +++ b/components/dfs/filesystems/elmfat/dfs_elm.c @@ -478,6 +478,33 @@ int dfs_elm_close(struct dfs_fd *file) int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args) { + switch (cmd) + { + case RT_FIOFTRUNCATE: + { + FIL *fd; + FSIZE_t fptr, length; + FRESULT result = FR_OK; + fd = (FIL *)(file->data); + RT_ASSERT(fd != RT_NULL); + + /* save file read/write point */ + fptr = fd->fptr; + length = *(off_t*)args; + if (length <= fd->obj.objsize) + { + fd->fptr = length; + result = f_truncate(fd); + } + else + { + result = f_lseek(fd, length); + } + /* restore file read/write point */ + fd->fptr = fptr; + return elm_result_to_dfs(result); + } + } return -ENOSYS; } diff --git a/components/dfs/include/dfs_file.h b/components/dfs/include/dfs_file.h index aaff3f6e9c..2dfacd653e 100644 --- a/components/dfs/include/dfs_file.h +++ b/components/dfs/include/dfs_file.h @@ -66,6 +66,10 @@ int dfs_file_lseek(struct dfs_fd *fd, off_t offset); int dfs_file_stat(const char *path, struct stat *buf); int dfs_file_rename(const char *oldpath, const char *newpath); +int dfs_file_ftruncate(struct dfs_fd *fd, off_t length); + +/* 0x5254 is just a magic number to make these relatively unique ("RT") */ +#define RT_FIOFTRUNCATE 0x52540000U #ifdef __cplusplus } diff --git a/components/dfs/include/dfs_fs.h b/components/dfs/include/dfs_fs.h index d3a00fc542..58a9e5cf55 100644 --- a/components/dfs/include/dfs_fs.h +++ b/components/dfs/include/dfs_fs.h @@ -90,6 +90,7 @@ int dfs_unmount(const char *specialfile); int dfs_mkfs(const char *fs_name, const char *device_name); int dfs_statfs(const char *path, struct statfs *buffer); +int dfs_mount_device(rt_device_t dev); #ifdef __cplusplus } diff --git a/components/dfs/include/dfs_posix.h b/components/dfs/include/dfs_posix.h index 9fd76debe2..87d5f0771e 100644 --- a/components/dfs/include/dfs_posix.h +++ b/components/dfs/include/dfs_posix.h @@ -58,6 +58,7 @@ int fstat(int fildes, struct stat *buf); int fsync(int fildes); int fcntl(int fildes, int cmd, ...); int ioctl(int fildes, int cmd, ...); +int ftruncate(int fd, off_t length); /* directory api*/ int rmdir(const char *path); diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c index 5f090a7f6b..1063a278ab 100644 --- a/components/dfs/src/dfs_file.c +++ b/components/dfs/src/dfs_file.c @@ -482,6 +482,35 @@ __exit: return result; } +/** + * this function is will cause the regular file referenced by fd + * to be truncated to a size of precisely length bytes. + * + * @param fd the file descriptor. + * @param length the length to be truncated. + * + * @return the status of truncated. + */ +int dfs_file_ftruncate(struct dfs_fd *fd, off_t length) +{ + int result; + + /* fd is null or not a regular file system fd, or length is invalid */ + if (fd == NULL || fd->type != FT_REGULAR || length < 0) + return -EINVAL; + + if (fd->fops->ioctl == NULL) + return -ENOSYS; + + result = fd->fops->ioctl(fd, RT_FIOFTRUNCATE, (void*)&length); + + /* update current size */ + if (result == 0) + fd->size = length; + + return result; +} + #ifdef RT_USING_FINSH #include <finsh.h> diff --git a/components/dfs/src/dfs_fs.c b/components/dfs/src/dfs_fs.c index 04d862e85d..164beed719 100644 --- a/components/dfs/src/dfs_fs.c +++ b/components/dfs/src/dfs_fs.c @@ -508,7 +508,7 @@ int dfs_mount_table(void) mount_table[index].rwflag, mount_table[index].data) != 0) { - rt_kprintf("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype, + LOG_E("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype, mount_table[index].path); return -RT_ERROR; } @@ -518,6 +518,43 @@ int dfs_mount_table(void) return 0; } INIT_ENV_EXPORT(dfs_mount_table); + +int dfs_mount_device(rt_device_t dev) +{ + int index = 0; + + if(dev == RT_NULL) { + rt_kprintf("the device is NULL to be mounted.\n"); + return -RT_ERROR; + } + + while (1) + { + if (mount_table[index].path == NULL) break; + + if(strcmp(mount_table[index].device_name, dev->parent.name) == 0) { + if (dfs_mount(mount_table[index].device_name, + mount_table[index].path, + mount_table[index].filesystemtype, + mount_table[index].rwflag, + mount_table[index].data) != 0) + { + LOG_E("mount fs[%s] device[%s] to %s failed.\n", mount_table[index].filesystemtype, dev->parent.name, + mount_table[index].path); + return -RT_ERROR; + } else { + LOG_D("mount fs[%s] device[%s] to %s ok.\n", mount_table[index].filesystemtype, dev->parent.name, + mount_table[index].path); + return RT_EOK; + } + } + + index ++; + } + + rt_kprintf("can't find device:%s to be mounted.\n", dev->parent.name); + return -RT_ERROR; +} #endif #ifdef RT_USING_FINSH diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c index 69fe56a84e..fc603df437 100644 --- a/components/dfs/src/dfs_posix.c +++ b/components/dfs/src/dfs_posix.c @@ -472,6 +472,52 @@ int ioctl(int fildes, int cmd, ...) RTM_EXPORT(ioctl); /** + * + * this function is a POSIX compliant version, which cause the regular file + * referenced by fd to be truncated to a size of precisely length bytes. + * @param fd the file descriptor. + * @param length the length to be truncated. + * + * @return Upon successful completion, ftruncate() shall return 0; + * otherwise, -1 shall be returned and errno set to indicate the error. + */ +int ftruncate(int fd, off_t length) +{ + int result; + struct dfs_fd *d; + + d = fd_get(fd); + if (d == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + if (length < 0) + { + fd_put(d); + rt_set_errno(-EINVAL); + + return -1; + } + result = dfs_file_ftruncate(d, length); + if (result < 0) + { + fd_put(d); + rt_set_errno(result); + + return -1; + } + + /* release the ref-count of fd */ + fd_put(d); + + return 0; +} +RTM_EXPORT(ftruncate); + +/** * this function is a POSIX compliant version, which will return the * information about a mounted file system. * diff --git a/components/dfs/src/poll.c b/components/dfs/src/poll.c index 473b1579d2..3f304549f7 100644 --- a/components/dfs/src/poll.c +++ b/components/dfs/src/poll.c @@ -19,6 +19,8 @@ #include <dfs_posix.h> #include <dfs_poll.h> +#ifdef RT_USING_POSIX + struct rt_poll_node; struct rt_poll_table @@ -214,3 +216,4 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout) return num; } +#endif diff --git a/components/dfs/src/select.c b/components/dfs/src/select.c index b20f7cf656..181855bc74 100644 --- a/components/dfs/src/select.c +++ b/components/dfs/src/select.c @@ -14,6 +14,8 @@ #include <dfs_poll.h> #include <dfs_select.h> +#ifdef RT_USING_POSIX + static void fdszero(fd_set *set, int nfds) { fd_mask *m; @@ -178,3 +180,4 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc return ret; } +#endif diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index ff2639b8fa..12b82671e3 100755 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -88,11 +88,21 @@ config RT_USING_I2C default n if RT_USING_I2C + config RT_I2C_DEBUG + bool "Use I2C debug mesage" + default n + config RT_USING_I2C_BITOPS bool "Use GPIO to simulate I2C" default y endif +if RT_USING_I2C_BITOPS + config RT_I2C_BITOPS_DEBUG + bool "Use simulate I2C debug mesage" + default n +endif + config RT_USING_PIN bool "Using generic GPIO device drivers" default y @@ -125,7 +135,6 @@ config RT_USING_PM config RT_USING_RTC bool "Using RTC device drivers" - select RT_USING_LIBC default n if RT_USING_RTC @@ -434,10 +443,20 @@ menuconfig RT_USING_HWCRYPTO endif endif -config RT_USING_ENCODER - bool "Using ENCODER device drivers" +config RT_USING_PULSE_ENCODER + bool "Using PULSE ENCODER device drivers" + default n + +config RT_USING_INPUT_CAPTURE + bool "Using INPUT CAPTURE device drivers" default n +if RT_USING_INPUT_CAPTURE + config RT_INPUT_CAPTURE_RB_SIZE + int "Set input capture ringbuffer size" + default 100 +endif + menuconfig RT_USING_WIFI bool "Using Wi-Fi framework" default n @@ -650,6 +669,9 @@ menu "Using USB" config _RT_USB_DEVICE_WINUSB bool "Enable to use device as winusb device" select RT_USB_DEVICE_WINUSB + config _RT_USB_DEVICE_AUDIO + bool "Enable to use device as audio device" + select RT_USB_DEVICE_AUDIO endchoice if RT_USB_DEVICE_COMPOSITE config RT_USB_DEVICE_CDC @@ -675,6 +697,9 @@ menu "Using USB" config RT_USB_DEVICE_WINUSB bool "Enable to use device as winusb device" default n + config RT_USB_DEVICE_AUDIO + bool "Enable to use device as audio device" + default n endif if RT_USB_DEVICE_CDC config RT_VCOM_TASK_STK_SIZE @@ -742,6 +767,24 @@ menu "Using USB" bool "Use to HID device as media keyboard" default y endif + if RT_USB_DEVICE_AUDIO + config RT_USB_DEVICE_AUDIO_MIC + bool "Use usb mic device as audio device" + default n + if RT_USB_DEVICE_AUDIO_MIC + config RT_USBD_MIC_DEVICE_NAME + string "audio mic device name" + default "mic0" + endif + config RT_USB_DEVICE_AUDIO_SPEAKER + bool "Use usb speaker device as audio device" + default n + if RT_USB_DEVICE_AUDIO_SPEAKER + config RT_USBD_SPEAKER_DEVICE_NAME + string "audio speaker device name" + default "sound0" + endif + endif endif endmenu endmenu diff --git a/components/drivers/can/can.c b/components/drivers/can/can.c index 0769c79fd7..3d60dbaa55 100644 --- a/components/drivers/can/can.c +++ b/components/drivers/can/can.c @@ -27,10 +27,15 @@ static rt_err_t rt_can_init(struct rt_device *dev) /* initialize rx/tx */ can->can_rx = RT_NULL; can->can_tx = RT_NULL; +#ifdef RT_CAN_USING_HDR + can->hdr = RT_NULL; +#endif /* apply configuration */ if (can->ops->configure) result = can->ops->configure(can, &can->config); + else + result = -RT_ENOSYS; return result; } @@ -293,7 +298,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) can->can_rx = rx_fifo; dev->open_flag |= RT_DEVICE_FLAG_INT_RX; - /* configure low level device */ + /* open can rx interrupt */ can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX); } } @@ -311,7 +316,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) tx_fifo->buffer = (struct rt_can_sndbxinx_list *)(tx_fifo + 1); rt_memset(tx_fifo->buffer, 0, - can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); + can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); rt_list_init(&tx_fifo->freelist); for (i = 0; i < can->config.sndboxnumber; i++) { @@ -325,7 +330,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) can->can_tx = tx_fifo; dev->open_flag |= RT_DEVICE_FLAG_INT_TX; - /* configure low level device */ + /* open can tx interrupt */ can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX); } } @@ -406,7 +411,7 @@ static rt_err_t rt_can_close(struct rt_device *dev) rt_free(rx_fifo); dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX; can->can_rx = RT_NULL; - /* configure low level device */ + /* clear can rx interrupt */ can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX); } @@ -420,7 +425,7 @@ static rt_err_t rt_can_close(struct rt_device *dev) rt_free(tx_fifo); dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX; can->can_tx = RT_NULL; - /* configure low level device */ + /* clear can tx interrupt */ can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_TX); } @@ -484,6 +489,7 @@ static rt_err_t rt_can_control(struct rt_device *dev, struct rt_can_device *can; rt_err_t res; + res = RT_EOK; RT_ASSERT(dev != RT_NULL); can = (struct rt_can_device *)dev; @@ -501,8 +507,9 @@ static rt_err_t rt_can_control(struct rt_device *dev, case RT_DEVICE_CTRL_CONFIG: /* configure device */ - can->ops->configure(can, (struct can_configure *)args); + res = can->ops->configure(can, (struct can_configure *)args); break; + case RT_CAN_CMD_SET_PRIV: /* configure device */ if ((rt_uint32_t)args != can->config.privmode) @@ -513,7 +520,6 @@ static rt_err_t rt_can_control(struct rt_device *dev, res = can->ops->control(can, cmd, args); if (res != RT_EOK) return res; - tx_fifo = (struct rt_can_tx_fifo *) can->can_tx; if (can->config.privmode) { @@ -522,11 +528,11 @@ static rt_err_t rt_can_control(struct rt_device *dev, level = rt_hw_interrupt_disable(); if(rt_list_isempty(&tx_fifo->buffer[i].list)) { - rt_sem_release(&(tx_fifo->sem)); + rt_sem_release(&(tx_fifo->sem)); } else { - rt_list_remove(&tx_fifo->buffer[i].list); + rt_list_remove(&tx_fifo->buffer[i].list); } rt_hw_interrupt_enable(level); } @@ -544,7 +550,6 @@ static rt_err_t rt_can_control(struct rt_device *dev, rt_hw_interrupt_enable(level); } } - return RT_EOK; } break; @@ -561,74 +566,73 @@ static rt_err_t rt_can_control(struct rt_device *dev, return res; } - { - struct rt_can_filter_config *pfilter; - struct rt_can_filter_item *pitem; - rt_uint32_t count; - rt_base_t level; + struct rt_can_filter_config *pfilter; + struct rt_can_filter_item *pitem; + rt_uint32_t count; + rt_base_t level; - pfilter = (struct rt_can_filter_config *)args; - count = pfilter->count; - pitem = pfilter->items; - if (pfilter->actived) + pfilter = (struct rt_can_filter_config *)args; + RT_ASSERT(pfilter); + count = pfilter->count; + pitem = pfilter->items; + if (pfilter->actived) + { + while (count) { - while (count) + if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0) { - if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0) - { - count--; - pitem++; - continue; - } - - level = rt_hw_interrupt_disable(); - if (!can->hdr[pitem->hdr].connected) - { - rt_hw_interrupt_enable(level); - rt_memcpy(&can->hdr[pitem->hdr].filter, pitem, - sizeof(struct rt_can_filter_item)); - level = rt_hw_interrupt_disable(); - can->hdr[pitem->hdr].connected = 1; - can->hdr[pitem->hdr].msgs = 0; - rt_list_init(&can->hdr[pitem->hdr].list); - } - rt_hw_interrupt_enable(level); - count--; pitem++; + continue; } + + level = rt_hw_interrupt_disable(); + if (!can->hdr[pitem->hdr].connected) + { + rt_hw_interrupt_enable(level); + rt_memcpy(&can->hdr[pitem->hdr].filter, pitem, + sizeof(struct rt_can_filter_item)); + level = rt_hw_interrupt_disable(); + can->hdr[pitem->hdr].connected = 1; + can->hdr[pitem->hdr].msgs = 0; + rt_list_init(&can->hdr[pitem->hdr].list); + } + rt_hw_interrupt_enable(level); + + count--; + pitem++; } - else + } + else + { + while (count) { - while (count) + if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0) { - if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0) - { - count--; - pitem++; - continue; - } - level = rt_hw_interrupt_disable(); + count--; + pitem++; + continue; + } + level = rt_hw_interrupt_disable(); - if (can->hdr[pitem->hdr].connected) + if (can->hdr[pitem->hdr].connected) + { + can->hdr[pitem->hdr].connected = 0; + can->hdr[pitem->hdr].msgs = 0; + if (!rt_list_isempty(&can->hdr[pitem->hdr].list)) { - can->hdr[pitem->hdr].connected = 0; - can->hdr[pitem->hdr].msgs = 0; - if (!rt_list_isempty(&can->hdr[pitem->hdr].list)) - { - rt_list_remove(can->hdr[pitem->hdr].list.next); - } - rt_hw_interrupt_enable(level); - rt_memset(&can->hdr[pitem->hdr].filter, 0, - sizeof(struct rt_can_filter_item)); + rt_list_remove(can->hdr[pitem->hdr].list.next); } - else - { - rt_hw_interrupt_enable(level); - } - count--; - pitem++; + rt_hw_interrupt_enable(level); + rt_memset(&can->hdr[pitem->hdr].filter, 0, + sizeof(struct rt_can_filter_item)); + } + else + { + rt_hw_interrupt_enable(level); } + count--; + pitem++; } } break; @@ -642,12 +646,16 @@ static rt_err_t rt_can_control(struct rt_device *dev, /* control device */ if (can->ops->control != RT_NULL) { - can->ops->control(can, cmd, args); + res = can->ops->control(can, cmd, args); + } + else + { + res = -RT_ENOSYS; } break; } - return RT_EOK; + return res; } /* @@ -655,8 +663,10 @@ static rt_err_t rt_can_control(struct rt_device *dev, */ static void cantimeout(void *arg) { - rt_can_t can = (rt_can_t)arg; + rt_can_t can; + can = (rt_can_t)arg; + RT_ASSERT(can); rt_device_control((rt_device_t)can, RT_CAN_CMD_GET_STATUS, (void *)&can->status); if (can->status_indicate.ind != RT_NULL) @@ -690,7 +700,7 @@ const static struct rt_device_ops can_device_ops = /* * can register */ -rt_err_t rt_hw_can_register(struct rt_can_device *can, +rt_err_t rt_hw_can_register(struct rt_can_device *can, const char *name, const struct rt_can_ops *ops, void *data) @@ -843,7 +853,10 @@ void rt_hw_can_isr(struct rt_can_device *can, int event) level = rt_hw_interrupt_disable(); rx_length = can->hdr[hdr].msgs * sizeof(struct rt_can_msg); rt_hw_interrupt_enable(level); - can->hdr[hdr].filter.ind(&can->parent, can->hdr[hdr].filter.args, hdr, rx_length); + if (rx_length) + { + can->hdr[hdr].filter.ind(&can->parent, can->hdr[hdr].filter.args, hdr, rx_length); + } } else #endif @@ -857,7 +870,10 @@ void rt_hw_can_isr(struct rt_can_device *can, int event) rx_length = rt_list_len(&rx_fifo->uselist)* sizeof(struct rt_can_msg); rt_hw_interrupt_enable(level); - can->parent.rx_indicate(&can->parent, rx_length); + if (rx_length) + { + can->parent.rx_indicate(&can->parent, rx_length); + } } } break; diff --git a/components/drivers/i2c/i2c-bit-ops.c b/components/drivers/i2c/i2c-bit-ops.c index 478cf99fd6..99338eef54 100644 --- a/components/drivers/i2c/i2c-bit-ops.c +++ b/components/drivers/i2c/i2c-bit-ops.c @@ -10,11 +10,13 @@ #include <rtdevice.h> -#ifdef RT_I2C_BIT_DEBUG -#define bit_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__) +#define DBG_TAG "I2C" +#ifdef RT_I2C_BITOPS_DEBUG +#define DBG_LVL DBG_LOG #else -#define bit_dbg(fmt, ...) +#define DBG_LVL DBG_INFO #endif +#include <rtdbg.h> #define SET_SDA(ops, val) ops->set_sda(ops->data, val) #define SET_SCL(ops, val) ops->set_scl(ops->data, val) @@ -54,11 +56,11 @@ static rt_err_t SCL_H(struct rt_i2c_bit_ops *ops) return -RT_ETIMEOUT; rt_thread_delay((ops->timeout + 1) >> 1); } -#ifdef RT_I2C_BIT_DEBUG +#ifdef RT_I2C_BITOPS_DEBUG if (rt_tick_get() != start) { - bit_dbg("wait %ld tick for SCL line to go high\n", - rt_tick_get() - start); + LOG_D("wait %ld tick for SCL line to go high", + rt_tick_get() - start); } #endif @@ -70,14 +72,14 @@ done: static void i2c_start(struct rt_i2c_bit_ops *ops) { -#ifdef RT_I2C_BIT_DEBUG +#ifdef RT_I2C_BITOPS_DEBUG if (ops->get_scl && !GET_SCL(ops)) { - bit_dbg("I2C bus error, SCL line low\n"); + LOG_E("I2C bus error, SCL line low"); } if (ops->get_sda && !GET_SDA(ops)) { - bit_dbg("I2C bus error, SDA line low\n"); + LOG_E("I2C bus error, SDA line low"); } #endif SDA_L(ops); @@ -114,13 +116,13 @@ rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops) if (SCL_H(ops) < 0) { - bit_dbg("wait ack timeout\n"); + LOG_W("wait ack timeout"); return -RT_ETIMEOUT; } ack = !GET_SDA(ops); /* ACK : SDA pin is pulled low */ - bit_dbg("%s\n", ack ? "ACK" : "NACK"); + LOG_D("%s", ack ? "ACK" : "NACK"); SCL_L(ops); @@ -142,8 +144,8 @@ static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data) i2c_delay(ops); if (SCL_H(ops) < 0) { - bit_dbg("i2c_writeb: 0x%02x, " - "wait scl pin high timeout at bit %d\n", + LOG_D("i2c_writeb: 0x%02x, " + "wait scl pin high timeout at bit %d", data, i); return -RT_ETIMEOUT; @@ -169,8 +171,8 @@ static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus) if (SCL_H(ops) < 0) { - bit_dbg("i2c_readb: wait scl pin high " - "timeout at bit %d\n", 7 - i); + LOG_D("i2c_readb: wait scl pin high " + "timeout at bit %d", 7 - i); return -RT_ETIMEOUT; } @@ -205,13 +207,13 @@ static rt_size_t i2c_send_bytes(struct rt_i2c_bus_device *bus, } else if (ret == 0) { - i2c_dbg("send bytes: NACK.\n"); + LOG_D("send bytes: NACK."); return 0; } else { - i2c_dbg("send bytes: error %d\n", ret); + LOG_E("send bytes: error %d", ret); return ret; } @@ -229,7 +231,7 @@ static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus_device *bus, int ack) i2c_delay(ops); if (SCL_H(ops) < 0) { - bit_dbg("ACK or NACK timeout\n"); + LOG_E("ACK or NACK timeout."); return -RT_ETIMEOUT; } @@ -263,7 +265,7 @@ static rt_size_t i2c_recv_bytes(struct rt_i2c_bus_device *bus, ptr ++; count --; - bit_dbg("recieve bytes: 0x%02x, %s\n", + LOG_D("recieve bytes: 0x%02x, %s", val, (flags & RT_I2C_NO_READ_ACK) ? "(No ACK/NACK)" : (count ? "ACK" : "NACK")); @@ -291,10 +293,10 @@ static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus, ret = i2c_writeb(bus, addr); if (ret == 1 || i == retries) break; - bit_dbg("send stop condition\n"); + LOG_D("send stop condition"); i2c_stop(ops); i2c_delay2(ops); - bit_dbg("send start condition\n"); + LOG_D("send start condition"); i2c_start(ops); } @@ -319,12 +321,12 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus, addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; - bit_dbg("addr1: %d, addr2: %d\n", addr1, addr2); + LOG_D("addr1: %d, addr2: %d", addr1, addr2); ret = i2c_send_address(bus, addr1, retries); if ((ret != 1) && !ignore_nack) { - bit_dbg("NACK: sending first addr\n"); + LOG_W("NACK: sending first addr"); return -RT_EIO; } @@ -332,19 +334,19 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus, ret = i2c_writeb(bus, addr2); if ((ret != 1) && !ignore_nack) { - bit_dbg("NACK: sending second addr\n"); + LOG_W("NACK: sending second addr"); return -RT_EIO; } if (flags & RT_I2C_RD) { - bit_dbg("send repeated start condition\n"); + LOG_D("send repeated start condition"); i2c_restart(ops); addr1 |= 0x01; ret = i2c_send_address(bus, addr1, retries); if ((ret != 1) && !ignore_nack) { - bit_dbg("NACK: sending repeated addr\n"); + LOG_E("NACK: sending repeated addr"); return -RT_EIO; } @@ -373,7 +375,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus, rt_int32_t i, ret; rt_uint16_t ignore_nack; - bit_dbg("send start condition\n"); + LOG_D("send start condition"); i2c_start(ops); for (i = 0; i < num; i++) { @@ -388,7 +390,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus, ret = i2c_bit_send_address(bus, msg); if ((ret != RT_EOK) && !ignore_nack) { - bit_dbg("receive NACK from device addr 0x%02x msg %d\n", + LOG_D("receive NACK from device addr 0x%02x msg %d", msgs[i].addr, i); goto out; } @@ -397,7 +399,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus, { ret = i2c_recv_bytes(bus, msg); if (ret >= 1) - bit_dbg("read %d byte%s\n", ret, ret == 1 ? "" : "s"); + LOG_D("read %d byte%s", ret, ret == 1 ? "" : "s"); if (ret < msg->len) { if (ret >= 0) @@ -409,7 +411,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus, { ret = i2c_send_bytes(bus, msg); if (ret >= 1) - bit_dbg("write %d byte%s\n", ret, ret == 1 ? "" : "s"); + LOG_D("write %d byte%s", ret, ret == 1 ? "" : "s"); if (ret < msg->len) { if (ret >= 0) @@ -421,7 +423,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus, ret = i; out: - bit_dbg("send stop condition\n"); + LOG_D("send stop condition"); i2c_stop(ops); return ret; diff --git a/components/drivers/i2c/i2c_core.c b/components/drivers/i2c/i2c_core.c index f245abb9ca..f358c2b758 100644 --- a/components/drivers/i2c/i2c_core.c +++ b/components/drivers/i2c/i2c_core.c @@ -10,6 +10,14 @@ #include <rtdevice.h> +#define DBG_TAG "I2C" +#ifdef RT_I2C_DEBUG +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_INFO +#endif +#include <rtdbg.h> + rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus, const char *bus_name) { @@ -21,7 +29,7 @@ rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus, res = rt_i2c_bus_device_device_init(bus, bus_name); - i2c_dbg("I2C bus [%s] registered\n", bus_name); + LOG_I("I2C bus [%s] registered", bus_name); return res; } @@ -32,7 +40,7 @@ struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name) rt_device_t dev = rt_device_find(bus_name); if (dev == RT_NULL || dev->type != RT_Device_Class_I2CBUS) { - i2c_dbg("I2C bus %s not exist\n", bus_name); + LOG_E("I2C bus %s not exist", bus_name); return RT_NULL; } @@ -53,9 +61,9 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, #ifdef RT_I2C_DEBUG for (ret = 0; ret < num; ret++) { - i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d\n", ret, - (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W', - msgs[ret].addr, msgs[ret].len); + LOG_D("msgs[%d] %c, addr=0x%02x, len=%d", ret, + (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W', + msgs[ret].addr, msgs[ret].len); } #endif @@ -67,7 +75,7 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, } else { - i2c_dbg("I2C bus operation not supported\n"); + LOG_E("I2C bus operation not supported"); return 0; } @@ -83,7 +91,7 @@ rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msg; msg.addr = addr; - msg.flags = flags & RT_I2C_ADDR_10BIT; + msg.flags = flags; msg.len = count; msg.buf = (rt_uint8_t *)buf; @@ -103,8 +111,7 @@ rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus, RT_ASSERT(bus != RT_NULL); msg.addr = addr; - msg.flags = flags & RT_I2C_ADDR_10BIT; - msg.flags |= RT_I2C_RD; + msg.flags = flags | RT_I2C_RD; msg.len = count; msg.buf = buf; diff --git a/components/drivers/i2c/i2c_dev.c b/components/drivers/i2c/i2c_dev.c index c784a4e4ee..59f728be09 100644 --- a/components/drivers/i2c/i2c_dev.c +++ b/components/drivers/i2c/i2c_dev.c @@ -11,6 +11,14 @@ #include <rtdevice.h> +#define DBG_TAG "I2C" +#ifdef RT_I2C_DEBUG +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_INFO +#endif +#include <rtdbg.h> + static rt_size_t i2c_bus_device_read(rt_device_t dev, rt_off_t pos, void *buffer, @@ -23,7 +31,7 @@ static rt_size_t i2c_bus_device_read(rt_device_t dev, RT_ASSERT(bus != RT_NULL); RT_ASSERT(buffer != RT_NULL); - i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", dev->parent.name, count); + LOG_D("I2C bus dev [%s] reading %u bytes.", dev->parent.name, count); addr = pos & 0xffff; flags = (pos >> 16) & 0xffff; @@ -43,7 +51,7 @@ static rt_size_t i2c_bus_device_write(rt_device_t dev, RT_ASSERT(bus != RT_NULL); RT_ASSERT(buffer != RT_NULL); - i2c_dbg("I2C bus dev [%s] writing %u bytes.\n", dev->parent.name, count); + LOG_D("I2C bus dev [%s] writing %u bytes.", dev->parent.name, count); addr = pos & 0xffff; flags = (pos >> 16) & 0xffff; diff --git a/components/drivers/include/drivers/can.h b/components/drivers/include/drivers/can.h index c61fb19eaa..d4fcc845b4 100644 --- a/components/drivers/include/drivers/can.h +++ b/components/drivers/include/drivers/can.h @@ -221,7 +221,7 @@ struct rt_can_msg rt_uint32_t rsv : 1; rt_uint32_t len : 8; rt_uint32_t priv : 8; - rt_uint32_t hdr : 8; + rt_int32_t hdr : 8; rt_uint32_t reserved : 8; rt_uint8_t data[8]; }; @@ -252,7 +252,7 @@ struct rt_can_rx_fifo #define RT_CAN_EVENT_RX_IND 0x01 /* Rx indication */ #define RT_CAN_EVENT_TX_DONE 0x02 /* Tx complete */ -#define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx complete */ +#define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx fail */ #define RT_CAN_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */ #define RT_CAN_EVENT_RXOF_IND 0x06 /* Rx overflow */ @@ -278,7 +278,7 @@ struct rt_can_ops int (*recvmsg)(struct rt_can_device *can, void *buf, rt_uint32_t boxno); }; -rt_err_t rt_hw_can_register(struct rt_can_device *can, +rt_err_t rt_hw_can_register(struct rt_can_device *can, const char *name, const struct rt_can_ops *ops, void *data); diff --git a/components/drivers/include/drivers/encoder.h b/components/drivers/include/drivers/encoder.h deleted file mode 100644 index f338f9e845..0000000000 --- a/components/drivers/include/drivers/encoder.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-08-08 balanceTWK the first version - */ - -#ifndef __ENCODER_H__ -#define __ENCODER_H__ - -#include <rtthread.h> -#include <rtdevice.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* encoder control command */ -#define ENCODER_CMD_GET_TYPE (128 + 0) /* get a encoder type information */ -#define ENCODER_CMD_ENABLE (128 + 1) /* enable encoder */ -#define ENCODER_CMD_DISABLE (128 + 2) /* disable encoder */ -#define ENCODER_CMD_CLEAR_COUNT (128 + 3) /* clear encoder count */ - -/* encoder type */ -enum rt_encoder_type -{ - UNKNOWN_ENCODER_TYPE = 0x00, /* Unknown encoder type */ - SINGLE_PHASE_ENCODER, /* single phase encoder */ - AB_PHASE_ENCODER /* two phase encoder */ -}; - -struct rt_encoder_device; - -struct rt_encoder_ops -{ - rt_err_t (*init)(struct rt_encoder_device *encoder); - rt_int32_t (*get_count)(struct rt_encoder_device *encoder); - rt_err_t (*clear_count)(struct rt_encoder_device *encoder); - rt_err_t (*control)(struct rt_encoder_device *encoder, rt_uint32_t cmd, void *args); -}; - -struct rt_encoder_device -{ - struct rt_device parent; - const struct rt_encoder_ops *ops; - enum rt_encoder_type type; -}; - -rt_err_t rt_device_encoder_register(struct rt_encoder_device *encoder, const char *name, void *user_data); - -#ifdef __cplusplus -} -#endif - -#endif /* __ENCODER_H__ */ diff --git a/components/drivers/include/drivers/i2c.h b/components/drivers/include/drivers/i2c.h index c6376efa89..17d57288cd 100644 --- a/components/drivers/include/drivers/i2c.h +++ b/components/drivers/include/drivers/i2c.h @@ -67,12 +67,6 @@ struct rt_i2c_client rt_uint16_t client_addr; }; -#ifdef RT_I2C_DEBUG -#define i2c_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__) -#else -#define i2c_dbg(fmt, ...) -#endif - rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus, const char *bus_name); struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name); diff --git a/components/drivers/include/drivers/pm.h b/components/drivers/include/drivers/pm.h index e35b21cd48..dd5875aa1d 100644 --- a/components/drivers/include/drivers/pm.h +++ b/components/drivers/include/drivers/pm.h @@ -86,8 +86,8 @@ struct rt_pm; */ struct rt_pm_ops { - void (*sleep)(struct rt_pm *pm, uint8_t mode); - void (*run)(struct rt_pm *pm, uint8_t mode); + void (*sleep)(struct rt_pm *pm, rt_uint8_t mode); + void (*run)(struct rt_pm *pm, rt_uint8_t mode); void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout); void (*timer_stop)(struct rt_pm *pm); rt_tick_t (*timer_get_tick)(struct rt_pm *pm); @@ -95,9 +95,9 @@ struct rt_pm_ops struct rt_device_pm_ops { - int (*suspend)(const struct rt_device *device, uint8_t mode); - void (*resume)(const struct rt_device *device, uint8_t mode); - int (*frequency_change)(const struct rt_device *device, uint8_t mode); + int (*suspend)(const struct rt_device *device, rt_uint8_t mode); + void (*resume)(const struct rt_device *device, rt_uint8_t mode); + int (*frequency_change)(const struct rt_device *device, rt_uint8_t mode); }; struct rt_device_pm @@ -137,22 +137,22 @@ enum struct rt_pm_notify { - void (*notify)(uint8_t event, uint8_t mode, void *data); + void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data); void *data; }; -void rt_pm_request(uint8_t sleep_mode); -void rt_pm_release(uint8_t sleep_mode); -int rt_pm_run_enter(uint8_t run_mode); +void rt_pm_request(rt_uint8_t sleep_mode); +void rt_pm_release(rt_uint8_t sleep_mode); +int rt_pm_run_enter(rt_uint8_t run_mode); void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops); void rt_pm_device_unregister(struct rt_device *device); -void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), void *data); -void rt_pm_default_set(uint8_t sleep_mode); +void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data); +void rt_pm_default_set(rt_uint8_t sleep_mode); void rt_system_pm_init(const struct rt_pm_ops *ops, - uint8_t timer_mask, + rt_uint8_t timer_mask, void *user_data); #endif /* __PM_H__ */ diff --git a/components/drivers/include/drivers/pulse_encoder.h b/components/drivers/include/drivers/pulse_encoder.h new file mode 100644 index 0000000000..0c7df04cd6 --- /dev/null +++ b/components/drivers/include/drivers/pulse_encoder.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-08 balanceTWK the first version + */ + +#ifndef __PULSE_ENCODER_H__ +#define __PULSE_ENCODER_H__ + +#include <rtthread.h> +#include <rtdevice.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* pulse_encoder control command */ +#define PULSE_ENCODER_CMD_GET_TYPE (128 + 0) /* get a pulse_encoder type information */ +#define PULSE_ENCODER_CMD_ENABLE (128 + 1) /* enable pulse_encoder */ +#define PULSE_ENCODER_CMD_DISABLE (128 + 2) /* disable pulse_encoder */ +#define PULSE_ENCODER_CMD_CLEAR_COUNT (128 + 3) /* clear pulse_encoder count */ + +/* pulse_encoder type */ +enum rt_pulse_encoder_type +{ + UNKNOWN_PULSE_ENCODER_TYPE = 0x00, /* Unknown pulse_encoder type */ + SINGLE_PHASE_PULSE_ENCODER, /* single phase pulse_encoder */ + AB_PHASE_PULSE_ENCODER /* two phase pulse_encoder */ +}; + +struct rt_pulse_encoder_device; + +struct rt_pulse_encoder_ops +{ + rt_err_t (*init)(struct rt_pulse_encoder_device *pulse_encoder); + rt_int32_t (*get_count)(struct rt_pulse_encoder_device *pulse_encoder); + rt_err_t (*clear_count)(struct rt_pulse_encoder_device *pulse_encoder); + rt_err_t (*control)(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args); +}; + +struct rt_pulse_encoder_device +{ + struct rt_device parent; + const struct rt_pulse_encoder_ops *ops; + enum rt_pulse_encoder_type type; +}; + +rt_err_t rt_device_pulse_encoder_register(struct rt_pulse_encoder_device *pulse_encoder, const char *name, void *user_data); + +#ifdef __cplusplus +} +#endif + +#endif /* __PULSE_ENCODER_H__ */ diff --git a/components/drivers/include/drivers/rt_inputcapture.h b/components/drivers/include/drivers/rt_inputcapture.h new file mode 100644 index 0000000000..0cadf6444c --- /dev/null +++ b/components/drivers/include/drivers/rt_inputcapture.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-13 balanceTWK first version. + */ + +#ifndef __RT_INPUT_CAPTURE_H__ +#define __RT_INPUT_CAPTURE_H__ + +#include <rtthread.h> +#include <rtdevice.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* capture control command */ +#define INPUTCAPTURE_CMD_CLEAR_BUF (128 + 0) /* clear capture buf */ +#define INPUTCAPTURE_CMD_SET_WATERMARK (128 + 1) /* Set the callback threshold */ + +struct rt_inputcapture_data +{ + rt_uint32_t pulsewidth_us; + rt_bool_t is_high; +}; + +struct rt_inputcapture_device +{ + struct rt_device parent; + + const struct rt_inputcapture_ops *ops; + struct rt_ringbuffer *ringbuff; + rt_size_t watermark; +}; + +/** + * capture operators + */ +struct rt_inputcapture_ops +{ + rt_err_t (*init)(struct rt_inputcapture_device *inputcapture); + rt_err_t (*open)(struct rt_inputcapture_device *inputcapture); + rt_err_t (*close)(struct rt_inputcapture_device *inputcapture); + rt_err_t (*get_pulsewidth)(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us); +}; + +void rt_hw_capture_isr(struct rt_inputcapture_device *inputcapture, rt_bool_t level); + +rt_err_t rt_device_inputcapture_register(struct rt_inputcapture_device *inputcapture, + const char *name, + void *data); +#ifdef __cplusplus +} +#endif + +#endif /* __RT_INPUT_CAPTURE_H__ */ diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h index 0c009e9580..623c085430 100644 --- a/components/drivers/include/rtdevice.h +++ b/components/drivers/include/rtdevice.h @@ -126,8 +126,12 @@ extern "C" { #include "drivers/crypto.h" #endif -#ifdef RT_USING_ENCODER -#include "drivers/encoder.h" +#ifdef RT_USING_PULSE_ENCODER +#include "drivers/pulse_encoder.h" +#endif + +#ifdef RT_USING_INPUT_CAPTURE +#include "drivers/rt_inputcapture.h" #endif #ifdef __cplusplus diff --git a/components/drivers/misc/SConscript b/components/drivers/misc/SConscript index 3bfb73fea0..8a9fdb5eb9 100644 --- a/components/drivers/misc/SConscript +++ b/components/drivers/misc/SConscript @@ -14,8 +14,11 @@ if GetDepend(['RT_USING_ADC']): if GetDepend(['RT_USING_PWM']): src = src + ['rt_drv_pwm.c'] -if GetDepend(['RT_USING_ENCODER']): - src = src + ['encoder.c'] +if GetDepend(['RT_USING_PULSE_ENCODER']): + src = src + ['pulse_encoder.c'] + +if GetDepend(['RT_USING_INPUT_CAPTURE']): + src = src + ['rt_inputcapture.c'] if len(src): group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/components/drivers/misc/encoder.c b/components/drivers/misc/encoder.c deleted file mode 100644 index e9e1da0f40..0000000000 --- a/components/drivers/misc/encoder.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-08-08 balanceTWK the first version - */ - -#include <rtthread.h> -#include <rtdevice.h> - -static rt_err_t rt_encoder_init(struct rt_device *dev) -{ - struct rt_encoder_device *encoder; - - encoder = (struct rt_encoder_device *)dev; - if (encoder->ops->init) - { - return encoder->ops->init(encoder); - } - else - { - return -RT_ENOSYS; - } -} - -static rt_err_t rt_encoder_open(struct rt_device *dev, rt_uint16_t oflag) -{ - struct rt_encoder_device *encoder; - - encoder = (struct rt_encoder_device *)dev; - if (encoder->ops->control) - { - return encoder->ops->control(encoder, ENCODER_CMD_ENABLE, RT_NULL); - } - else - { - return -RT_ENOSYS; - } -} - -static rt_err_t rt_encoder_close(struct rt_device *dev) -{ - struct rt_encoder_device *encoder; - - encoder = (struct rt_encoder_device *)dev; - if (encoder->ops->control) - { - return encoder->ops->control(encoder, ENCODER_CMD_DISABLE, RT_NULL); - } - else - { - return -RT_ENOSYS; - } -} - -static rt_size_t rt_encoder_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - struct rt_encoder_device *encoder; - - encoder = (struct rt_encoder_device *)dev; - if (encoder->ops->get_count) - { - *(rt_int32_t *)buffer = encoder->ops->get_count(encoder); - } - return 1; -} - -static rt_err_t rt_encoder_control(struct rt_device *dev, int cmd, void *args) -{ - rt_err_t result; - struct rt_encoder_device *encoder; - - result = RT_EOK; - encoder = (struct rt_encoder_device *)dev; - switch (cmd) - { - case ENCODER_CMD_CLEAR_COUNT: - result = encoder->ops->clear_count(encoder); - break; - case ENCODER_CMD_GET_TYPE: - *(enum rt_encoder_type *)args = encoder->type; - break; - case ENCODER_CMD_ENABLE: - case ENCODER_CMD_DISABLE: - result = encoder->ops->control(encoder, cmd, args); - break; - default: - result = -RT_ENOSYS; - break; - } - - return result; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops encoder_ops = -{ - rt_encoder_init, - rt_encoder_open, - rt_encoder_close, - rt_encoder_read, - RT_NULL, - rt_encoder_control -}; -#endif - -rt_err_t rt_device_encoder_register(struct rt_encoder_device *encoder, const char *name, void *user_data) -{ - struct rt_device *device; - - RT_ASSERT(encoder != RT_NULL); - RT_ASSERT(encoder->ops != RT_NULL); - - device = &(encoder->parent); - - device->type = RT_Device_Class_Miscellaneous; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &encoder_ops; -#else - device->init = rt_encoder_init; - device->open = rt_encoder_open; - device->close = rt_encoder_close; - device->read = rt_encoder_read; - device->write = RT_NULL; - device->control = rt_encoder_control; -#endif - device->user_data = user_data; - - return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE); -} diff --git a/components/drivers/misc/pulse_encoder.c b/components/drivers/misc/pulse_encoder.c new file mode 100644 index 0000000000..3145c24675 --- /dev/null +++ b/components/drivers/misc/pulse_encoder.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-08 balanceTWK the first version + */ + +#include <rtthread.h> +#include <rtdevice.h> + +static rt_err_t rt_pulse_encoder_init(struct rt_device *dev) +{ + struct rt_pulse_encoder_device *pulse_encoder; + + pulse_encoder = (struct rt_pulse_encoder_device *)dev; + if (pulse_encoder->ops->init) + { + return pulse_encoder->ops->init(pulse_encoder); + } + else + { + return -RT_ENOSYS; + } +} + +static rt_err_t rt_pulse_encoder_open(struct rt_device *dev, rt_uint16_t oflag) +{ + struct rt_pulse_encoder_device *pulse_encoder; + + pulse_encoder = (struct rt_pulse_encoder_device *)dev; + if (pulse_encoder->ops->control) + { + return pulse_encoder->ops->control(pulse_encoder, PULSE_ENCODER_CMD_ENABLE, RT_NULL); + } + else + { + return -RT_ENOSYS; + } +} + +static rt_err_t rt_pulse_encoder_close(struct rt_device *dev) +{ + struct rt_pulse_encoder_device *pulse_encoder; + + pulse_encoder = (struct rt_pulse_encoder_device *)dev; + if (pulse_encoder->ops->control) + { + return pulse_encoder->ops->control(pulse_encoder, PULSE_ENCODER_CMD_DISABLE, RT_NULL); + } + else + { + return -RT_ENOSYS; + } +} + +static rt_size_t rt_pulse_encoder_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + struct rt_pulse_encoder_device *pulse_encoder; + + pulse_encoder = (struct rt_pulse_encoder_device *)dev; + if (pulse_encoder->ops->get_count) + { + *(rt_int32_t *)buffer = pulse_encoder->ops->get_count(pulse_encoder); + } + return 1; +} + +static rt_err_t rt_pulse_encoder_control(struct rt_device *dev, int cmd, void *args) +{ + rt_err_t result; + struct rt_pulse_encoder_device *pulse_encoder; + + result = RT_EOK; + pulse_encoder = (struct rt_pulse_encoder_device *)dev; + switch (cmd) + { + case PULSE_ENCODER_CMD_CLEAR_COUNT: + result = pulse_encoder->ops->clear_count(pulse_encoder); + break; + case PULSE_ENCODER_CMD_GET_TYPE: + *(enum rt_pulse_encoder_type *)args = pulse_encoder->type; + break; + case PULSE_ENCODER_CMD_ENABLE: + case PULSE_ENCODER_CMD_DISABLE: + result = pulse_encoder->ops->control(pulse_encoder, cmd, args); + break; + default: + result = -RT_ENOSYS; + break; + } + + return result; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops pulse_encoder_ops = +{ + rt_pulse_encoder_init, + rt_pulse_encoder_open, + rt_pulse_encoder_close, + rt_pulse_encoder_read, + RT_NULL, + rt_pulse_encoder_control +}; +#endif + +rt_err_t rt_device_pulse_encoder_register(struct rt_pulse_encoder_device *pulse_encoder, const char *name, void *user_data) +{ + struct rt_device *device; + + RT_ASSERT(pulse_encoder != RT_NULL); + RT_ASSERT(pulse_encoder->ops != RT_NULL); + + device = &(pulse_encoder->parent); + + device->type = RT_Device_Class_Miscellaneous; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + +#ifdef RT_USING_DEVICE_OPS + device->ops = &pulse_encoder_ops; +#else + device->init = rt_pulse_encoder_init; + device->open = rt_pulse_encoder_open; + device->close = rt_pulse_encoder_close; + device->read = rt_pulse_encoder_read; + device->write = RT_NULL; + device->control = rt_pulse_encoder_control; +#endif + device->user_data = user_data; + + return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE); +} diff --git a/components/drivers/misc/rt_drv_pwm.c b/components/drivers/misc/rt_drv_pwm.c index 2b7986b4d8..97d38d51b3 100644 --- a/components/drivers/misc/rt_drv_pwm.c +++ b/components/drivers/misc/rt_drv_pwm.c @@ -259,7 +259,7 @@ static int pwm_set(int argc, char **argv) _exit: return result; } -MSH_CMD_EXPORT(pwm_set, pwm_set 1 100 50); +MSH_CMD_EXPORT(pwm_set, pwm_set pwm1 1 100 50); #endif /* FINSH_USING_MSH */ #endif /* RT_USING_FINSH */ diff --git a/components/drivers/misc/rt_inputcapture.c b/components/drivers/misc/rt_inputcapture.c new file mode 100644 index 0000000000..d1886186d7 --- /dev/null +++ b/components/drivers/misc/rt_inputcapture.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-13 balanceTWK the first version + */ + +#include <rtthread.h> +#include <rtdevice.h> +#include <rtdbg.h> + +static rt_err_t rt_inputcapture_init(struct rt_device *dev) +{ + rt_err_t ret; + struct rt_inputcapture_device *inputcapture; + + RT_ASSERT(dev != RT_NULL); + + ret = RT_EOK; + inputcapture = (struct rt_inputcapture_device *)dev; + inputcapture->watermark = RT_INPUT_CAPTURE_RB_SIZE / 2; + if (inputcapture->ops->init) + { + ret = inputcapture->ops->init(inputcapture); + } + + return ret; +} + +static rt_err_t rt_inputcapture_open(struct rt_device *dev, rt_uint16_t oflag) +{ + rt_err_t ret; + struct rt_inputcapture_device *inputcapture; + + RT_ASSERT(dev != RT_NULL); + + ret = RT_EOK; + inputcapture = (struct rt_inputcapture_device *)dev; + if (inputcapture->ringbuff == RT_NULL) + { + inputcapture->ringbuff = rt_ringbuffer_create(sizeof(struct rt_inputcapture_data) * RT_INPUT_CAPTURE_RB_SIZE); + } + if (inputcapture->ops->open) + { + ret = inputcapture->ops->open(inputcapture); + } + + return ret; +} + +static rt_err_t rt_inputcapture_close(struct rt_device *dev) +{ + rt_err_t ret; + struct rt_inputcapture_device *inputcapture; + + RT_ASSERT(dev != RT_NULL); + + ret = -RT_ERROR; + inputcapture = (struct rt_inputcapture_device *)dev; + + if (inputcapture->ops->close) + { + ret = inputcapture->ops->close(inputcapture); + } + + if (ret != RT_EOK) + { + return ret; + } + + if (inputcapture->ringbuff) + { + rt_ringbuffer_destroy(inputcapture->ringbuff); + inputcapture->ringbuff = RT_NULL; + } + return ret; +} + +static rt_size_t rt_inputcapture_read(struct rt_device *dev, + rt_off_t pos, + void *buffer, + rt_size_t size) +{ + rt_size_t receive_size; + struct rt_inputcapture_device *inputcapture; + + RT_ASSERT(dev != RT_NULL); + + inputcapture = (struct rt_inputcapture_device *)dev; + receive_size = rt_ringbuffer_get(inputcapture->ringbuff, (rt_uint8_t *)buffer, sizeof(struct rt_inputcapture_data) * size); + + return receive_size / sizeof(struct rt_inputcapture_data); +} + +static rt_err_t rt_inputcapture_control(struct rt_device *dev, int cmd, void *args) +{ + rt_err_t result; + struct rt_inputcapture_device *inputcapture; + + RT_ASSERT(dev != RT_NULL); + + result = RT_EOK; + inputcapture = (struct rt_inputcapture_device *)dev; + switch (cmd) + { + case INPUTCAPTURE_CMD_CLEAR_BUF: + if (inputcapture->ringbuff) + { + rt_ringbuffer_reset(inputcapture->ringbuff); + } + break; + case INPUTCAPTURE_CMD_SET_WATERMARK: + inputcapture->watermark = *(rt_size_t *)args; + break; + default: + result = -RT_ENOSYS; + break; + } + + return result; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops inputcapture_ops = +{ + rt_inputcapture_init, + rt_inputcapture_open, + rt_inputcapture_close, + rt_inputcapture_read, + RT_NULL, + rt_inputcapture_control +}; +#endif + +rt_err_t rt_device_inputcapture_register(struct rt_inputcapture_device *inputcapture, const char *name, void *user_data) +{ + struct rt_device *device; + + RT_ASSERT(inputcapture != RT_NULL); + RT_ASSERT(inputcapture->ops != RT_NULL); + RT_ASSERT(inputcapture->ops->get_pulsewidth != RT_NULL); + + device = &(inputcapture->parent); + + device->type = RT_Device_Class_Miscellaneous; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + inputcapture->ringbuff = RT_NULL; + +#ifdef RT_USING_DEVICE_OPS + device->ops = &inputcapture_ops; +#else + device->init = rt_inputcapture_init; + device->open = rt_inputcapture_open; + device->close = rt_inputcapture_close; + device->read = rt_inputcapture_read; + device->write = RT_NULL; + device->control = rt_inputcapture_control; +#endif + device->user_data = user_data; + + return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE); +} + +/** + * This function is ISR for inputcapture interrupt. + * level: RT_TRUE denotes high level pulse, and RT_FALSE denotes low level pulse. + */ +void rt_hw_inputcapture_isr(struct rt_inputcapture_device *inputcapture, rt_bool_t level) +{ + struct rt_inputcapture_data data; + rt_size_t receive_size; + if (inputcapture->ops->get_pulsewidth(inputcapture, &data.pulsewidth_us) != RT_EOK) + { + return; + } + + data.is_high = level; + if (rt_ringbuffer_put(inputcapture->ringbuff, (rt_uint8_t *)&data, sizeof(struct rt_inputcapture_data)) == 0) + { + LOG_W("inputcapture ringbuffer doesn't have enough space."); + } + + receive_size = rt_ringbuffer_data_len(inputcapture->ringbuff) / sizeof(struct rt_inputcapture_data); + + if (receive_size >= inputcapture->watermark) + { + /* indicate to upper layer application */ + if (inputcapture->parent.rx_indicate != RT_NULL) + inputcapture->parent.rx_indicate(&inputcapture->parent, receive_size); + } +} diff --git a/components/drivers/pm/pm.c b/components/drivers/pm/pm.c index 60e71ddfd9..dd7cc2ae63 100644 --- a/components/drivers/pm/pm.c +++ b/components/drivers/pm/pm.c @@ -17,18 +17,18 @@ #ifdef RT_USING_PM static struct rt_pm _pm; -static uint8_t _pm_default_sleep = RT_PM_DEFAULT_SLEEP_MODE; +static rt_uint8_t _pm_default_sleep = RT_PM_DEFAULT_SLEEP_MODE; static struct rt_pm_notify _pm_notify; -static uint8_t _pm_init_flag = 0; +static rt_uint8_t _pm_init_flag = 0; #define RT_PM_TICKLESS_THRESH (2) -RT_WEAK uint32_t rt_pm_enter_critical(uint8_t sleep_mode) +RT_WEAK rt_uint32_t rt_pm_enter_critical(rt_uint8_t sleep_mode) { return rt_hw_interrupt_disable(); } -RT_WEAK void rt_pm_exit_critical(uint32_t ctx, uint8_t sleep_mode) +RT_WEAK void rt_pm_exit_critical(rt_uint32_t ctx, rt_uint8_t sleep_mode) { rt_hw_interrupt_enable(ctx); } @@ -36,7 +36,7 @@ RT_WEAK void rt_pm_exit_critical(uint32_t ctx, uint8_t sleep_mode) /** * This function will suspend all registered devices */ -static int _pm_device_suspend(uint8_t mode) +static int _pm_device_suspend(rt_uint8_t mode) { int index, ret = RT_EOK; @@ -45,8 +45,8 @@ static int _pm_device_suspend(uint8_t mode) if (_pm.device_pm[index].ops->suspend != RT_NULL) { ret = _pm.device_pm[index].ops->suspend(_pm.device_pm[index].device, mode); - if (ret != RT_EOK) - break; + if(ret != RT_EOK) + break; } } @@ -56,7 +56,7 @@ static int _pm_device_suspend(uint8_t mode) /** * This function will resume all registered devices */ -static void _pm_device_resume(uint8_t mode) +static void _pm_device_resume(rt_uint8_t mode) { int index; @@ -72,7 +72,7 @@ static void _pm_device_resume(uint8_t mode) /** * This function will update the frequency of all registered devices */ -static void _pm_device_frequency_change(uint8_t mode) +static void _pm_device_frequency_change(rt_uint8_t mode) { rt_uint32_t index; @@ -106,10 +106,10 @@ static void _pm_frequency_scaling(struct rt_pm *pm) /** * This function selects the sleep mode according to the rt_pm_request/rt_pm_release count. */ -static uint8_t _pm_select_sleep_mode(struct rt_pm *pm) +static rt_uint8_t _pm_select_sleep_mode(struct rt_pm *pm) { int index; - uint8_t mode; + rt_uint8_t mode; mode = _pm_default_sleep; for (index = PM_SLEEP_MODE_NONE; index < PM_SLEEP_MODE_MAX; index ++) @@ -128,7 +128,7 @@ static uint8_t _pm_select_sleep_mode(struct rt_pm *pm) /** * This function changes the power sleep mode base on the result of selection */ -static void _pm_change_sleep_mode(struct rt_pm *pm, uint8_t mode) +static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode) { rt_tick_t timeout_tick, delta_tick; rt_base_t level; @@ -214,7 +214,7 @@ static void _pm_change_sleep_mode(struct rt_pm *pm, uint8_t mode) */ void rt_system_power_manager(void) { - uint8_t mode; + rt_uint8_t mode; if (_pm_init_flag == 0) return; @@ -233,7 +233,7 @@ void rt_system_power_manager(void) * * @param parameter the parameter of run mode or sleep mode */ -void rt_pm_request(uint8_t mode) +void rt_pm_request(rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; @@ -258,7 +258,7 @@ void rt_pm_request(uint8_t mode) * @param parameter the parameter of run mode or sleep mode * */ -void rt_pm_release(uint8_t mode) +void rt_pm_release(rt_uint8_t mode) { rt_ubase_t level; struct rt_pm *pm; @@ -342,7 +342,7 @@ void rt_pm_device_unregister(struct rt_device *device) /** * This function set notification callback for application */ -void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), void *data) +void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data) { _pm_notify.notify = notify; _pm_notify.data = data; @@ -351,7 +351,7 @@ void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), v /** * This function set default sleep mode when no pm_request */ -void rt_pm_default_set(uint8_t sleep_mode) +void rt_pm_default_set(rt_uint8_t sleep_mode) { _pm_default_sleep = sleep_mode; } @@ -428,7 +428,7 @@ static rt_err_t _rt_pm_device_control(rt_device_t dev, return RT_EOK; } -int rt_pm_run_enter(uint8_t mode) +int rt_pm_run_enter(rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; diff --git a/components/drivers/sdio/block_dev.c b/components/drivers/sdio/block_dev.c index cac4fc5036..5db0f38c08 100644 --- a/components/drivers/sdio/block_dev.c +++ b/components/drivers/sdio/block_dev.c @@ -472,7 +472,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) } #ifdef RT_USING_DFS_MNTTABLE - if (0) // if (blk_dev) + if (blk_dev) { LOG_I("try to mount file system!"); /* try to mount file system on this block device */ @@ -507,9 +507,10 @@ void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card) const char * mounted_path = dfs_filesystem_get_mounted_path(&(blk_dev->dev)); if (mounted_path) { - dfs_unmount(mounted_path); + dfs_unmount(mounted_path); + LOG_D("unmount file system %s for device %s.\r\n", mounted_path, blk_dev->dev.parent.name); } - + rt_sem_delete(blk_dev->part.lock); rt_device_unregister(&blk_dev->dev); rt_list_remove(&blk_dev->list); rt_free(blk_dev); diff --git a/components/drivers/sdio/sdio.c b/components/drivers/sdio/sdio.c index f31f5b81a8..65bf87b895 100644 --- a/components/drivers/sdio/sdio.c +++ b/components/drivers/sdio/sdio.c @@ -709,6 +709,16 @@ static rt_int32_t sdio_initialize_function(struct rt_mmcsd_card *card, if (ret) goto err1; + /* + * product/manufacturer id is optional for function CIS, so + * copy it from the card structure as needed. + */ + if (func->product == 0) + { + func->manufacturer = card->cis.manufacturer; + func->product = card->cis.product; + } + card->sdio_function[func_num] = func; return 0; diff --git a/components/drivers/sensors/sensor.c b/components/drivers/sensors/sensor.c index 451d2745f1..91b256bd66 100644 --- a/components/drivers/sensors/sensor.c +++ b/components/drivers/sensors/sensor.c @@ -430,10 +430,12 @@ int rt_hw_sensor_register(rt_sensor_t sensor, result = rt_device_register(device, device_name, flag | RT_DEVICE_FLAG_STANDALONE); if (result != RT_EOK) { + rt_free(device_name); LOG_E("rt_sensor register err code: %d", result); return result; } + rt_free(device_name); LOG_I("rt_sensor init success"); return RT_EOK; } diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c index e1d606557b..50dd7e188b 100644 --- a/components/drivers/serial/serial.c +++ b/components/drivers/serial/serial.c @@ -327,6 +327,18 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t * return size - length; } +static void _serial_check_buffer_size(void) +{ + static rt_bool_t already_output = RT_FALSE; + + if (already_output == RT_FALSE) + { + LOG_W("Warning: There is no enough buffer for saving data," + " please increase the RT_SERIAL_RB_BUFSZ option."); + already_output = RT_TRUE; + } +} + #if defined(RT_USING_POSIX) || defined(RT_SERIAL_USING_DMA) static rt_size_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial) { @@ -430,6 +442,7 @@ static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_siz if(rx_fifo->is_full == RT_TRUE) { + _serial_check_buffer_size(); rx_fifo->get_index = rx_fifo->put_index; } } @@ -1170,6 +1183,8 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event) rx_fifo->get_index += 1; rx_fifo->is_full = RT_TRUE; if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0; + + _serial_check_buffer_size(); } /* enable interrupt */ diff --git a/components/drivers/spi/sfud/inc/sfud_cfg.h b/components/drivers/spi/sfud/inc/sfud_cfg.h index 051de6d577..3b7860062d 100644 --- a/components/drivers/spi/sfud/inc/sfud_cfg.h +++ b/components/drivers/spi/sfud/inc/sfud_cfg.h @@ -59,6 +59,6 @@ #define SFUD_USING_FLASH_INFO_TABLE #endif -#define SFUD_FLASH_DEVICE_TABLE {0} +#define SFUD_FLASH_DEVICE_TABLE {{0}} #endif /* _SFUD_CFG_H_ */ diff --git a/components/drivers/spi/sfud/inc/sfud_flash_def.h b/components/drivers/spi/sfud/inc/sfud_flash_def.h index 8922375557..13a0e702a8 100644 --- a/components/drivers/spi/sfud/inc/sfud_flash_def.h +++ b/components/drivers/spi/sfud/inc/sfud_flash_def.h @@ -124,6 +124,7 @@ typedef struct { {"AT45DB161E", SFUD_MF_ID_ATMEL, 0x26, 0x00, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_DUAL_BUFFER, 512, 0x81}, \ {"W25Q40BV", SFUD_MF_ID_WINBOND, 0x40, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q16BV", SFUD_MF_ID_WINBOND, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ + {"W25Q64DW", SFUD_MF_ID_WINBOND, 0x60, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q128BV", SFUD_MF_ID_WINBOND, 0x40, 0x18, 16L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q256FV", SFUD_MF_ID_WINBOND, 0x40, 0x19, 32L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ {"SST25VF016B", SFUD_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \ diff --git a/components/drivers/usb/usbdevice/SConscript b/components/drivers/usb/usbdevice/SConscript index be0b0c7b50..010b9837a4 100644 --- a/components/drivers/usb/usbdevice/SConscript +++ b/components/drivers/usb/usbdevice/SConscript @@ -24,6 +24,12 @@ if GetDepend('RT_USB_DEVICE_RNDIS'): if GetDepend('RT_USB_DEVICE_WINUSB'): src += Glob('class/winusb.c') + +if GetDepend('RT_USB_DEVICE_AUDIO_MIC'): + src += Glob('class/audio_mic.c') + +if GetDepend('RT_USB_DEVICE_AUDIO_SPEAKER'): + src += Glob('class/audio_speaker.c') CPPPATH = [cwd] diff --git a/components/drivers/usb/usbdevice/class/audio.h b/components/drivers/usb/usbdevice/class/audio.h new file mode 100644 index 0000000000..4bb8994b47 --- /dev/null +++ b/components/drivers/usb/usbdevice/class/audio.h @@ -0,0 +1,676 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * <linux/usb/audio.h> -- USB Audio definitions. + * + * Copyright (C) 2006 Thumtronics Pty Ltd. + * Developed for Thumtronics by Grey Innovation + * Ben Williamson <[email protected]> + * + * This software is distributed under the terms of the GNU General Public + * License ("GPL") version 2, as published by the Free Software Foundation. + * + * This file holds USB constants and structures defined + * by the USB Device Class Definition for Audio Devices. + * Comments below reference relevant sections of that document: + * + * http://www.usb.org/developers/devclass_docs/audio10.pdf + * + * Types and defines in this file are either specific to version 1.0 of + * this standard or common for newer versions. + */ + +#ifndef _UAPI__LINUX_USB_AUDIO_H +#define _UAPI__LINUX_USB_AUDIO_H + +//#include <linux/types.h> +#include <rtthread.h> + +typedef int8_t __s8; +typedef uint8_t __u8; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef int32_t __s32; +typedef uint32_t __u32; +typedef int64_t __s64; +typedef uint64_t __u64; + +#define UAC_USE_FEATURE_UNIT 0 /* Feature unit does not support */ + +/* + * Below are truly Linux-specific types that should never collide with + * any application/library that wants linux/types.h. + */ + +#ifdef __CHECKER__ +#define __bitwise__ __attribute__((bitwise)) +#else +#define __bitwise__ +#endif +#ifdef __CHECK_ENDIAN__ +#define __bitwise __bitwise__ +#else +#define __bitwise +#endif + +typedef __u16 __bitwise __le16; +typedef __u16 __bitwise __be16; +typedef __u32 __bitwise __le32; +typedef __u32 __bitwise __be32; +typedef __u64 __bitwise __le64; +typedef __u64 __bitwise __be64; + +typedef __u16 __bitwise __sum16; +typedef __u32 __bitwise __wsum; + +/* bInterfaceProtocol values to denote the version of the standard used */ +#define UAC_VERSION_1 0x00 +#define UAC_VERSION_2 0x20 +#define UAC_VERSION_3 0x30 + +/* A.2 Audio Interface Subclass Codes */ +#define USB_SUBCLASS_AUDIOCONTROL 0x01 +#define USB_SUBCLASS_AUDIOSTREAMING 0x02 +#define USB_SUBCLASS_MIDISTREAMING 0x03 + +/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */ +#define UAC_HEADER 0x01 +#define UAC_INPUT_TERMINAL 0x02 +#define UAC_OUTPUT_TERMINAL 0x03 +#define UAC_MIXER_UNIT 0x04 +#define UAC_SELECTOR_UNIT 0x05 +#define UAC_FEATURE_UNIT 0x06 +#define UAC1_PROCESSING_UNIT 0x07 +#define UAC1_EXTENSION_UNIT 0x08 + +/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */ +#define UAC_AS_GENERAL 0x01 +#define UAC_FORMAT_TYPE 0x02 +#define UAC_FORMAT_SPECIFIC 0x03 + +/* A.7 Processing Unit Process Types */ +#define UAC_PROCESS_UNDEFINED 0x00 +#define UAC_PROCESS_UP_DOWNMIX 0x01 +#define UAC_PROCESS_DOLBY_PROLOGIC 0x02 +#define UAC_PROCESS_STEREO_EXTENDER 0x03 +#define UAC_PROCESS_REVERB 0x04 +#define UAC_PROCESS_CHORUS 0x05 +#define UAC_PROCESS_DYN_RANGE_COMP 0x06 + +/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */ +#define UAC_EP_GENERAL 0x01 + +/* A.9 Audio Class-Specific Request Codes */ +#define UAC_SET_ 0x00 +#define UAC_GET_ 0x80 + +#define UAC__CUR 0x1 +#define UAC__MIN 0x2 +#define UAC__MAX 0x3 +#define UAC__RES 0x4 +#define UAC__MEM 0x5 + +#define UAC_SET_CUR (UAC_SET_ | UAC__CUR) +#define UAC_GET_CUR (UAC_GET_ | UAC__CUR) +#define UAC_SET_MIN (UAC_SET_ | UAC__MIN) +#define UAC_GET_MIN (UAC_GET_ | UAC__MIN) +#define UAC_SET_MAX (UAC_SET_ | UAC__MAX) +#define UAC_GET_MAX (UAC_GET_ | UAC__MAX) +#define UAC_SET_RES (UAC_SET_ | UAC__RES) +#define UAC_GET_RES (UAC_GET_ | UAC__RES) +#define UAC_SET_MEM (UAC_SET_ | UAC__MEM) +#define UAC_GET_MEM (UAC_GET_ | UAC__MEM) + +#define UAC_GET_STAT 0xff + +/* A.10 Control Selector Codes */ + +/* A.10.1 Terminal Control Selectors */ +#define UAC_TERM_COPY_PROTECT 0x01 + +/* A.10.2 Feature Unit Control Selectors */ +#define UAC_FU_MUTE 0x01 +#define UAC_FU_VOLUME 0x02 +#define UAC_FU_BASS 0x03 +#define UAC_FU_MID 0x04 +#define UAC_FU_TREBLE 0x05 +#define UAC_FU_GRAPHIC_EQUALIZER 0x06 +#define UAC_FU_AUTOMATIC_GAIN 0x07 +#define UAC_FU_DELAY 0x08 +#define UAC_FU_BASS_BOOST 0x09 +#define UAC_FU_LOUDNESS 0x0a + +#define UAC_CONTROL_BIT(CS) (1 << ((CS) - 1)) + +/* A.10.3.1 Up/Down-mix Processing Unit Controls Selectors */ +#define UAC_UD_ENABLE 0x01 +#define UAC_UD_MODE_SELECT 0x02 + +/* A.10.3.2 Dolby Prologic (tm) Processing Unit Controls Selectors */ +#define UAC_DP_ENABLE 0x01 +#define UAC_DP_MODE_SELECT 0x02 + +/* A.10.3.3 3D Stereo Extender Processing Unit Control Selectors */ +#define UAC_3D_ENABLE 0x01 +#define UAC_3D_SPACE 0x02 + +/* A.10.3.4 Reverberation Processing Unit Control Selectors */ +#define UAC_REVERB_ENABLE 0x01 +#define UAC_REVERB_LEVEL 0x02 +#define UAC_REVERB_TIME 0x03 +#define UAC_REVERB_FEEDBACK 0x04 + +/* A.10.3.5 Chorus Processing Unit Control Selectors */ +#define UAC_CHORUS_ENABLE 0x01 +#define UAC_CHORUS_LEVEL 0x02 +#define UAC_CHORUS_RATE 0x03 +#define UAC_CHORUS_DEPTH 0x04 + +/* A.10.3.6 Dynamic Range Compressor Unit Control Selectors */ +#define UAC_DCR_ENABLE 0x01 +#define UAC_DCR_RATE 0x02 +#define UAC_DCR_MAXAMPL 0x03 +#define UAC_DCR_THRESHOLD 0x04 +#define UAC_DCR_ATTACK_TIME 0x05 +#define UAC_DCR_RELEASE_TIME 0x06 + +/* A.10.4 Extension Unit Control Selectors */ +#define UAC_XU_ENABLE 0x01 + +/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */ +#define UAC_MS_HEADER 0x01 +#define UAC_MIDI_IN_JACK 0x02 +#define UAC_MIDI_OUT_JACK 0x03 + +/* MIDI - A.1 MS Class-Specific Endpoint Descriptor Subtypes */ +#define UAC_MS_GENERAL 0x01 + +/* Terminals - 2.1 USB Terminal Types */ +#define UAC_TERMINAL_UNDEFINED 0x100 +#define UAC_TERMINAL_STREAMING 0x101 +#define UAC_TERMINAL_VENDOR_SPEC 0x1FF + +/* Terminal Control Selectors */ +/* 4.3.2 Class-Specific AC Interface Descriptor */ +struct uac1_ac_header_descriptor { + __u8 bLength; /* 8 + n */ + __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ + __u8 bDescriptorSubtype; /* UAC_MS_HEADER */ + __le16 bcdADC; /* 0x0100 */ + __le16 wTotalLength; /* includes Unit and Terminal desc. */ + __u8 bInCollection; /* n */ + __u8 baInterfaceNr[]; /* [n] */ +} __attribute__ ((packed)); + +#define UAC_DT_AC_HEADER_SIZE(n) (8 + (n)) + +/* As above, but more useful for defining your own descriptors: */ +#define DECLARE_UAC_AC_HEADER_DESCRIPTOR(n) \ +struct uac1_ac_header_descriptor_##n { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubtype; \ + __le16 bcdADC; \ + __le16 wTotalLength; \ + __u8 bInCollection; \ + __u8 baInterfaceNr[n]; \ +} __attribute__ ((packed)) + +/* 4.3.2.1 Input Terminal Descriptor */ +struct uac_input_terminal_descriptor { + __u8 bLength; /* in bytes: 12 */ + __u8 bDescriptorType; /* CS_INTERFACE descriptor type */ + __u8 bDescriptorSubtype; /* INPUT_TERMINAL descriptor subtype */ + __u8 bTerminalID; /* Constant uniquely terminal ID */ + __le16 wTerminalType; /* USB Audio Terminal Types */ + __u8 bAssocTerminal; /* ID of the Output Terminal associated */ + __u8 bNrChannels; /* Number of logical output channels */ + __le16 wChannelConfig; + __u8 iChannelNames; + __u8 iTerminal; +} __attribute__ ((packed)); + +#define UAC_DT_INPUT_TERMINAL_SIZE 12 + +/* Terminals - 2.2 Input Terminal Types */ +#define UAC_INPUT_TERMINAL_UNDEFINED 0x200 +#define UAC_INPUT_TERMINAL_MICROPHONE 0x201 +#define UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE 0x202 +#define UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE 0x203 +#define UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE 0x204 +#define UAC_INPUT_TERMINAL_MICROPHONE_ARRAY 0x205 +#define UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY 0x206 + +/* Terminals - control selectors */ + +#define UAC_TERMINAL_CS_COPY_PROTECT_CONTROL 0x01 + +/* 4.3.2.2 Output Terminal Descriptor */ +struct uac1_output_terminal_descriptor { + __u8 bLength; /* in bytes: 9 */ + __u8 bDescriptorType; /* CS_INTERFACE descriptor type */ + __u8 bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */ + __u8 bTerminalID; /* Constant uniquely terminal ID */ + __le16 wTerminalType; /* USB Audio Terminal Types */ + __u8 bAssocTerminal; /* ID of the Input Terminal associated */ + __u8 bSourceID; /* ID of the connected Unit or Terminal*/ + __u8 iTerminal; +} __attribute__ ((packed)); + +#define UAC_DT_OUTPUT_TERMINAL_SIZE 9 + +/* Terminals - 2.3 Output Terminal Types */ +#define UAC_OUTPUT_TERMINAL_UNDEFINED 0x300 +#define UAC_OUTPUT_TERMINAL_SPEAKER 0x301 +#define UAC_OUTPUT_TERMINAL_HEADPHONES 0x302 +#define UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x303 +#define UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER 0x304 +#define UAC_OUTPUT_TERMINAL_ROOM_SPEAKER 0x305 +#define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306 +#define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307 + +/* Terminals - 2.4 Bi-directional Terminal Types */ +#define UAC_BIDIR_TERMINAL_UNDEFINED 0x400 +#define UAC_BIDIR_TERMINAL_HANDSET 0x401 +#define UAC_BIDIR_TERMINAL_HEADSET 0x402 +#define UAC_BIDIR_TERMINAL_SPEAKER_PHONE 0x403 +#define UAC_BIDIR_TERMINAL_ECHO_SUPPRESSING 0x404 +#define UAC_BIDIR_TERMINAL_ECHO_CANCELING 0x405 + +/* Set bControlSize = 2 as default setting */ +#define UAC_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2) + +/* As above, but more useful for defining your own descriptors: */ +#define DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(ch) \ +struct uac_feature_unit_descriptor_##ch { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubtype; \ + __u8 bUnitID; \ + __u8 bSourceID; \ + __u8 bControlSize; \ + __le16 bmaControls[ch + 1]; \ + __u8 iFeature; \ +} __attribute__ ((packed)) + +/* 4.3.2.3 Mixer Unit Descriptor */ +struct uac_mixer_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bUnitID; + __u8 bNrInPins; + __u8 baSourceID[]; +} __attribute__ ((packed)); + +static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc) +{ + return desc->baSourceID[desc->bNrInPins]; +} + +static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc, + int protocol) +{ + if (protocol == UAC_VERSION_1) + return (desc->baSourceID[desc->bNrInPins + 2] << 8) | + desc->baSourceID[desc->bNrInPins + 1]; + else + return (desc->baSourceID[desc->bNrInPins + 4] << 24) | + (desc->baSourceID[desc->bNrInPins + 3] << 16) | + (desc->baSourceID[desc->bNrInPins + 2] << 8) | + (desc->baSourceID[desc->bNrInPins + 1]); +} + +static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc, + int protocol) +{ + return (protocol == UAC_VERSION_1) ? + desc->baSourceID[desc->bNrInPins + 3] : + desc->baSourceID[desc->bNrInPins + 5]; +} + +static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc, + int protocol) +{ + switch (protocol) { + case UAC_VERSION_1: + return &desc->baSourceID[desc->bNrInPins + 4]; + case UAC_VERSION_2: + return &desc->baSourceID[desc->bNrInPins + 6]; + case UAC_VERSION_3: + return &desc->baSourceID[desc->bNrInPins + 2]; + default: + return NULL; + } +} + +static inline __u16 uac3_mixer_unit_wClusterDescrID(struct uac_mixer_unit_descriptor *desc) +{ + return (desc->baSourceID[desc->bNrInPins + 1] << 8) | + desc->baSourceID[desc->bNrInPins]; +} + +static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc) +{ + __u8 *raw = (__u8 *) desc; + return raw[desc->bLength - 1]; +} + +/* 4.3.2.4 Selector Unit Descriptor */ +struct uac_selector_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bUintID; + __u8 bNrInPins; + __u8 baSourceID[]; +} __attribute__ ((packed)); + +static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc) +{ + __u8 *raw = (__u8 *) desc; + return raw[desc->bLength - 1]; +} +#if UAC_USE_FEATURE_UNIT +/* 4.3.2.5 Feature Unit Descriptor */ +struct uac_feature_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bUnitID; + __u8 bSourceID; + __u8 bControlSize; + __u8 bmaControls[0]; /* variable length */ +} __attribute__((packed)); + +static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc) +{ + __u8 *raw = (__u8 *) desc; + return raw[desc->bLength - 1]; +} +#endif +/* 4.3.2.6 Processing Unit Descriptors */ +struct uac_processing_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bUnitID; + __le16 wProcessType; + __u8 bNrInPins; + __u8 baSourceID[]; +} __attribute__ ((packed)); + +static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc) +{ + return desc->baSourceID[desc->bNrInPins]; +} + +static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc, + int protocol) +{ + if (protocol == UAC_VERSION_1) + return (desc->baSourceID[desc->bNrInPins + 2] << 8) | + desc->baSourceID[desc->bNrInPins + 1]; + else + return (desc->baSourceID[desc->bNrInPins + 4] << 24) | + (desc->baSourceID[desc->bNrInPins + 3] << 16) | + (desc->baSourceID[desc->bNrInPins + 2] << 8) | + (desc->baSourceID[desc->bNrInPins + 1]); +} + +static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc, + int protocol) +{ + return (protocol == UAC_VERSION_1) ? + desc->baSourceID[desc->bNrInPins + 3] : + desc->baSourceID[desc->bNrInPins + 5]; +} + +static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc, + int protocol) +{ + switch (protocol) { + case UAC_VERSION_1: + return desc->baSourceID[desc->bNrInPins + 4]; + case UAC_VERSION_2: + return 2; /* in UAC2, this value is constant */ + case UAC_VERSION_3: + return 4; /* in UAC3, this value is constant */ + default: + return 1; + } +} + +static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc, + int protocol) +{ + switch (protocol) { + case UAC_VERSION_1: + return &desc->baSourceID[desc->bNrInPins + 5]; + case UAC_VERSION_2: + return &desc->baSourceID[desc->bNrInPins + 6]; + case UAC_VERSION_3: + return &desc->baSourceID[desc->bNrInPins + 2]; + default: + return NULL; + } +} + +static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc, + int protocol) +{ + __u8 control_size = uac_processing_unit_bControlSize(desc, protocol); + + switch (protocol) { + case UAC_VERSION_1: + case UAC_VERSION_2: + default: + return *(uac_processing_unit_bmControls(desc, protocol) + + control_size); + case UAC_VERSION_3: + return 0; /* UAC3 does not have this field */ + } +} + +static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc, + int protocol) +{ + __u8 control_size = uac_processing_unit_bControlSize(desc, protocol); + + switch (protocol) { + case UAC_VERSION_1: + case UAC_VERSION_2: + default: + return uac_processing_unit_bmControls(desc, protocol) + + control_size + 1; + case UAC_VERSION_3: + return uac_processing_unit_bmControls(desc, protocol) + + control_size; + } +} + +/* + * Extension Unit (XU) has almost compatible layout with Processing Unit, but + * on UAC2, it has a different bmControls size (bControlSize); it's 1 byte for + * XU while 2 bytes for PU. The last iExtension field is a one-byte index as + * well as iProcessing field of PU. + */ +static inline __u8 uac_extension_unit_bControlSize(struct uac_processing_unit_descriptor *desc, + int protocol) +{ + switch (protocol) { + case UAC_VERSION_1: + return desc->baSourceID[desc->bNrInPins + 4]; + case UAC_VERSION_2: + return 1; /* in UAC2, this value is constant */ + case UAC_VERSION_3: + return 4; /* in UAC3, this value is constant */ + default: + return 1; + } +} + +static inline __u8 uac_extension_unit_iExtension(struct uac_processing_unit_descriptor *desc, + int protocol) +{ + __u8 control_size = uac_extension_unit_bControlSize(desc, protocol); + + switch (protocol) { + case UAC_VERSION_1: + case UAC_VERSION_2: + default: + return *(uac_processing_unit_bmControls(desc, protocol) + + control_size); + case UAC_VERSION_3: + return 0; /* UAC3 does not have this field */ + } +} + +/* 4.5.2 Class-Specific AS Interface Descriptor */ +struct uac1_as_header_descriptor { + __u8 bLength; /* in bytes: 7 */ + __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ + __u8 bDescriptorSubtype; /* AS_GENERAL */ + __u8 bTerminalLink; /* Terminal ID of connected Terminal */ + __u8 bDelay; /* Delay introduced by the data path */ + __le16 wFormatTag; /* The Audio Data Format */ +} __attribute__ ((packed)); + +#define UAC_DT_AS_HEADER_SIZE 7 + +/* Formats - A.1.1 Audio Data Format Type I Codes */ +#define UAC_FORMAT_TYPE_I_UNDEFINED 0x0 +#define UAC_FORMAT_TYPE_I_PCM 0x1 +#define UAC_FORMAT_TYPE_I_PCM8 0x2 +#define UAC_FORMAT_TYPE_I_IEEE_FLOAT 0x3 +#define UAC_FORMAT_TYPE_I_ALAW 0x4 +#define UAC_FORMAT_TYPE_I_MULAW 0x5 + +struct uac_format_type_i_continuous_descriptor { + __u8 bLength; /* in bytes: 8 + (ns * 3) */ + __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ + __u8 bDescriptorSubtype; /* FORMAT_TYPE */ + __u8 bFormatType; /* FORMAT_TYPE_1 */ + __u8 bNrChannels; /* physical channels in the stream */ + __u8 bSubframeSize; /* */ + __u8 bBitResolution; + __u8 bSamFreqType; + __u8 tLowerSamFreq[3]; + __u8 tUpperSamFreq[3]; +} __attribute__ ((packed)); + +#define UAC_FORMAT_TYPE_I_CONTINUOUS_DESC_SIZE 14 + +struct uac_format_type_i_discrete_descriptor { + __u8 bLength; /* in bytes: 8 + (ns * 3) */ + __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ + __u8 bDescriptorSubtype; /* FORMAT_TYPE */ + __u8 bFormatType; /* FORMAT_TYPE_1 */ + __u8 bNrChannels; /* physical channels in the stream */ + __u8 bSubframeSize; /* */ + __u8 bBitResolution; + __u8 bSamFreqType; + __u8 tSamFreq[][3]; +} __attribute__ ((packed)); + +#define DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(n) \ +struct uac_format_type_i_discrete_descriptor_##n { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubtype; \ + __u8 bFormatType; \ + __u8 bNrChannels; \ + __u8 bSubframeSize; \ + __u8 bBitResolution; \ + __u8 bSamFreqType; \ + __u8 tSamFreq[n][3]; \ +} __attribute__ ((packed)) + +#define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n) (8 + (n * 3)) + +struct uac_format_type_i_ext_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bFormatType; + __u8 bSubslotSize; + __u8 bBitResolution; + __u8 bHeaderLength; + __u8 bControlSize; + __u8 bSideBandProtocol; +} __attribute__((packed)); + +/* Formats - Audio Data Format Type I Codes */ + +#define UAC_FORMAT_TYPE_II_MPEG 0x1001 +#define UAC_FORMAT_TYPE_II_AC3 0x1002 + +struct uac_format_type_ii_discrete_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bFormatType; + __le16 wMaxBitRate; + __le16 wSamplesPerFrame; + __u8 bSamFreqType; + __u8 tSamFreq[][3]; +} __attribute__((packed)); + +struct uac_format_type_ii_ext_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bFormatType; + __le16 wMaxBitRate; + __le16 wSamplesPerFrame; + __u8 bHeaderLength; + __u8 bSideBandProtocol; +} __attribute__((packed)); + +/* type III */ +#define UAC_FORMAT_TYPE_III_IEC1937_AC3 0x2001 +#define UAC_FORMAT_TYPE_III_IEC1937_MPEG1_LAYER1 0x2002 +#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_NOEXT 0x2003 +#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_EXT 0x2004 +#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER1_LS 0x2005 +#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER23_LS 0x2006 + +/* Formats - A.2 Format Type Codes */ +#define UAC_FORMAT_TYPE_UNDEFINED 0x0 +#define UAC_FORMAT_TYPE_I 0x1 +#define UAC_FORMAT_TYPE_II 0x2 +#define UAC_FORMAT_TYPE_III 0x3 +#define UAC_EXT_FORMAT_TYPE_I 0x81 +#define UAC_EXT_FORMAT_TYPE_II 0x82 +#define UAC_EXT_FORMAT_TYPE_III 0x83 + +struct uac_iso_endpoint_descriptor { + __u8 bLength; /* in bytes: 7 */ + __u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */ + __u8 bDescriptorSubtype; /* EP_GENERAL */ + __u8 bmAttributes; + __u8 bLockDelayUnits; + __le16 wLockDelay; +} __attribute__((packed)); +#define UAC_ISO_ENDPOINT_DESC_SIZE 7 + +#define UAC_EP_CS_ATTR_SAMPLE_RATE 0x01 +#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02 +#define UAC_EP_CS_ATTR_FILL_MAX 0x80 + +/* status word format (3.7.1.1) */ + +#define UAC1_STATUS_TYPE_ORIG_MASK 0x0f +#define UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF 0x0 +#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_IF 0x1 +#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_EP 0x2 + +#define UAC1_STATUS_TYPE_IRQ_PENDING (1 << 7) +#define UAC1_STATUS_TYPE_MEM_CHANGED (1 << 6) + +struct uac1_status_word { + __u8 bStatusType; + __u8 bOriginator; +} __attribute__((packed)); + + +#endif /* _UAPI__LINUX_USB_AUDIO_H */ diff --git a/components/drivers/usb/usbdevice/class/audio_mic.c b/components/drivers/usb/usbdevice/class/audio_mic.c new file mode 100644 index 0000000000..4ac85711ad --- /dev/null +++ b/components/drivers/usb/usbdevice/class/audio_mic.c @@ -0,0 +1,577 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-09-07 flybreak the first version + */ + +#include <rthw.h> +#include <rtthread.h> +#include <rtservice.h> +#include <rtdevice.h> + +#include "drivers/usb_device.h" +#include "audio.h" + +#define DBG_TAG "usbd.audio.mic" +#define DBG_LVL DBG_INFO +#include <rtdbg.h> + +#define RECORD_SAMPLERATE 16000 +#define RECORD_CHANNEL 1 +#define RESOLUTION_BITS 16 + +#define RESOLUTION_BYTE (RESOLUTION_BITS / 8) +#define RECORD_PER_MS_SZ ((RECORD_SAMPLERATE * RECORD_CHANNEL * RESOLUTION_BYTE) / 1000) +#define RECORD_BUFFER_SZ (RECORD_PER_MS_SZ * 20) /* 20ms */ + +#if defined(RT_USBD_MIC_DEVICE_NAME) + #define MIC_DEVICE_NAME RT_USBD_MIC_DEVICE_NAME +#else + #define MIC_DEVICE_NAME "mic0" +#endif + +#define EVENT_RECORD_START (1 << 0) +#define EVENT_RECORD_STOP (1 << 1) +#define EVENT_RECORD_DATA (1 << 2) + +/* + * uac mic descriptor define + */ + +#define UAC_CS_INTERFACE 0x24 +#define UAC_CS_ENDPOINT 0x25 + +#define UAC_MAX_PACKET_SIZE 64 +#define UAC_EP_MAX_PACKET_SIZE 32 +#define UAC_CHANNEL_NUM RECORD_CHANNEL +#define UAC_INTR_NUM 1 +#define UAC_CH_NUM 1 +#define UAC_FORMAT_NUM 1 + +struct uac_ac_descriptor +{ +#ifdef RT_USB_DEVICE_COMPOSITE + struct uiad_descriptor iad_desc; +#endif + struct uinterface_descriptor intf_desc; + DECLARE_UAC_AC_HEADER_DESCRIPTOR(UAC_INTR_NUM) hdr_desc; + struct uac_input_terminal_descriptor it_desc; + struct uac1_output_terminal_descriptor ot_desc; +#if UAC_USE_FEATURE_UNIT + DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(UAC_CH_NUM) feature_unit_desc; +#endif +}; + +struct uac_as_descriptor +{ + struct uinterface_descriptor intf_desc; + struct uac1_as_header_descriptor hdr_desc; + DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(UAC_FORMAT_NUM) format_type_desc; + struct uendpoint_descriptor ep_desc; + struct uac_iso_endpoint_descriptor as_ep_desc; +}; + +/* + * uac mic device type + */ + +struct uac_audio_mic +{ + rt_device_t dev; + rt_event_t event; + rt_uint8_t open_count; + + rt_uint8_t *buffer; + rt_uint32_t buffer_index; + + uep_t ep; +}; +static struct uac_audio_mic mic; + +ALIGN(4) +static struct udevice_descriptor dev_desc = +{ + USB_DESC_LENGTH_DEVICE, //bLength; + USB_DESC_TYPE_DEVICE, //type; + USB_BCD_VERSION, //bcdUSB; + USB_CLASS_DEVICE, //bDeviceClass; + 0x00, //bDeviceSubClass; + 0x00, //bDeviceProtocol; + UAC_MAX_PACKET_SIZE, //bMaxPacketSize0; + _VENDOR_ID, //idVendor; + _PRODUCT_ID, //idProduct; + USB_BCD_DEVICE, //bcdDevice; + USB_STRING_MANU_INDEX, //iManufacturer; + USB_STRING_PRODUCT_INDEX, //iProduct; + USB_STRING_SERIAL_INDEX, //iSerialNumber;Unused. + USB_DYNAMIC, //bNumConfigurations; +}; + +//FS and HS needed +ALIGN(4) +static struct usb_qualifier_descriptor dev_qualifier = +{ + sizeof(dev_qualifier), //bLength + USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType + 0x0200, //bcdUSB + USB_CLASS_AUDIO, //bDeviceClass + 0x00, //bDeviceSubClass + 0x00, //bDeviceProtocol + 64, //bMaxPacketSize0 + 0x01, //bNumConfigurations + 0, +}; + +ALIGN(4) +const static char *_ustring[] = +{ + "Language", + "RT-Thread Team.", + "Microphone", + "32021919830108", + "Configuration", + "Interface", +}; + +ALIGN(4) +static struct uac_ac_descriptor ac_desc = +{ +#ifdef RT_USB_DEVICE_COMPOSITE + /* Interface Association Descriptor */ + { + USB_DESC_LENGTH_IAD, + USB_DESC_TYPE_IAD, + USB_DYNAMIC, + 0x02, + USB_CLASS_AUDIO, + USB_SUBCLASS_AUDIOSTREAMING, + 0x00, + 0x00, + }, +#endif + /* Interface Descriptor */ + { + USB_DESC_LENGTH_INTERFACE, + USB_DESC_TYPE_INTERFACE, + USB_DYNAMIC, + 0x00, + 0x00, + USB_CLASS_AUDIO, + USB_SUBCLASS_AUDIOCONTROL, + 0x00, + 0x00, + }, + /* Header Descriptor */ + { + UAC_DT_AC_HEADER_SIZE(UAC_INTR_NUM), + UAC_CS_INTERFACE, + UAC_HEADER, + 0x0100, /* Version: 1.00 */ + 0x001E, /* Total length: 30 */ + 0x01, /* Total number of interfaces: 1 */ + {0x01}, /* Interface number: 1 */ + }, + /* Input Terminal Descriptor */ + { + UAC_DT_INPUT_TERMINAL_SIZE, + UAC_CS_INTERFACE, + UAC_INPUT_TERMINAL, + 0x01, /* Terminal ID: 1 */ + 0x0201, /* Terminal Type: Microphone (0x0201) */ + 0x00, /* Assoc Terminal: 0 */ + 0x01, /* Number Channels: 1 */ + 0x0000, /* Channel Config: 0x0000 */ + 0x00, /* Channel Names: 0 */ + 0x00, /* Terminal: 0 */ + }, + /* Output Terminal Descriptor */ + { + UAC_DT_OUTPUT_TERMINAL_SIZE, + UAC_CS_INTERFACE, + UAC_OUTPUT_TERMINAL, + 0x02, /* Terminal ID: 2 */ + 0x0101, /* Terminal Type: USB Streaming (0x0101) */ + 0x00, /* Assoc Terminal: 0 */ + 0x01, /* Source ID: 1 */ + 0x00, /* Terminal: 0 */ + }, +#if UAC_USE_FEATURE_UNIT + /* Feature unit Descriptor */ + { + UAC_DT_FEATURE_UNIT_SIZE(UAC_CH_NUM), + UAC_CS_INTERFACE, + UAC_FEATURE_UNIT, + 0x02, + 0x0101, + 0x00, + 0x01, + }, +#endif +}; + +ALIGN(4) +static struct uinterface_descriptor as_desc0 = +{ + USB_DESC_LENGTH_INTERFACE, + USB_DESC_TYPE_INTERFACE, + USB_DYNAMIC, + 0x00, + 0x00, + USB_CLASS_AUDIO, + USB_SUBCLASS_AUDIOSTREAMING, + 0x00, + 0x00, +}; + +ALIGN(4) +static struct uac_as_descriptor as_desc = +{ + /* Interface Descriptor */ + { + USB_DESC_LENGTH_INTERFACE, + USB_DESC_TYPE_INTERFACE, + USB_DYNAMIC, + 0x01, + 0x01, + USB_CLASS_AUDIO, + USB_SUBCLASS_AUDIOSTREAMING, + 0x00, + 0x00, + }, + /* General AS Descriptor */ + { + UAC_DT_AS_HEADER_SIZE, + UAC_CS_INTERFACE, + UAC_AS_GENERAL, + 0x02, /* Terminal ID: 2 */ + 0x01, /* Interface delay in frames: 1 */ + UAC_FORMAT_TYPE_I_PCM, + }, + /* Format type i Descriptor */ + { + UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(UAC_FORMAT_NUM), + UAC_CS_INTERFACE, + UAC_FORMAT_TYPE, + UAC_FORMAT_TYPE_I, + UAC_CHANNEL_NUM, + 2, /* Subframe Size: 2 */ + RESOLUTION_BITS, + 0x01, /* Samples Frequence Type: 1 */ + {0}, /* Samples Frequence */ + }, + /* Endpoint Descriptor */ + { + USB_DESC_LENGTH_ENDPOINT, + USB_DESC_TYPE_ENDPOINT, + USB_DYNAMIC | USB_DIR_IN, + USB_EP_ATTR_ISOC, + UAC_EP_MAX_PACKET_SIZE, + 0x01, + }, + /* AS Endpoint Descriptor */ + { + UAC_ISO_ENDPOINT_DESC_SIZE, + UAC_CS_ENDPOINT, + UAC_MS_GENERAL, + }, +}; + +void mic_entry(void *parameter) +{ + struct rt_audio_caps caps = {0}; + rt_uint32_t e, index; + + mic.buffer = rt_malloc(RECORD_BUFFER_SZ); + if (mic.buffer == RT_NULL) + { + LOG_E("malloc failed"); + goto __exit; + } + + mic.dev = rt_device_find(MIC_DEVICE_NAME); + if (mic.dev == RT_NULL) + { + LOG_E("can't find device:%s", MIC_DEVICE_NAME); + goto __exit; + } + + while (1) + { + if (rt_event_recv(mic.event, EVENT_RECORD_START | EVENT_RECORD_STOP, + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + 1000, &e) != RT_EOK) + { + continue; + } + if (mic.open_count == 0) + { + continue; + } + LOG_D("record start"); + + rt_device_open(mic.dev, RT_DEVICE_OFLAG_RDONLY); + + caps.main_type = AUDIO_TYPE_INPUT; + caps.sub_type = AUDIO_DSP_PARAM; + caps.udata.config.samplerate = RECORD_SAMPLERATE; + caps.udata.config.channels = RECORD_CHANNEL; + caps.udata.config.samplebits = RESOLUTION_BITS; + rt_device_control(mic.dev, AUDIO_CTL_CONFIGURE, &caps); + + while (1) + { + if (rt_event_recv(mic.event, EVENT_RECORD_DATA | EVENT_RECORD_STOP, + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + 1000, &e) != RT_EOK) + { + if (mic.open_count > 0) + continue; + else + break; + } + if (e & EVENT_RECORD_DATA) + { + index = (mic.buffer_index >= RECORD_BUFFER_SZ / 2) ? 0 : (RECORD_BUFFER_SZ / 2); + rt_device_read(mic.dev, 0, mic.buffer + index, RECORD_BUFFER_SZ / 2); + } + else if (e & EVENT_RECORD_STOP) + { + break; + } + } + LOG_D("record stop"); + rt_device_close(mic.dev); + } + +__exit: + if (mic.buffer) + rt_free(mic.buffer); +} + +static rt_err_t _record_start(ufunction_t func) +{ + mic.ep->request.buffer = RT_NULL; + mic.ep->request.size = UAC_EP_MAX_PACKET_SIZE; + mic.ep->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, mic.ep, &mic.ep->request); + + mic.open_count ++; + rt_event_send(mic.event, EVENT_RECORD_START); + return 0; +} + +static rt_err_t _record_stop(ufunction_t func) +{ + mic.open_count --; + rt_event_send(mic.event, EVENT_RECORD_STOP); + return 0; +} + +static rt_err_t _ep_data_in_handler(ufunction_t func, rt_size_t size) +{ + RT_ASSERT(func != RT_NULL); + LOG_D("_ep_data_in_handler"); + + mic.ep->request.buffer = mic.buffer + mic.buffer_index; + mic.ep->request.size = UAC_EP_MAX_PACKET_SIZE; + mic.ep->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, mic.ep, &mic.ep->request); + + mic.buffer_index += UAC_EP_MAX_PACKET_SIZE; + if (mic.buffer_index >= RECORD_BUFFER_SZ) + { + mic.buffer_index = 0; + rt_event_send(mic.event, EVENT_RECORD_DATA); + } + else if (mic.buffer_index == RECORD_BUFFER_SZ / 2) + { + rt_event_send(mic.event, EVENT_RECORD_DATA); + } + + return RT_EOK; +} + +static rt_err_t _interface_as_handler(ufunction_t func, ureq_t setup) +{ + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + RT_ASSERT(setup != RT_NULL); + + LOG_D("_interface_as_handler"); + + if ((setup->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) + { + switch (setup->bRequest) + { + case USB_REQ_GET_INTERFACE: + break; + case USB_REQ_SET_INTERFACE: + LOG_D("set interface handler"); + if (setup->wValue == 1) + { + _record_start(func); + } + else if (setup->wValue == 0) + { + _record_stop(func); + } + break; + default: + LOG_D("unknown uac request 0x%x", setup->bRequest); + return -RT_ERROR; + } + } + + return RT_EOK; +} + +static rt_err_t _function_enable(ufunction_t func) +{ + RT_ASSERT(func != RT_NULL); + + LOG_D("uac function enable"); + + return RT_EOK; +} + +static rt_err_t _function_disable(ufunction_t func) +{ + RT_ASSERT(func != RT_NULL); + + LOG_D("uac function disable"); + _record_stop(func); + return RT_EOK; +} + +static struct ufunction_ops ops = +{ + _function_enable, + _function_disable, + RT_NULL, +}; +/** + * This function will configure uac descriptor. + * + * @param comm the communication interface number. + * @param data the data interface number. + * + * @return RT_EOK on successful. + */ +static rt_err_t _uac_descriptor_config(struct uac_ac_descriptor *ac, + rt_uint8_t cintf_nr, struct uac_as_descriptor *as, rt_uint8_t sintf_nr) +{ + ac->hdr_desc.baInterfaceNr[0] = sintf_nr; +#ifdef RT_USB_DEVICE_COMPOSITE + ac->iad_desc.bFirstInterface = cintf_nr; +#endif + + return RT_EOK; +} + +static rt_err_t _uac_samplerate_config(struct uac_as_descriptor *as, rt_uint32_t samplerate) +{ + as->format_type_desc.tSamFreq[0][2] = samplerate >> 16 & 0xff; + as->format_type_desc.tSamFreq[0][1] = samplerate >> 8 & 0xff; + as->format_type_desc.tSamFreq[0][0] = samplerate & 0xff; + return RT_EOK; +} + +/** + * This function will create a uac function instance. + * + * @param device the usb device object. + * + * @return RT_EOK on successful. + */ +ufunction_t rt_usbd_function_uac_mic_create(udevice_t device) +{ + ufunction_t func; + uintf_t intf_ac, intf_as; + ualtsetting_t setting_as0; + ualtsetting_t setting_ac, setting_as; + struct uac_as_descriptor *as_desc_t; + + /* parameter check */ + RT_ASSERT(device != RT_NULL); + + /* set usb device string description */ + rt_usbd_device_set_string(device, _ustring); + + /* create a uac function */ + func = rt_usbd_function_new(device, &dev_desc, &ops); + //not support HS + //rt_usbd_device_set_qualifier(device, &dev_qualifier); + + /* create interface */ + intf_ac = rt_usbd_interface_new(device, RT_NULL); + intf_as = rt_usbd_interface_new(device, _interface_as_handler); + + /* create alternate setting */ + setting_ac = rt_usbd_altsetting_new(sizeof(struct uac_ac_descriptor)); + setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor)); + setting_as = rt_usbd_altsetting_new(sizeof(struct uac_as_descriptor)); + /* config desc in alternate setting */ + rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc, + (rt_off_t) & ((struct uac_ac_descriptor *)0)->intf_desc); + rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0); + rt_usbd_altsetting_config_descriptor(setting_as, &as_desc, + (rt_off_t) & ((struct uac_as_descriptor *)0)->intf_desc); + /* configure the uac interface descriptor */ + _uac_descriptor_config(setting_ac->desc, intf_ac->intf_num, setting_as->desc, intf_as->intf_num); + _uac_samplerate_config(setting_as->desc, RECORD_SAMPLERATE); + + /* create endpoint */ + as_desc_t = (struct uac_as_descriptor *)setting_as->desc; + mic.ep = rt_usbd_endpoint_new(&as_desc_t->ep_desc, _ep_data_in_handler); + + /* add the endpoint to the alternate setting */ + rt_usbd_altsetting_add_endpoint(setting_as, mic.ep); + + /* add the alternate setting to the interface, then set default setting of the interface */ + rt_usbd_interface_add_altsetting(intf_ac, setting_ac); + rt_usbd_set_altsetting(intf_ac, 0); + rt_usbd_interface_add_altsetting(intf_as, setting_as0); + rt_usbd_interface_add_altsetting(intf_as, setting_as); + rt_usbd_set_altsetting(intf_as, 0); + + /* add the interface to the uac function */ + rt_usbd_function_add_interface(func, intf_ac); + rt_usbd_function_add_interface(func, intf_as); + + return func; +} + +int audio_mic_init(void) +{ + rt_thread_t mic_tid; + mic.event = rt_event_create("mic_event", RT_IPC_FLAG_FIFO); + + mic_tid = rt_thread_create("mic_thread", + mic_entry, RT_NULL, + 1024, + 5, 10); + + if (mic_tid != RT_NULL) + rt_thread_startup(mic_tid); + return RT_EOK; +} +INIT_COMPONENT_EXPORT(audio_mic_init); + +/* + * register uac class + */ +struct udclass uac_class = +{ + .rt_usbd_function_create = rt_usbd_function_uac_mic_create +}; + +int rt_usbd_uac_mic_class_register(void) +{ + rt_usbd_class_register(&uac_class); + return 0; +} +INIT_PREV_EXPORT(rt_usbd_uac_mic_class_register); diff --git a/components/drivers/usb/usbdevice/class/audio_speaker.c b/components/drivers/usb/usbdevice/class/audio_speaker.c new file mode 100644 index 0000000000..84c36d2053 --- /dev/null +++ b/components/drivers/usb/usbdevice/class/audio_speaker.c @@ -0,0 +1,578 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-09-19 flybreak the first version + */ + +#include <rthw.h> +#include <rtthread.h> +#include <rtservice.h> +#include <rtdevice.h> + +#include "drivers/usb_device.h" +#include "audio.h" + +#define DBG_TAG "usbd.audio.speaker" +#define DBG_LVL DBG_INFO +#include <rtdbg.h> + +#define AUDIO_SAMPLERATE 16000 +#define AUDIO_CHANNEL 1 +#define RESOLUTION_BITS 16 + +#define RESOLUTION_BYTE (RESOLUTION_BITS / 8) +#define AUDIO_PER_MS_SZ ((AUDIO_SAMPLERATE * AUDIO_CHANNEL * RESOLUTION_BYTE) / 1000) +#define AUDIO_BUFFER_SZ (AUDIO_PER_MS_SZ * 20) /* 20ms */ + +#if defined(RT_USBD_SPEAKER_DEVICE_NAME) + #define SPEAKER_DEVICE_NAME RT_USBD_SPEAKER_DEVICE_NAME +#else + #define SPEAKER_DEVICE_NAME "sound0" +#endif + +#define EVENT_AUDIO_START (1 << 0) +#define EVENT_AUDIO_STOP (1 << 1) +#define EVENT_AUDIO_DATA (1 << 2) + +/* + * uac speaker descriptor define + */ + +#define UAC_CS_INTERFACE 0x24 +#define UAC_CS_ENDPOINT 0x25 + +#define UAC_MAX_PACKET_SIZE 64 +#define UAC_EP_MAX_PACKET_SIZE 32 +#define UAC_CHANNEL_NUM AUDIO_CHANNEL +#define UAC_INTR_NUM 1 +#define UAC_CH_NUM 1 +#define UAC_FORMAT_NUM 1 + +struct uac_ac_descriptor +{ +#ifdef RT_USB_DEVICE_COMPOSITE + struct uiad_descriptor iad_desc; +#endif + struct uinterface_descriptor intf_desc; + DECLARE_UAC_AC_HEADER_DESCRIPTOR(UAC_INTR_NUM) hdr_desc; + struct uac_input_terminal_descriptor it_desc; + struct uac1_output_terminal_descriptor ot_desc; +#if UAC_USE_FEATURE_UNIT + DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(UAC_CH_NUM) feature_unit_desc; +#endif +}; + +struct uac_as_descriptor +{ + struct uinterface_descriptor intf_desc; + struct uac1_as_header_descriptor hdr_desc; + DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(UAC_FORMAT_NUM) format_type_desc; + struct uendpoint_descriptor ep_desc; + struct uac_iso_endpoint_descriptor as_ep_desc; +}; + +/* + * uac speaker device type + */ + +struct uac_audio_speaker +{ + rt_device_t dev; + rt_event_t event; + rt_uint8_t open_count; + + rt_uint8_t *buffer; + rt_uint32_t buffer_index; + + uep_t ep; +}; +static struct uac_audio_speaker speaker; + +ALIGN(4) +static struct udevice_descriptor dev_desc = +{ + USB_DESC_LENGTH_DEVICE, //bLength; + USB_DESC_TYPE_DEVICE, //type; + USB_BCD_VERSION, //bcdUSB; + USB_CLASS_DEVICE, //bDeviceClass; + 0x00, //bDeviceSubClass; + 0x00, //bDeviceProtocol; + UAC_MAX_PACKET_SIZE, //bMaxPacketSize0; + _VENDOR_ID, //idVendor; + _PRODUCT_ID, //idProduct; + USB_BCD_DEVICE, //bcdDevice; + USB_STRING_MANU_INDEX, //iManufacturer; + USB_STRING_PRODUCT_INDEX, //iProduct; + USB_STRING_SERIAL_INDEX, //iSerialNumber;Unused. + USB_DYNAMIC, //bNumConfigurations; +}; + +//FS and HS needed +ALIGN(4) +static struct usb_qualifier_descriptor dev_qualifier = +{ + sizeof(dev_qualifier), //bLength + USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType + 0x0200, //bcdUSB + USB_CLASS_AUDIO, //bDeviceClass + 0x00, //bDeviceSubClass + 0x00, //bDeviceProtocol + 64, //bMaxPacketSize0 + 0x01, //bNumConfigurations + 0, +}; + +ALIGN(4) +const static char *_ustring[] = +{ + "Language", + "RT-Thread Team.", + "RT-Thread Speaker", + "32021919830108", + "Configuration", + "Interface", +}; + +ALIGN(4) +static struct uac_ac_descriptor ac_desc = +{ +#ifdef RT_USB_DEVICE_COMPOSITE + /* Interface Association Descriptor */ + { + USB_DESC_LENGTH_IAD, + USB_DESC_TYPE_IAD, + USB_DYNAMIC, + 0x02, + USB_CLASS_AUDIO, + USB_SUBCLASS_AUDIOSTREAMING, + 0x00, + 0x00, + }, +#endif + /* Interface Descriptor */ + { + USB_DESC_LENGTH_INTERFACE, + USB_DESC_TYPE_INTERFACE, + USB_DYNAMIC, + 0x00, + 0x00, + USB_CLASS_AUDIO, + USB_SUBCLASS_AUDIOCONTROL, + 0x00, + 0x00, + }, + /* Header Descriptor */ + { + UAC_DT_AC_HEADER_SIZE(UAC_INTR_NUM), + UAC_CS_INTERFACE, + UAC_HEADER, + 0x0100, /* Version: 1.00 */ + 0x0027, /* Total length: 39 */ + 0x01, /* Total number of interfaces: 1 */ + {0x01}, /* Interface number: 1 */ + }, + /* Input Terminal Descriptor */ + { + UAC_DT_INPUT_TERMINAL_SIZE, + UAC_CS_INTERFACE, + UAC_INPUT_TERMINAL, + 0x01, /* Terminal ID: 1 */ + 0x0101, /* Terminal Type: USB Streaming (0x0101) */ + 0x00, /* Assoc Terminal: 0 */ + 0x01, /* Number Channels: 1 */ + 0x0000, /* Channel Config: 0x0000 */ + 0x00, /* Channel Names: 0 */ + 0x00, /* Terminal: 0 */ + }, + /* Output Terminal Descriptor */ + { + UAC_DT_OUTPUT_TERMINAL_SIZE, + UAC_CS_INTERFACE, + UAC_OUTPUT_TERMINAL, + 0x02, /* Terminal ID: 2 */ + 0x0302, /* Terminal Type: Headphones (0x0302) */ + 0x00, /* Assoc Terminal: 0 */ + 0x01, /* Source ID: 1 */ + 0x00, /* Terminal: 0 */ + }, +#if UAC_USE_FEATURE_UNIT + /* Feature unit Descriptor */ + { + UAC_DT_FEATURE_UNIT_SIZE(UAC_CH_NUM), + UAC_CS_INTERFACE, + UAC_FEATURE_UNIT, + 0x02, + 0x0101, + 0x00, + 0x01, + }, +#endif +}; + +ALIGN(4) +static struct uinterface_descriptor as_desc0 = +{ + USB_DESC_LENGTH_INTERFACE, + USB_DESC_TYPE_INTERFACE, + USB_DYNAMIC, + 0x00, + 0x00, + USB_CLASS_AUDIO, + USB_SUBCLASS_AUDIOSTREAMING, + 0x00, + 0x00, +}; + +ALIGN(4) +static struct uac_as_descriptor as_desc = +{ + /* Interface Descriptor */ + { + USB_DESC_LENGTH_INTERFACE, + USB_DESC_TYPE_INTERFACE, + USB_DYNAMIC, + 0x01, + 0x01, + USB_CLASS_AUDIO, + USB_SUBCLASS_AUDIOSTREAMING, + 0x00, + 0x00, + }, + /* General AS Descriptor */ + { + UAC_DT_AS_HEADER_SIZE, + UAC_CS_INTERFACE, + UAC_AS_GENERAL, + 0x01, /* Terminal ID: 1 */ + 0x01, /* Interface delay in frames: 1 */ + UAC_FORMAT_TYPE_I_PCM, + }, + /* Format type i Descriptor */ + { + UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(UAC_FORMAT_NUM), + UAC_CS_INTERFACE, + UAC_FORMAT_TYPE, + UAC_FORMAT_TYPE_I, + UAC_CHANNEL_NUM, + 2, /* Subframe Size: 2 */ + RESOLUTION_BITS, + 0x01, /* Samples Frequence Type: 1 */ + {0}, /* Samples Frequence */ + }, + /* Endpoint Descriptor */ + { + USB_DESC_LENGTH_ENDPOINT, + USB_DESC_TYPE_ENDPOINT, + USB_DYNAMIC | USB_DIR_OUT, + USB_EP_ATTR_ISOC, + UAC_EP_MAX_PACKET_SIZE, + 0x01, + }, + /* AS Endpoint Descriptor */ + { + UAC_ISO_ENDPOINT_DESC_SIZE, + UAC_CS_ENDPOINT, + UAC_MS_GENERAL, + }, +}; + +void speaker_entry(void *parameter) +{ + struct rt_audio_caps caps = {0}; + rt_uint32_t e, index; + + speaker.buffer = rt_malloc(AUDIO_BUFFER_SZ); + if (speaker.buffer == RT_NULL) + { + LOG_E("malloc failed"); + goto __exit; + } + + speaker.dev = rt_device_find(SPEAKER_DEVICE_NAME); + if (speaker.dev == RT_NULL) + { + LOG_E("can't find device:%s", SPEAKER_DEVICE_NAME); + goto __exit; + } + + while (1) + { + if (rt_event_recv(speaker.event, EVENT_AUDIO_START | EVENT_AUDIO_STOP, + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + 1000, &e) != RT_EOK) + { + continue; + } + if (speaker.open_count == 0) + { + continue; + } + LOG_D("play start"); + + rt_device_open(speaker.dev, RT_DEVICE_OFLAG_WRONLY); + + caps.main_type = AUDIO_TYPE_OUTPUT; + caps.sub_type = AUDIO_DSP_PARAM; + caps.udata.config.samplerate = AUDIO_SAMPLERATE; + caps.udata.config.channels = AUDIO_CHANNEL; + caps.udata.config.samplebits = RESOLUTION_BITS; + rt_device_control(speaker.dev, AUDIO_CTL_CONFIGURE, &caps); + + while (1) + { + if (rt_event_recv(speaker.event, EVENT_AUDIO_DATA | EVENT_AUDIO_STOP, + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + 1000, &e) != RT_EOK) + { + if (speaker.open_count > 0) + continue; + else + break; + } + if (e & EVENT_AUDIO_DATA) + { + index = (speaker.buffer_index >= AUDIO_BUFFER_SZ / 2) ? 0 : (AUDIO_BUFFER_SZ / 2); + rt_device_write(speaker.dev, 0, speaker.buffer + index, AUDIO_BUFFER_SZ / 2); + } + else if (e & EVENT_AUDIO_STOP) + { + break; + } + } + LOG_D("play stop"); + rt_device_close(speaker.dev); + } + +__exit: + if (speaker.buffer) + rt_free(speaker.buffer); +} + +static rt_err_t _audio_start(ufunction_t func) +{ + speaker.ep->request.buffer = speaker.buffer; + speaker.ep->request.size = UAC_EP_MAX_PACKET_SIZE; + speaker.ep->request.req_type = UIO_REQUEST_READ_FULL; + rt_usbd_io_request(func->device, speaker.ep, &speaker.ep->request); + + speaker.open_count ++; + rt_event_send(speaker.event, EVENT_AUDIO_START); + + return 0; +} + +static rt_err_t _audio_stop(ufunction_t func) +{ + speaker.open_count --; + rt_event_send(speaker.event, EVENT_AUDIO_STOP); + return 0; +} + +static rt_err_t _ep_data_handler(ufunction_t func, rt_size_t size) +{ + RT_ASSERT(func != RT_NULL); + LOG_D("_ep_data_handler"); + + speaker.ep->request.buffer = speaker.buffer + speaker.buffer_index; + speaker.ep->request.size = UAC_EP_MAX_PACKET_SIZE; + speaker.ep->request.req_type = UIO_REQUEST_READ_FULL; + rt_usbd_io_request(func->device, speaker.ep, &speaker.ep->request); + + speaker.buffer_index += UAC_EP_MAX_PACKET_SIZE; + if (speaker.buffer_index >= AUDIO_BUFFER_SZ) + { + speaker.buffer_index = 0; + rt_event_send(speaker.event, EVENT_AUDIO_DATA); + } + else if (speaker.buffer_index == AUDIO_BUFFER_SZ / 2) + { + rt_event_send(speaker.event, EVENT_AUDIO_DATA); + } + + return RT_EOK; +} + +static rt_err_t _interface_as_handler(ufunction_t func, ureq_t setup) +{ + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + RT_ASSERT(setup != RT_NULL); + + LOG_D("_interface_as_handler"); + + if ((setup->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) + { + switch (setup->bRequest) + { + case USB_REQ_GET_INTERFACE: + break; + case USB_REQ_SET_INTERFACE: + LOG_D("set interface handler"); + if (setup->wValue == 1) + { + _audio_start(func); + } + else if (setup->wValue == 0) + { + _audio_stop(func); + } + break; + default: + LOG_D("unknown uac request 0x%x", setup->bRequest); + return -RT_ERROR; + } + } + + return RT_EOK; +} + +static rt_err_t _function_enable(ufunction_t func) +{ + RT_ASSERT(func != RT_NULL); + + LOG_D("uac function enable"); + + return RT_EOK; +} + +static rt_err_t _function_disable(ufunction_t func) +{ + RT_ASSERT(func != RT_NULL); + + LOG_D("uac function disable"); + _audio_stop(func); + return RT_EOK; +} + +static struct ufunction_ops ops = +{ + _function_enable, + _function_disable, + RT_NULL, +}; +/** + * This function will configure uac descriptor. + * + * @param comm the communication interface number. + * @param data the data interface number. + * + * @return RT_EOK on successful. + */ +static rt_err_t _uac_descriptor_config(struct uac_ac_descriptor *ac, + rt_uint8_t cintf_nr, struct uac_as_descriptor *as, rt_uint8_t sintf_nr) +{ + ac->hdr_desc.baInterfaceNr[0] = sintf_nr; +#ifdef RT_USB_DEVICE_COMPOSITE + ac->iad_desc.bFirstInterface = cintf_nr; +#endif + + return RT_EOK; +} + +static rt_err_t _uac_samplerate_config(struct uac_as_descriptor *as, rt_uint32_t samplerate) +{ + as->format_type_desc.tSamFreq[0][2] = samplerate >> 16 & 0xff; + as->format_type_desc.tSamFreq[0][1] = samplerate >> 8 & 0xff; + as->format_type_desc.tSamFreq[0][0] = samplerate & 0xff; + return RT_EOK; +} + +/** + * This function will create a uac function instance. + * + * @param device the usb device object. + * + * @return RT_EOK on successful. + */ +ufunction_t rt_usbd_function_uac_speaker_create(udevice_t device) +{ + ufunction_t func; + uintf_t intf_ac, intf_as; + ualtsetting_t setting_as0; + ualtsetting_t setting_ac, setting_as; + struct uac_as_descriptor *as_desc_t; + + /* parameter check */ + RT_ASSERT(device != RT_NULL); + + /* set usb device string description */ + rt_usbd_device_set_string(device, _ustring); + + /* create a uac function */ + func = rt_usbd_function_new(device, &dev_desc, &ops); + //not support HS + //rt_usbd_device_set_qualifier(device, &dev_qualifier); + + /* create interface */ + intf_ac = rt_usbd_interface_new(device, RT_NULL); + intf_as = rt_usbd_interface_new(device, _interface_as_handler); + + /* create alternate setting */ + setting_ac = rt_usbd_altsetting_new(sizeof(struct uac_ac_descriptor)); + setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor)); + setting_as = rt_usbd_altsetting_new(sizeof(struct uac_as_descriptor)); + /* config desc in alternate setting */ + rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc, + (rt_off_t) & ((struct uac_ac_descriptor *)0)->intf_desc); + rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0); + rt_usbd_altsetting_config_descriptor(setting_as, &as_desc, + (rt_off_t) & ((struct uac_as_descriptor *)0)->intf_desc); + /* configure the uac interface descriptor */ + _uac_descriptor_config(setting_ac->desc, intf_ac->intf_num, setting_as->desc, intf_as->intf_num); + _uac_samplerate_config(setting_as->desc, AUDIO_SAMPLERATE); + + /* create endpoint */ + as_desc_t = (struct uac_as_descriptor *)setting_as->desc; + speaker.ep = rt_usbd_endpoint_new(&as_desc_t->ep_desc, _ep_data_handler); + + /* add the endpoint to the alternate setting */ + rt_usbd_altsetting_add_endpoint(setting_as, speaker.ep); + + /* add the alternate setting to the interface, then set default setting of the interface */ + rt_usbd_interface_add_altsetting(intf_ac, setting_ac); + rt_usbd_set_altsetting(intf_ac, 0); + rt_usbd_interface_add_altsetting(intf_as, setting_as0); + rt_usbd_interface_add_altsetting(intf_as, setting_as); + rt_usbd_set_altsetting(intf_as, 0); + + /* add the interface to the uac function */ + rt_usbd_function_add_interface(func, intf_ac); + rt_usbd_function_add_interface(func, intf_as); + + return func; +} + +int audio_speaker_init(void) +{ + rt_thread_t speaker_tid; + speaker.event = rt_event_create("speaker_event", RT_IPC_FLAG_FIFO); + + speaker_tid = rt_thread_create("speaker_thread", + speaker_entry, RT_NULL, + 1024, + 5, 10); + + if (speaker_tid != RT_NULL) + rt_thread_startup(speaker_tid); + return RT_EOK; +} +INIT_COMPONENT_EXPORT(audio_speaker_init); + +/* + * register uac class + */ +static struct udclass uac_speaker_class = +{ + .rt_usbd_function_create = rt_usbd_function_uac_speaker_create +}; + +int rt_usbd_uac_speaker_class_register(void) +{ + rt_usbd_class_register(&uac_speaker_class); + return 0; +} +INIT_PREV_EXPORT(rt_usbd_uac_speaker_class_register); diff --git a/components/drivers/usb/usbdevice/class/rndis.c b/components/drivers/usb/usbdevice/class/rndis.c index ec61234947..93e0ba6ae2 100644 --- a/components/drivers/usb/usbdevice/class/rndis.c +++ b/components/drivers/usb/usbdevice/class/rndis.c @@ -421,7 +421,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg) case OID_GEN_LINK_SPEED: resp = _create_resp(4); if(resp == RT_NULL) break; - _set_resp(resp, func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000) / 100); + _set_resp(resp, (func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000)) / 100); break; case OID_GEN_MEDIA_CONNECT_STATUS: diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/core.c index ae0704585f..584556303f 100644 --- a/components/drivers/usb/usbdevice/core/core.c +++ b/components/drivers/usb/usbdevice/core/core.c @@ -237,7 +237,8 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup) { rt_uint8_t value; uintf_t intf; - + ufunction_t func; + /* parameter check */ RT_ASSERT(device != RT_NULL); RT_ASSERT(setup != RT_NULL); @@ -251,12 +252,17 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup) } /* find the specified interface and its alternate setting */ - intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, RT_NULL); + intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func); value = intf->curr_setting->intf_desc->bAlternateSetting; /* send the interface alternate setting to endpoint 0*/ rt_usbd_ep0_write(device, &value, 1); + if (intf->handler) + { + intf->handler(func, setup); + } + return RT_EOK; } @@ -270,6 +276,7 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup) */ static rt_err_t _set_interface(struct udevice* device, ureq_t setup) { + ufunction_t func; uintf_t intf; uep_t ep; struct rt_list_node* i; @@ -288,7 +295,7 @@ static rt_err_t _set_interface(struct udevice* device, ureq_t setup) } /* find the specified interface */ - intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, RT_NULL); + intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func); /* set alternate setting to the interface */ rt_usbd_set_altsetting(intf, setup->wValue & 0xFF); @@ -303,6 +310,11 @@ static rt_err_t _set_interface(struct udevice* device, ureq_t setup) } dcd_ep0_send_status(device->dcd); + if (intf->handler) + { + intf->handler(func, setup); + } + return RT_EOK; } @@ -1488,9 +1500,10 @@ uep_t rt_usbd_find_endpoint(udevice_t device, ufunction_t* pfunc, rt_uint8_t ep_ */ rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg) { - struct rt_list_node *i, *j, *k; + struct rt_list_node *i, *j, *k, *m; ufunction_t func; uintf_t intf; + ualtsetting_t altsetting; uep_t ep; RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbd_device_add_config\n")); @@ -1512,22 +1525,26 @@ rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg) intf = (uintf_t)rt_list_entry(j, struct uinterface, list); cfg->cfg_desc.bNumInterfaces++; - /* allocate address for every endpoint in the interface alternate setting */ - for(k=intf->curr_setting->ep_list.next; - k!=&intf->curr_setting->ep_list; k=k->next) + for(k=intf->setting_list.next; k!=&intf->setting_list;k=k->next) { - ep = (uep_t)rt_list_entry(k, struct uendpoint, list); - if(rt_usbd_ep_assign(device, ep) != RT_EOK) + altsetting = (ualtsetting_t)rt_list_entry(k, struct ualtsetting, list); + + /* allocate address for every endpoint in the interface alternate setting */ + for(m=altsetting->ep_list.next; m!=&altsetting->ep_list; m=m->next) { - rt_kprintf("endpoint assign error\n"); + ep = (uep_t)rt_list_entry(m, struct uendpoint, list); + if(rt_usbd_ep_assign(device, ep) != RT_EOK) + { + rt_kprintf("endpoint assign error\n"); + } } - } - /* construct complete configuration descriptor */ - rt_memcpy((void*)&cfg->cfg_desc.data[cfg->cfg_desc.wTotalLength - USB_DESC_LENGTH_CONFIG], - (void*)intf->curr_setting->desc, - intf->curr_setting->desc_size); - cfg->cfg_desc.wTotalLength += intf->curr_setting->desc_size; + /* construct complete configuration descriptor */ + rt_memcpy((void*)&cfg->cfg_desc.data[cfg->cfg_desc.wTotalLength - USB_DESC_LENGTH_CONFIG], + (void*)altsetting->desc, + altsetting->desc_size); + cfg->cfg_desc.wTotalLength += altsetting->desc_size; + } } } diff --git a/components/drivers/wlan/wlan_lwip.c b/components/drivers/wlan/wlan_lwip.c index 797dd823fb..3c4e4dd598 100644 --- a/components/drivers/wlan/wlan_lwip.c +++ b/components/drivers/wlan/wlan_lwip.c @@ -181,14 +181,10 @@ static void netif_set_connected(void *parameter) netifapi_netif_common(eth_dev->netif, netif_set_link_up, NULL); #ifdef LWIP_USING_DHCPD { - char netif_name[8]; - int i; + char netif_name[RT_NAME_MAX]; rt_memset(netif_name, 0, sizeof(netif_name)); - for (i = 0; i < sizeof(eth_dev->netif->name); i++) - { - netif_name[i] = eth_dev->netif->name[i]; - } + rt_memcpy(netif_name, eth_dev->netif->name, sizeof(eth_dev->netif->name)); dhcpd_start(netif_name); } #endif @@ -196,24 +192,24 @@ static void netif_set_connected(void *parameter) } else { - if (wlan->mode == RT_WLAN_STATION) - { - LOG_D("F:%s L:%d dhcp stop run", __FUNCTION__, __LINE__); - netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL); + LOG_D("F:%s L:%d set linkdown", __FUNCTION__, __LINE__); + netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL); + rt_timer_stop(&lwip_prot->timer); #ifdef RT_LWIP_DHCP - { - ip_addr_t ip_addr = { 0 }; - dhcp_stop(eth_dev->netif); - netif_set_addr(eth_dev->netif, &ip_addr, &ip_addr, &ip_addr); - } -#endif - rt_timer_stop(&lwip_prot->timer); + { + ip_addr_t ip_addr = { 0 }; + dhcp_stop(eth_dev->netif); + netif_set_addr(eth_dev->netif, &ip_addr, &ip_addr, &ip_addr); } - else if (wlan->mode == RT_WLAN_AP) +#endif +#ifdef LWIP_USING_DHCPD { - LOG_D("F:%s L:%d dhcpd stop run", __FUNCTION__, __LINE__); - netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL); + char netif_name[RT_NAME_MAX]; + rt_memset(netif_name, 0, sizeof(netif_name)); + rt_memcpy(netif_name, lwip_prot->eth.netif->name, sizeof(lwip_prot->eth.netif->name)); + dhcpd_stop(netif_name); } +#endif } } @@ -421,7 +417,7 @@ const static struct rt_device_ops wlan_lwip_ops = static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan) { struct eth_device *eth = RT_NULL; - static rt_uint8_t id = 0; + rt_uint8_t id = 0; char eth_name[4], timer_name[16]; rt_device_t device = RT_NULL; struct lwip_prot_des *lwip_prot; @@ -501,8 +497,30 @@ static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot * static void rt_wlan_lwip_protocol_unregister(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan) { - /*TODO*/ + struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)prot; + LOG_D("F:%s L:%d is run wlan:0x%08x", __FUNCTION__, __LINE__, wlan); +#if !defined(RT_USING_LWIP141) + wlan->prot = RT_NULL; + if (lwip_prot == RT_NULL) + { + return; + } + +#ifdef LWIP_USING_DHCPD + { + char netif_name[RT_NAME_MAX]; + rt_memset(netif_name, 0, sizeof(netif_name)); + rt_memcpy(netif_name, lwip_prot->eth.netif->name, sizeof(lwip_prot->eth.netif->name)); + dhcpd_stop(netif_name); + } +#endif + eth_device_deinit(&lwip_prot->eth); + rt_device_close((rt_device_t)wlan); + rt_timer_detach(&lwip_prot->timer); + wlan->netdev = RT_NULL; + rt_free(lwip_prot); +#endif } static struct rt_wlan_prot_ops ops = diff --git a/components/drivers/wlan/wlan_mgnt.c b/components/drivers/wlan/wlan_mgnt.c index e0ee67e06c..cf2204c6b3 100644 --- a/components/drivers/wlan/wlan_mgnt.c +++ b/components/drivers/wlan/wlan_mgnt.c @@ -260,7 +260,8 @@ static rt_err_t rt_wlan_send_to_thread(rt_wlan_event_t event, void *buff, int le msg->event = event; if (len != 0) { - msg->buff = ((char *)msg) + sizeof(struct rt_wlan_msg); + msg->buff = (void *)&msg[1]; + rt_memcpy(msg->buff, buff, len); msg->len = len; } diff --git a/components/finsh/SConscript b/components/finsh/SConscript index e1e2b3bbdb..be04c56616 100644 --- a/components/finsh/SConscript +++ b/components/finsh/SConscript @@ -4,7 +4,6 @@ from building import * cwd = GetCurrentDir() src = Split(''' shell.c -symbol.c cmd.c ''') @@ -21,19 +20,20 @@ finsh_vm.c finsh_token.c ''') -msh_src = Split(''' -msh.c -msh_cmd.c -msh_file.c -''') +msh_src = Glob('msh.c') -CPPPATH = [cwd] +if GetDepend('RT_USING_DFS'): + msh_src += ['msh_file.c'] +if not GetDepend('FINSH_USING_SYMTAB'): + src += ['symbol.c'] if GetDepend('FINSH_USING_MSH'): src = src + msh_src if not GetDepend('FINSH_USING_MSH_ONLY'): src = src + fsh_src +CPPPATH = [cwd] + group = DefineGroup('finsh', src, depend = ['RT_USING_FINSH'], CPPPATH = CPPPATH) Return('group') diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c index 608e962f6c..48a629961b 100644 --- a/components/finsh/cmd.c +++ b/components/finsh/cmd.c @@ -675,6 +675,8 @@ long list_mempool(void) { struct rt_object *obj; struct rt_mempool *mp; + int suspend_thread_count; + rt_list_t *node; obj = rt_list_entry(obj_list[i], struct rt_object, list); level = rt_hw_interrupt_disable(); @@ -687,7 +689,14 @@ long list_mempool(void) rt_hw_interrupt_enable(level); mp = (struct rt_mempool *)obj; - if (mp->suspend_thread_count > 0) + + suspend_thread_count = 0; + rt_list_for_each(node, &mp->suspend_thread) + { + suspend_thread_count++; + } + + if (suspend_thread_count > 0) { rt_kprintf("%-*.*s %04d %04d %04d %d:", maxlen, RT_NAME_MAX, @@ -695,7 +704,7 @@ long list_mempool(void) mp->block_size, mp->block_total_count, mp->block_free_count, - mp->suspend_thread_count); + suspend_thread_count); show_wait_queue(&(mp->suspend_thread)); rt_kprintf("\n"); } @@ -707,7 +716,7 @@ long list_mempool(void) mp->block_size, mp->block_total_count, mp->block_free_count, - mp->suspend_thread_count); + suspend_thread_count); } } } @@ -878,7 +887,7 @@ long list(void) /* skip the internal command */ if (strncmp((char *)index->name, "__", 2) == 0) continue; -#ifdef FINSH_USING_DESCRIPTION +#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB) rt_kprintf("%-16s -- %s\n", index->name, index->desc); #else rt_kprintf("%s\n", index->name); diff --git a/components/finsh/msh.c b/components/finsh/msh.c index fd1ee1198d..79f1e3c87f 100644 --- a/components/finsh/msh.c +++ b/components/finsh/msh.c @@ -89,6 +89,37 @@ int msh_help(int argc, char **argv) } FINSH_FUNCTION_EXPORT_ALIAS(msh_help, __cmd_help, RT-Thread shell help.); +int cmd_ps(int argc, char **argv) +{ + extern long list_thread(void); + extern int list_module(void); + +#ifdef RT_USING_MODULE + if ((argc == 2) && (strcmp(argv[1], "-m") == 0)) + list_module(); + else +#endif + list_thread(); + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_ps, __cmd_ps, List threads in the system.); + +#ifdef RT_USING_HEAP +int cmd_free(int argc, char **argv) +{ + extern void list_mem(void); + extern void list_memheap(void); + +#ifdef RT_USING_MEMHEAP_AS_HEAP + list_memheap(); +#else + list_mem(); +#endif + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_free, __cmd_free, Show the memory usage in the system.); +#endif + static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX]) { char *ptr; diff --git a/components/finsh/msh_cmd.c b/components/finsh/msh_cmd.c deleted file mode 100644 index 4a9c67fa75..0000000000 --- a/components/finsh/msh_cmd.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-03-30 Bernard the first verion for FinSH - * 2015-08-28 Bernard Add mkfs command. - */ - -#include <rtthread.h> - -#ifdef FINSH_USING_MSH - -#include <finsh.h> -#include "msh.h" - -#ifdef RT_USING_DFS -#include <dfs_posix.h> - -#ifdef DFS_USING_WORKDIR -extern char working_directory[]; -#endif - -int cmd_ls(int argc, char **argv) -{ - extern void ls(const char *pathname); - - if (argc == 1) - { -#ifdef DFS_USING_WORKDIR - ls(working_directory); -#else - ls("/"); -#endif - } - else - { - ls(argv[1]); - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_ls, __cmd_ls, List information about the FILEs.); - -int cmd_cp(int argc, char **argv) -{ - void copy(const char *src, const char *dst); - - if (argc != 3) - { - rt_kprintf("Usage: cp SOURCE DEST\n"); - rt_kprintf("Copy SOURCE to DEST.\n"); - } - else - { - copy(argv[1], argv[2]); - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_cp, __cmd_cp, Copy SOURCE to DEST.); - -int cmd_mv(int argc, char **argv) -{ - if (argc != 3) - { - rt_kprintf("Usage: mv SOURCE DEST\n"); - rt_kprintf("Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n"); - } - else - { - int fd; - char *dest = RT_NULL; - - rt_kprintf("%s => %s\n", argv[1], argv[2]); - - fd = open(argv[2], O_DIRECTORY, 0); - if (fd >= 0) - { - char *src; - - close(fd); - - /* it's a directory */ - dest = (char *)rt_malloc(DFS_PATH_MAX); - if (dest == RT_NULL) - { - rt_kprintf("out of memory\n"); - return -RT_ENOMEM; - } - - src = argv[1] + rt_strlen(argv[1]); - while (src != argv[1]) - { - if (*src == '/') break; - src --; - } - - rt_snprintf(dest, DFS_PATH_MAX - 1, "%s/%s", argv[2], src); - } - else - { - fd = open(argv[2], O_RDONLY, 0); - if (fd >= 0) - { - close(fd); - - unlink(argv[2]); - } - - dest = argv[2]; - } - - rename(argv[1], dest); - if (dest != RT_NULL && dest != argv[2]) rt_free(dest); - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_mv, __cmd_mv, Rename SOURCE to DEST.); - -int cmd_cat(int argc, char **argv) -{ - int index; - extern void cat(const char *filename); - - if (argc == 1) - { - rt_kprintf("Usage: cat [FILE]...\n"); - rt_kprintf("Concatenate FILE(s)\n"); - return 0; - } - - for (index = 1; index < argc; index ++) - { - cat(argv[index]); - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_cat, __cmd_cat, Concatenate FILE(s)); - -int cmd_rm(int argc, char **argv) -{ - int index; - - if (argc == 1) - { - rt_kprintf("Usage: rm FILE...\n"); - rt_kprintf("Remove (unlink) the FILE(s).\n"); - return 0; - } - - for (index = 1; index < argc; index ++) - { - unlink(argv[index]); - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_rm, __cmd_rm, Remove(unlink) the FILE(s).); - -#ifdef DFS_USING_WORKDIR -int cmd_cd(int argc, char **argv) -{ - if (argc == 1) - { - rt_kprintf("%s\n", working_directory); - } - else if (argc == 2) - { - if (chdir(argv[1]) != 0) - { - rt_kprintf("No such directory: %s\n", argv[1]); - } - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_cd, __cmd_cd, Change the shell working directory.); - -int cmd_pwd(int argc, char **argv) -{ - rt_kprintf("%s\n", working_directory); - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_pwd, __cmd_pwd, Print the name of the current working directory.); -#endif - -int cmd_mkdir(int argc, char **argv) -{ - if (argc == 1) - { - rt_kprintf("Usage: mkdir [OPTION] DIRECTORY\n"); - rt_kprintf("Create the DIRECTORY, if they do not already exist.\n"); - } - else - { - mkdir(argv[1], 0); - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkdir, __cmd_mkdir, Create the DIRECTORY.); - -int cmd_mkfs(int argc, char **argv) -{ - int result = 0; - char *type = "elm"; /* use the default file system type as 'fatfs' */ - - if (argc == 2) - { - result = dfs_mkfs(type, argv[1]); - } - else if (argc == 4) - { - if (strcmp(argv[1], "-t") == 0) - { - type = argv[2]; - result = dfs_mkfs(type, argv[3]); - } - } - else - { - rt_kprintf("Usage: mkfs [-t type] device\n"); - return 0; - } - - if (result != RT_EOK) - { - rt_kprintf("mkfs failed, result=%d\n", result); - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkfs, __cmd_mkfs, format disk with file system); - -extern int df(const char *path); -int cmd_df(int argc, char** argv) -{ - if (argc != 2) - { - df("/"); - } - else - { - if ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0)) - { - rt_kprintf("df [path]\n"); - } - else - { - df(argv[1]); - } - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_df, __cmd_df, disk free); - -int cmd_echo(int argc, char** argv) -{ - if (argc == 2) - { - rt_kprintf("%s\n", argv[1]); - } - else if (argc == 3) - { - int fd; - - fd = open(argv[2], O_RDWR | O_APPEND | O_CREAT, 0); - if (fd >= 0) - { - write (fd, argv[1], strlen(argv[1])); - close(fd); - } - else - { - rt_kprintf("open file:%s failed!\n", argv[2]); - } - } - else - { - rt_kprintf("Usage: echo \"string\" [filename]\n"); - } - - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file); -#endif - -int cmd_ps(int argc, char **argv) -{ - extern long list_thread(void); - extern int list_module(void); - -#ifdef RT_USING_MODULE - if ((argc == 2) && (strcmp(argv[1], "-m") == 0)) - list_module(); - else -#endif - list_thread(); - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_ps, __cmd_ps, List threads in the system.); - -int cmd_time(int argc, char **argv) -{ - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_time, __cmd_time, Execute command with time.); - -#ifdef RT_USING_HEAP -int cmd_free(int argc, char **argv) -{ - extern void list_mem(void); - extern void list_memheap(void); - -#ifdef RT_USING_MEMHEAP_AS_HEAP - list_memheap(); -#else - list_mem(); -#endif - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(cmd_free, __cmd_free, Show the memory usage in the system.); -#endif - -#endif /* FINSH_USING_MSH */ diff --git a/components/finsh/msh_file.c b/components/finsh/msh_file.c index d8eec0a71a..10251b4cb5 100644 --- a/components/finsh/msh_file.c +++ b/components/finsh/msh_file.c @@ -137,5 +137,276 @@ int msh_exec_script(const char *cmd_line, int size) return ret; } +#ifdef DFS_USING_WORKDIR +extern char working_directory[]; +#endif + +int cmd_ls(int argc, char **argv) +{ + extern void ls(const char *pathname); + + if (argc == 1) + { +#ifdef DFS_USING_WORKDIR + ls(working_directory); +#else + ls("/"); +#endif + } + else + { + ls(argv[1]); + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_ls, __cmd_ls, List information about the FILEs.); + +int cmd_cp(int argc, char **argv) +{ + void copy(const char *src, const char *dst); + + if (argc != 3) + { + rt_kprintf("Usage: cp SOURCE DEST\n"); + rt_kprintf("Copy SOURCE to DEST.\n"); + } + else + { + copy(argv[1], argv[2]); + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_cp, __cmd_cp, Copy SOURCE to DEST.); + +int cmd_mv(int argc, char **argv) +{ + if (argc != 3) + { + rt_kprintf("Usage: mv SOURCE DEST\n"); + rt_kprintf("Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n"); + } + else + { + int fd; + char *dest = RT_NULL; + + rt_kprintf("%s => %s\n", argv[1], argv[2]); + + fd = open(argv[2], O_DIRECTORY, 0); + if (fd >= 0) + { + char *src; + + close(fd); + + /* it's a directory */ + dest = (char *)rt_malloc(DFS_PATH_MAX); + if (dest == RT_NULL) + { + rt_kprintf("out of memory\n"); + return -RT_ENOMEM; + } + + src = argv[1] + rt_strlen(argv[1]); + while (src != argv[1]) + { + if (*src == '/') break; + src --; + } + + rt_snprintf(dest, DFS_PATH_MAX - 1, "%s/%s", argv[2], src); + } + else + { + fd = open(argv[2], O_RDONLY, 0); + if (fd >= 0) + { + close(fd); + + unlink(argv[2]); + } + + dest = argv[2]; + } + + rename(argv[1], dest); + if (dest != RT_NULL && dest != argv[2]) rt_free(dest); + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_mv, __cmd_mv, Rename SOURCE to DEST.); + +int cmd_cat(int argc, char **argv) +{ + int index; + extern void cat(const char *filename); + + if (argc == 1) + { + rt_kprintf("Usage: cat [FILE]...\n"); + rt_kprintf("Concatenate FILE(s)\n"); + return 0; + } + + for (index = 1; index < argc; index ++) + { + cat(argv[index]); + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_cat, __cmd_cat, Concatenate FILE(s)); + +int cmd_rm(int argc, char **argv) +{ + int index; + + if (argc == 1) + { + rt_kprintf("Usage: rm FILE...\n"); + rt_kprintf("Remove (unlink) the FILE(s).\n"); + return 0; + } + + for (index = 1; index < argc; index ++) + { + unlink(argv[index]); + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_rm, __cmd_rm, Remove(unlink) the FILE(s).); + +#ifdef DFS_USING_WORKDIR +int cmd_cd(int argc, char **argv) +{ + if (argc == 1) + { + rt_kprintf("%s\n", working_directory); + } + else if (argc == 2) + { + if (chdir(argv[1]) != 0) + { + rt_kprintf("No such directory: %s\n", argv[1]); + } + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_cd, __cmd_cd, Change the shell working directory.); + +int cmd_pwd(int argc, char **argv) +{ + rt_kprintf("%s\n", working_directory); + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_pwd, __cmd_pwd, Print the name of the current working directory.); +#endif + +int cmd_mkdir(int argc, char **argv) +{ + if (argc == 1) + { + rt_kprintf("Usage: mkdir [OPTION] DIRECTORY\n"); + rt_kprintf("Create the DIRECTORY, if they do not already exist.\n"); + } + else + { + mkdir(argv[1], 0); + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkdir, __cmd_mkdir, Create the DIRECTORY.); + +int cmd_mkfs(int argc, char **argv) +{ + int result = 0; + char *type = "elm"; /* use the default file system type as 'fatfs' */ + + if (argc == 2) + { + result = dfs_mkfs(type, argv[1]); + } + else if (argc == 4) + { + if (strcmp(argv[1], "-t") == 0) + { + type = argv[2]; + result = dfs_mkfs(type, argv[3]); + } + } + else + { + rt_kprintf("Usage: mkfs [-t type] device\n"); + return 0; + } + + if (result != RT_EOK) + { + rt_kprintf("mkfs failed, result=%d\n", result); + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkfs, __cmd_mkfs, format disk with file system); + +extern int df(const char *path); +int cmd_df(int argc, char** argv) +{ + if (argc != 2) + { + df("/"); + } + else + { + if ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0)) + { + rt_kprintf("df [path]\n"); + } + else + { + df(argv[1]); + } + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_df, __cmd_df, disk free); + +int cmd_echo(int argc, char** argv) +{ + if (argc == 2) + { + rt_kprintf("%s\n", argv[1]); + } + else if (argc == 3) + { + int fd; + + fd = open(argv[2], O_RDWR | O_APPEND | O_CREAT, 0); + if (fd >= 0) + { + write (fd, argv[1], strlen(argv[1])); + close(fd); + } + else + { + rt_kprintf("open file:%s failed!\n", argv[2]); + } + } + else + { + rt_kprintf("Usage: echo \"string\" [filename]\n"); + } + + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file); + #endif /* defined(FINSH_USING_MSH) && defined(RT_USING_DFS) */ diff --git a/components/finsh/shell.c b/components/finsh/shell.c index 76ac726597..c35ed1cd86 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -41,6 +41,14 @@ static char finsh_thread_stack[FINSH_THREAD_STACK_SIZE]; struct finsh_shell _shell; #endif +/* finsh symtab */ +#ifdef FINSH_USING_SYMTAB +struct finsh_syscall *_syscall_table_begin = NULL; +struct finsh_syscall *_syscall_table_end = NULL; +struct finsh_sysvar *_sysvar_table_begin = NULL; +struct finsh_sysvar *_sysvar_table_end = NULL; +#endif + struct finsh_shell *shell; static char *finsh_prompt_custom = RT_NULL; @@ -158,6 +166,7 @@ void finsh_set_prompt_mode(rt_uint32_t prompt_mode) static int finsh_getchar(void) { +#ifdef RT_USING_DEVICE #ifdef RT_USING_POSIX return getchar(); #else @@ -169,9 +178,13 @@ static int finsh_getchar(void) return (int)ch; #endif +#else + extern char rt_hw_console_getchar(void); + return rt_hw_console_getchar(); +#endif } -#ifndef RT_USING_POSIX +#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE) static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size) { RT_ASSERT(shell != RT_NULL); @@ -499,7 +512,7 @@ void finsh_thread_entry(void *parameter) finsh_init(&shell->parser); #endif -#ifndef RT_USING_POSIX +#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE) /* set console device as shell device */ if (shell->device == RT_NULL) { diff --git a/components/finsh/shell.h b/components/finsh/shell.h index 2cf2c9b833..8741759ed4 100644 --- a/components/finsh/shell.h +++ b/components/finsh/shell.h @@ -79,10 +79,10 @@ struct finsh_shell #endif char line[FINSH_CMD_SIZE]; - rt_uint8_t line_position; - rt_uint8_t line_curpos; + rt_uint16_t line_position; + rt_uint16_t line_curpos; -#ifndef RT_USING_POSIX +#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE) rt_device_t device; #endif diff --git a/components/finsh/symbol.c b/components/finsh/symbol.c index e500637bdd..78df9fac5c 100644 --- a/components/finsh/symbol.c +++ b/components/finsh/symbol.c @@ -10,7 +10,7 @@ #include <rtthread.h> -#ifdef RT_USING_FINSH +#if defined(RT_USING_FINSH) && !defined(FINSH_USING_SYMTAB) #include "finsh.h" @@ -27,12 +27,6 @@ long list_msgqueue(void); long list_mempool(void); long list_timer(void); -#ifdef FINSH_USING_SYMTAB -struct finsh_syscall *_syscall_table_begin = NULL; -struct finsh_syscall *_syscall_table_end = NULL; -struct finsh_sysvar *_sysvar_table_begin = NULL; -struct finsh_sysvar *_sysvar_table_end = NULL; -#else struct finsh_syscall _syscall_table[] = { {"hello", hello}, @@ -67,7 +61,6 @@ struct finsh_syscall *_syscall_table_end = &_syscall_table[sizeof(_syscall_tab struct finsh_sysvar *_sysvar_table_begin = NULL; struct finsh_sysvar *_sysvar_table_end = NULL; -#endif -#endif /* RT_USING_FINSH */ +#endif /* RT_USING_FINSH && !FINSH_USING_SYMTAB */ diff --git a/components/libc/Kconfig b/components/libc/Kconfig index 43d9330102..2d1e9315f1 100644 --- a/components/libc/Kconfig +++ b/components/libc/Kconfig @@ -39,4 +39,10 @@ if RT_USING_LIBC && RT_USING_DFS default n endif +if RT_USING_LIBC != y + config RT_LIBC_USING_TIME + bool "Enable TIME FUNCTIONS WITHOUT COMPILER'S LIBC" + default y +endif + endmenu diff --git a/components/libc/compilers/armlibc/libc.h b/components/libc/compilers/armlibc/libc.h index 158fe06c3e..b9b1b6212d 100644 --- a/components/libc/compilers/armlibc/libc.h +++ b/components/libc/compilers/armlibc/libc.h @@ -12,11 +12,17 @@ #include <stddef.h> +#ifdef __cplusplus +extern "C" { +#endif int libc_system_init(void); int libc_stdio_set_console(const char* device_name, int mode); int libc_stdio_get_console(void); -int libc_stdio_read (void *buffer, size_t size); -int libc_stdio_write(const void *buffer, size_t size); +int libc_stdio_read(void* buffer, size_t size); +int libc_stdio_write(const void* buffer, size_t size); +#ifdef __cplusplus +} +#endif #endif diff --git a/components/libc/compilers/armlibc/sys/time.h b/components/libc/compilers/armlibc/sys/time.h deleted file mode 100644 index bac122e183..0000000000 --- a/components/libc/compilers/armlibc/sys/time.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef _SYS_TIME_H_ -#define _SYS_TIME_H_ - -#include <time.h> -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _TIMEVAL_DEFINED -#define _TIMEVAL_DEFINED -/* - * Structure returned by gettimeofday(2) system call, - * and used in other calls. - */ -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif /* _TIMEVAL_DEFINED */ - -#ifndef _TIMESPEC_DEFINED -#define _TIMESPEC_DEFINED -/* - * Structure defined by POSIX.1b to be like a timeval. - */ -struct timespec { - time_t tv_sec; /* seconds */ - long tv_nsec; /* and nanoseconds */ -}; -#endif /* _TIMESPEC_DEFINED */ - -struct timezone { - int tz_minuteswest; /* minutes west of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; - -int gettimeofday(struct timeval *tp, void *ignore); -struct tm *gmtime_r(const time_t *timep, struct tm *r); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_TIME_H_ */ diff --git a/components/libc/compilers/armlibc/time.c b/components/libc/compilers/armlibc/time.c deleted file mode 100644 index f099d51330..0000000000 --- a/components/libc/compilers/armlibc/time.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#include <sys/time.h> -#include <rtthread.h> - -#ifdef RT_USING_DEVICE -int gettimeofday(struct timeval *tp, void *ignore) -{ - time_t time; - rt_device_t device; - - device = rt_device_find("rtc"); - RT_ASSERT(device != RT_NULL); - - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); - if (tp != RT_NULL) - { - tp->tv_sec = time; - tp->tv_usec = 0; - } - - return time; -} -#endif - -/** - * Returns the current time. - * - * @param time_t * t the timestamp pointer, if not used, keep NULL. - * - * @return time_t return timestamp current. - * - */ -/* for IAR 6.2 later Compiler */ -#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 -#pragma module_name = "?time" -time_t (__time32)(time_t *t) /* Only supports 32-bit timestamp */ -#else -time_t time(time_t *t) -#endif -{ - time_t time_now = 0; - -#ifdef RT_USING_RTC - static rt_device_t device = RT_NULL; - - /* optimization: find rtc device only first. */ - if (device == RT_NULL) - { - device = rt_device_find("rtc"); - } - - /* read timestamp from RTC device. */ - if (device != RT_NULL) - { - if (rt_device_open(device, 0) == RT_EOK) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); - rt_device_close(device); - } - } -#endif /* RT_USING_RTC */ - - /* if t is not NULL, write timestamp to *t */ - if (t != RT_NULL) - { - *t = time_now; - } - - return time_now; -} - -RT_WEAK clock_t clock(void) -{ - return rt_tick_get(); -} diff --git a/components/libc/compilers/common/SConscript b/components/libc/compilers/common/SConscript index 02bf49941d..a8d2606820 100644 --- a/components/libc/compilers/common/SConscript +++ b/components/libc/compilers/common/SConscript @@ -2,11 +2,18 @@ from building import * Import('rtconfig') -src = Glob('*.c') +src = [] cwd = GetCurrentDir() group = [] CPPPATH = [cwd] -group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'], CPPPATH = CPPPATH) +if GetDepend('RT_USING_LIBC'): + src += Glob('*.c') +else: + if GetDepend('RT_LIBC_USING_TIME'): + src += ['time.c'] + +if (rtconfig.PLATFORM == 'armcc' or rtconfig.PLATFORM == 'iar') and rtconfig.ARCH != 'sim' : + group = DefineGroup('libc', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/components/libc/compilers/common/gmtime_r.c b/components/libc/compilers/common/gmtime_r.c deleted file mode 100644 index dff251ab6c..0000000000 --- a/components/libc/compilers/common/gmtime_r.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-10-26 zylx first version - */ - -#if defined(__CC_ARM) || defined(__CLANG_ARM) || defined (__IAR_SYSTEMS_ICC__) -#include <sys/time.h> - -/* seconds per day */ -#define SPD 24*60*60 - -/* days per month -- nonleap! */ -const short __spm[13] = -{ - 0, - (31), - (31 + 28), - (31 + 28 + 31), - (31 + 28 + 31 + 30), - (31 + 28 + 31 + 30 + 31), - (31 + 28 + 31 + 30 + 31 + 30), - (31 + 28 + 31 + 30 + 31 + 30 + 31), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31), -}; - -int __isleap(int year) -{ - /* every fourth year is a leap year except for century years that are - * not divisible by 400. */ - /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */ - return (!(year % 4) && ((year % 100) || !(year % 400))); -} - -/** - * This function will convert Time (Restartable) - * - * @param timep the timestamp - * @param the structure to stores information - * - * @return the structure to stores information - * - */ -struct tm *gmtime_r(const time_t *timep, struct tm *r) -{ - time_t i; - register time_t work = *timep % (SPD); - r->tm_sec = work % 60; - work /= 60; - r->tm_min = work % 60; - r->tm_hour = work / 60; - work = *timep / (SPD); - r->tm_wday = (4 + work) % 7; - for (i = 1970;; ++i) - { - register time_t k = __isleap(i) ? 366 : 365; - if (work >= k) - work -= k; - else - break; - } - r->tm_year = i - 1900; - r->tm_yday = work; - - r->tm_mday = 1; - if (__isleap(i) && (work > 58)) - { - if (work == 59) - r->tm_mday = 2; /* 29.2. */ - work -= 1; - } - - for (i = 11; i && (__spm[i] > work); --i) - ; - r->tm_mon = i; - r->tm_mday += work - __spm[i]; - return r; -} -#endif /* end of __CC_ARM or __CLANG_ARM or __IAR_SYSTEMS_ICC__ */ - diff --git a/components/libc/compilers/dlib/sys/time.h b/components/libc/compilers/common/sys/time.h index baf566936b..1d68eeafa3 100644 --- a/components/libc/compilers/dlib/sys/time.h +++ b/components/libc/compilers/common/sys/time.h @@ -10,7 +10,6 @@ #define _SYS_TIME_H_ #include <time.h> -#include <sys/types.h> #ifdef __cplusplus extern "C" { diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c new file mode 100644 index 0000000000..50a800b259 --- /dev/null +++ b/components/libc/compilers/common/time.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-21 zhangjun copy from minilibc + */ + +#include <sys/time.h> +#include <rtthread.h> + +#if !defined (__IAR_SYSTEMS_ICC__) + +/* days per month -- nonleap! */ +const short __spm[13] = +{ + 0, + (31), + (31 + 28), + (31 + 28 + 31), + (31 + 28 + 31 + 30), + (31 + 28 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31), +}; +static const char days[] = "Sun Mon Tue Wed Thu Fri Sat "; +static const char months[] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec "; + +/* seconds per day */ +#define SPD 24*60*60 + +int __isleap(int year) +{ + /* every fourth year is a leap year except for century years that are + * not divisible by 400. */ + /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */ + return (!(year % 4) && ((year % 100) || !(year % 400))); +} + +struct tm *gmtime_r(const time_t *timep, struct tm *r) +{ + time_t i; + register time_t work = *timep % (SPD); + r->tm_sec = work % 60; + work /= 60; + r->tm_min = work % 60; + r->tm_hour = work / 60; + work = *timep / (SPD); + r->tm_wday = (4 + work) % 7; + for (i = 1970;; ++i) + { + register time_t k = __isleap(i) ? 366 : 365; + if (work >= k) + work -= k; + else + break; + } + r->tm_year = i - 1900; + r->tm_yday = work; + + r->tm_mday = 1; + if (__isleap(i) && (work > 58)) + { + if (work == 59) + r->tm_mday = 2; /* 29.2. */ + work -= 1; + } + + for (i = 11; i && (__spm[i] > work); --i) + ; + r->tm_mon = i; + r->tm_mday += work - __spm[i]; + return r; +} + +struct tm* gmtime(const time_t* t) +{ + static struct tm tmp; + return gmtime_r(t, &tmp); +} + +/*TODO timezone is not supprt now */ +struct tm* localtime_r(const time_t* t, struct tm* r) +{ + return gmtime_r(t, r); +} + +struct tm* localtime(const time_t* t) +{ + static struct tm tmp; + return localtime_r(t, &tmp); +} + +time_t mktime(struct tm * const t) +{ + register time_t day; + register time_t i; + register time_t years = t->tm_year - 70; + + if (t->tm_sec > 60) + { + t->tm_min += t->tm_sec / 60; + t->tm_sec %= 60; + } + if (t->tm_min > 60) + { + t->tm_hour += t->tm_min / 60; + t->tm_min %= 60; + } + if (t->tm_hour > 24) + { + t->tm_mday += t->tm_hour / 24; + t->tm_hour %= 24; + } + if (t->tm_mon > 12) + { + t->tm_year += t->tm_mon / 12; + t->tm_mon %= 12; + } + while (t->tm_mday > __spm[1 + t->tm_mon]) + { + if (t->tm_mon == 1 && __isleap(t->tm_year + 1900)) + { + --t->tm_mday; + } + t->tm_mday -= __spm[t->tm_mon]; + ++t->tm_mon; + if (t->tm_mon > 11) + { + t->tm_mon = 0; + ++t->tm_year; + } + } + + if (t->tm_year < 70) + return (time_t) - 1; + + /* Days since 1970 is 365 * number of years + number of leap years since 1970 */ + day = years * 365 + (years + 1) / 4; + + /* After 2100 we have to substract 3 leap years for every 400 years + This is not intuitive. Most mktime implementations do not support + dates after 2059, anyway, so we might leave this out for it's + bloat. */ + if (years >= 131) + { + years -= 131; + years /= 100; + day -= (years >> 2) * 3 + 1; + if ((years &= 3) == 3) + years--; + day -= years; + } + + day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 + + (__isleap(t->tm_year + 1900) & (t->tm_mon > 1)); + + /* day is now the number of days since 'Jan 1 1970' */ + i = 7; + t->tm_wday = (day + 4) % i; /* Sunday=0, Monday=1, ..., Saturday=6 */ + + i = 24; + day *= i; + i = 60; + return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec; +} + +static void num2str(char *c, int i) +{ + c[0] = i / 10 + '0'; + c[1] = i % 10 + '0'; +} + +char* asctime_r(const struct tm *t, char *buf) +{ + /* "Wed Jun 30 21:49:08 1993\n" */ + *(int*) buf = *(int*) (days + (t->tm_wday << 2)); + *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2)); + num2str(buf + 8, t->tm_mday); + if (buf[8] == '0') + buf[8] = ' '; + buf[10] = ' '; + num2str(buf + 11, t->tm_hour); + buf[13] = ':'; + num2str(buf + 14, t->tm_min); + buf[16] = ':'; + num2str(buf + 17, t->tm_sec); + buf[19] = ' '; + num2str(buf + 20, (t->tm_year + 1900) / 100); + num2str(buf + 22, (t->tm_year + 1900) % 100); + buf[24] = '\n'; + return buf; +} + +char* asctime(const struct tm *timeptr) +{ + static char buf[25]; + return asctime_r(timeptr, buf); +} + +char* ctime(const time_t *timep) +{ + return asctime(localtime(timep)); +} + +#endif /* __IAR_SYSTEMS_ICC__ */ + +int gettimeofday(struct timeval *tp, void *ignore) +{ + time_t time = 0; +#ifdef RT_USING_DEVICE + rt_device_t device; + device = rt_device_find("rtc"); + RT_ASSERT(device != RT_NULL); + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); + if (tp != RT_NULL) + { + tp->tv_sec = time; + tp->tv_usec = 0; + } +#else + tv->tv_sec = 0; + tv->tv_usec = 0; +#endif + + return time; +} + + +/** + * Returns the current time. + * + * @param time_t * t the timestamp pointer, if not used, keep NULL. + * + * @return time_t return timestamp current. + * + */ +/* for IAR 6.2 later Compiler */ +#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 +#pragma module_name = "?time" +#if _DLIB_TIME_USES_64 +time_t __time64(time_t *t) +#else +time_t __time32(time_t *t) +#endif +#else +time_t time(time_t *t) +#endif +{ + time_t time_now = 0; + +#ifdef RT_USING_RTC + static rt_device_t device = RT_NULL; + + /* optimization: find rtc device only first. */ + if (device == RT_NULL) + { + device = rt_device_find("rtc"); + } + + /* read timestamp from RTC device. */ + if (device != RT_NULL) + { + if (rt_device_open(device, 0) == RT_EOK) + { + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); + rt_device_close(device); + } + } +#endif /* RT_USING_RTC */ + + /* if t is not NULL, write timestamp to *t */ + if (t != RT_NULL) + { + *t = time_now; + } + + return time_now; +} + +RT_WEAK clock_t clock(void) +{ + return rt_tick_get(); +} diff --git a/components/libc/compilers/dlib/libc.h b/components/libc/compilers/dlib/libc.h index 7b2665c32b..5b46bee0c8 100644 --- a/components/libc/compilers/dlib/libc.h +++ b/components/libc/compilers/dlib/libc.h @@ -13,11 +13,17 @@ #include <stddef.h> +#ifdef __cplusplus +extern "C" { +#endif int libc_system_init(void); int libc_stdio_set_console(const char* device_name, int mode); int libc_stdio_get_console(void); -int libc_stdio_read (void *buffer, size_t size); -int libc_stdio_write(const void *buffer, size_t size); +int libc_stdio_read(void* buffer, size_t size); +int libc_stdio_write(const void* buffer, size_t size); +#ifdef __cplusplus +} +#endif #endif diff --git a/components/libc/compilers/dlib/time.c b/components/libc/compilers/dlib/time.c deleted file mode 100644 index df35313b0e..0000000000 --- a/components/libc/compilers/dlib/time.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#include <sys/time.h> -#include <rtthread.h> - -#ifdef RT_USING_DEVICE -int gettimeofday(struct timeval *tp, void *ignore) -{ - time_t time; - rt_device_t device; - - device = rt_device_find("rtc"); - RT_ASSERT(device != RT_NULL); - - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); - if (tp != RT_NULL) - { - tp->tv_sec = time; - tp->tv_usec = 0; - } - - return time; -} -#endif - -/** - * Returns the current time. - * - * @param time_t * t the timestamp pointer, if not used, keep NULL. - * - * @return time_t return timestamp current. - * - */ -#pragma module_name = "?time" -#if _DLIB_TIME_USES_64 -time_t __time64(time_t *t) -#else -/* for IAR 6.2 later Compiler */ -#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 -time_t __time32(time_t *t) -#else -time_t time(time_t *t) -#endif -#endif -{ - time_t time_now = 0; - -#ifdef RT_USING_RTC - static rt_device_t device = RT_NULL; - - /* optimization: find rtc device only first. */ - if (device == RT_NULL) - { - device = rt_device_find("rtc"); - } - - /* read timestamp from RTC device. */ - if (device != RT_NULL) - { - if (rt_device_open(device, 0) == RT_EOK) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); - rt_device_close(device); - } - } -#endif /* RT_USING_RTC */ - - /* if t is not NULL, write timestamp to *t */ - if (t != RT_NULL) - { - *t = time_now; - } - - return time_now; -} - -RT_WEAK clock_t clock(void) -{ - return rt_tick_get(); -} diff --git a/components/libc/compilers/minilibc/math.h b/components/libc/compilers/minilibc/math.h index 9ddb9c859b..49b80d8219 100644 --- a/components/libc/compilers/minilibc/math.h +++ b/components/libc/compilers/minilibc/math.h @@ -14,4 +14,7 @@ double sin(double x); double cos(double x); +typedef float float_t; +typedef double double_t; + #endif diff --git a/components/libc/compilers/newlib/libc.h b/components/libc/compilers/newlib/libc.h index ab9334fe26..fdf2ab4f60 100644 --- a/components/libc/compilers/newlib/libc.h +++ b/components/libc/compilers/newlib/libc.h @@ -27,13 +27,19 @@ #define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND) #define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND) +#ifdef __cplusplus +extern "C" { +#endif int libc_system_init(void); int libc_stdio_set_console(const char* device_name, int mode); int libc_stdio_get_console(void); /* some time related function */ -int libc_set_time(const struct timespec *time); -int libc_get_time(struct timespec *time); -int libc_time_to_tick(const struct timespec *time); +int libc_set_time(const struct timespec* time); +int libc_get_time(struct timespec* time); +int libc_time_to_tick(const struct timespec* time); +#ifdef __cplusplus +} +#endif #endif diff --git a/components/libc/compilers/newlib/syscalls.c b/components/libc/compilers/newlib/syscalls.c index 9919e11727..59c1881ad1 100644 --- a/components/libc/compilers/newlib/syscalls.c +++ b/components/libc/compilers/newlib/syscalls.c @@ -442,3 +442,18 @@ void abort(void) while (1); } + +uid_t getuid(void) +{ + return 0; +} + +mode_t umask(mode_t mask) +{ + return 022; +} + +int flock(int fd, int operation) +{ + return 0; +} diff --git a/components/libc/pthreads/pthread.c b/components/libc/pthreads/pthread.c index 7ecf304038..5d3bc0796a 100644..100755 --- a/components/libc/pthreads/pthread.c +++ b/components/libc/pthreads/pthread.c @@ -102,7 +102,7 @@ void _pthread_data_destroy(pthread_t pth) rt_sem_delete(ptd->joinable_sem); /* release thread resource */ - if (ptd->attr.stackaddr == RT_NULL) + if (ptd->attr.stackaddr == RT_NULL && ptd->tid->stack_addr != RT_NULL) { /* release thread allocated stack */ rt_free(ptd->tid->stack_addr); @@ -219,20 +219,6 @@ int pthread_create(pthread_t *pid, } rt_snprintf(name, sizeof(name), "pth%02d", pthread_number ++); - if (ptd->attr.stackaddr == 0) - { - stack = (void *)rt_malloc(ptd->attr.stacksize); - } - else - { - stack = (void *)(ptd->attr.stackaddr); - } - - if (stack == RT_NULL) - { - ret = ENOMEM; - goto __exit; - } /* pthread is a static thread object */ ptd->tid = (rt_thread_t) rt_malloc(sizeof(struct rt_thread)); @@ -241,6 +227,7 @@ int pthread_create(pthread_t *pid, ret = ENOMEM; goto __exit; } + memset(ptd->tid, 0, sizeof(struct rt_thread)); if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE) { @@ -260,6 +247,22 @@ int pthread_create(pthread_t *pid, ptd->thread_entry = start; ptd->thread_parameter = parameter; + /* stack */ + if (ptd->attr.stackaddr == 0) + { + stack = (void *)rt_malloc(ptd->attr.stacksize); + } + else + { + stack = (void *)(ptd->attr.stackaddr); + } + + if (stack == RT_NULL) + { + ret = ENOMEM; + goto __exit; + } + /* initial this pthread to system */ if (rt_thread_init(ptd->tid, name, pthread_entry_stub, ptd, stack, ptd->attr.stacksize, diff --git a/components/net/Kconfig b/components/net/Kconfig index ff498a7425..4436934f09 100644 --- a/components/net/Kconfig +++ b/components/net/Kconfig @@ -1,18 +1,17 @@ menu "Network" menu "Socket abstraction layer" - + config RT_USING_SAL bool "Enable socket abstraction layer" select RT_USING_NETDEV - select RT_USING_LIBC select RT_USING_SYSTEM_WORKQUEUE default n if RT_USING_SAL if RT_USING_LWIP || AT_USING_SOCKET - + menu "protocol stack implement" config SAL_USING_LWIP @@ -24,29 +23,30 @@ config RT_USING_SAL bool "Support AT Commands stack" default y depends on AT_USING_SOCKET - + config SAL_USING_TLS bool "Support MbedTLS protocol" default y depends on PKG_USING_MBEDTLS endmenu - + endif config SAL_USING_POSIX bool "Enable BSD socket operated by file system API" default n select RT_USING_DFS + select RT_USING_LIBC select RT_USING_POSIX help Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs. - + if !SAL_USING_POSIX - + config SAL_SOCKETS_NUM int "the maximum number of sockets" default 16 - + endif endif @@ -68,7 +68,7 @@ config RT_USING_NETDEV config NETDEV_USING_PING bool "Enable ping features" default y - + config NETDEV_USING_NETSTAT bool "Enable netstat features" default y @@ -76,8 +76,8 @@ config RT_USING_NETDEV config NETDEV_USING_AUTO_DEFAULT bool "Enable default netdev automatic change features" default y - - config NETDEV_USING_IPV6 + + config NETDEV_USING_IPV6 bool "Enable IPV6 protocol support" default n @@ -94,7 +94,7 @@ config RT_USING_NETDEV bool help Defined to synchronize the ip6_addr structure state - default n + default n endif endmenu @@ -277,7 +277,7 @@ config RT_USING_LWIP config LWIP_NETIF_STATUS_CALLBACK int "Enable netif status callback" default 1 - + config LWIP_NETIF_LINK_CALLBACK int "Enable netif link status callback" default 1 @@ -314,7 +314,7 @@ config RT_USING_LWIP config RT_LWIP_USING_HW_CHECKSUM bool "Enable hardware checksum" default n - + config RT_LWIP_USING_PING bool "Enable ping features" default y diff --git a/components/net/at/Kconfig b/components/net/at/Kconfig index 5a4a644761..50de005545 100644 --- a/components/net/at/Kconfig +++ b/components/net/at/Kconfig @@ -9,11 +9,11 @@ if RT_USING_AT config AT_DEBUG bool "Enable debug log output" default n - + config AT_USING_SERVER bool "Enable AT commands server" default n - + if AT_USING_SERVER config AT_SERVER_DEVICE @@ -44,33 +44,32 @@ if RT_USING_AT endchoice endif - + config AT_USING_CLIENT bool "Enable AT commands client" default n - + if AT_USING_CLIENT config AT_CLIENT_NUM_MAX int "The maximum number of supported clients" default 1 range 1 65535 - + config AT_USING_SOCKET bool "Enable BSD Socket API support by AT commnads" - select RT_USING_LIBC select RT_USING_SAL default n - + endif if AT_USING_SERVER || AT_USING_CLIENT - + config AT_USING_CLI bool "Enable CLI(Command-Line Interface) for AT commands" default y depends on FINSH_USING_MSH - + config AT_PRINT_RAW_CMD bool "Enable print RAW format AT command communication data" default n @@ -78,7 +77,7 @@ if RT_USING_AT config AT_CMD_MAX_LEN int "The maximum lenght of AT Commonds buffer" default 128 - + endif config AT_SW_VERSION_NUM diff --git a/components/net/at/at_socket/at_socket.c b/components/net/at/at_socket/at_socket.c index 72ff9a7aa3..11be4e23c0 100644 --- a/components/net/at/at_socket/at_socket.c +++ b/components/net/at/at_socket/at_socket.c @@ -54,7 +54,6 @@ static rt_slist_t _socket_list = RT_SLIST_OBJECT_INIT(_socket_list); struct at_socket *at_get_socket(int socket) { rt_base_t level; - size_t list_num = 0; rt_slist_t *node = RT_NULL; struct at_socket *at_sock = RT_NULL; @@ -62,9 +61,9 @@ struct at_socket *at_get_socket(int socket) rt_slist_for_each(node, &_socket_list) { - if (socket == (list_num++)) + at_sock = rt_slist_entry(node, struct at_socket, list); + if (socket == at_sock->socket) { - at_sock = rt_slist_entry(node, struct at_socket, list); if (at_sock && at_sock->magic == AT_SOCKET_MAGIC) { rt_hw_interrupt_enable(level); @@ -275,6 +274,34 @@ static void at_do_event_clean(struct at_socket *sock, at_event_t event) } } +static int alloc_empty_socket(rt_slist_t *l) +{ + rt_base_t level; + rt_slist_t *node = RT_NULL; + rt_slist_t *pre_node = &_socket_list; + struct at_socket *at_sock = RT_NULL; + int idx = 0; + + level = rt_hw_interrupt_disable(); + + rt_slist_init(l); + + rt_slist_for_each(node, &_socket_list) + { + at_sock = rt_slist_entry(node, struct at_socket, list); + if(at_sock->socket != idx) + break; + idx++; + pre_node = node; + } + + rt_slist_insert(pre_node, l); + + rt_hw_interrupt_enable(level); + + return idx; +} + static struct at_socket *alloc_socket_by_device(struct at_device *device) { static rt_mutex_t at_slock = RT_NULL; @@ -304,21 +331,9 @@ static struct at_socket *alloc_socket_by_device(struct at_device *device) goto __err; } - /* add device socket to global socket list */ - { - rt_base_t level; - - level = rt_hw_interrupt_disable(); - - rt_slist_init(&(device->sockets[idx].list)); - rt_slist_append(&_socket_list, &(device->sockets[idx].list)); - - rt_hw_interrupt_enable(level); - } - sock = &(device->sockets[idx]); /* the socket descriptor is the number of sockte lists */ - sock->socket = rt_slist_len(&_socket_list) - 1; + sock->socket = alloc_empty_socket(&(sock->list)); /* the socket operations is the specify operations of the device */ sock->ops = device->class->socket_ops; /* the user-data is the at device socket descriptor */ @@ -446,7 +461,6 @@ static int free_socket(struct at_socket *sock) /* delect socket from socket list */ { rt_base_t level; - int list_num = 0; rt_slist_t *node = RT_NULL; struct at_socket *at_sock = RT_NULL; @@ -454,10 +468,10 @@ static int free_socket(struct at_socket *sock) rt_slist_for_each(node, &_socket_list) { - if (sock->socket == (list_num++)) + at_sock = rt_slist_entry(node, struct at_socket, list); + if (sock->socket == at_sock->socket) { - at_sock = rt_slist_entry(node, struct at_socket, list); - if (at_sock) + if (at_sock && at_sock->magic == AT_SOCKET_MAGIC) { rt_slist_remove(&_socket_list, &at_sock->list); break; diff --git a/components/net/at/include/at.h b/components/net/at/include/at.h index dc2abef353..a7a6aeca7a 100644 --- a/components/net/at/include/at.h +++ b/components/net/at/include/at.h @@ -96,7 +96,7 @@ struct at_server rt_device_t device; at_status_t status; - char (*get_char)(void); + rt_err_t (*get_char)(struct at_server *server, char *ch, rt_int32_t timeout); rt_bool_t echo_mode; char recv_buffer[AT_SERVER_RECV_BUFF_LEN]; @@ -194,6 +194,8 @@ int at_server_init(void); void at_server_printf(const char *format, ...); void at_server_printfln(const char *format, ...); void at_server_print_result(at_result_t result); +rt_size_t at_server_send(at_server_t server, const char *buf, rt_size_t size); +rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32_t timeout); /* AT server request arguments parse */ int at_req_parse_args(const char *req_args, const char *req_expr, ...); diff --git a/components/net/at/src/at_cli.c b/components/net/at/src/at_cli.c index 80af613fa6..e39a913357 100644 --- a/components/net/at/src/at_cli.c +++ b/components/net/at/src/at_cli.c @@ -100,6 +100,12 @@ void at_cli_deinit(void) } #ifdef AT_USING_SERVER +static rt_err_t at_server_console_getchar(struct at_server *server, char *ch, rt_int32_t timeout) +{ + *ch = console_getchar(); + return RT_EOK; +} + static void server_cli_parser(void) { extern at_server_t at_get_server(void); @@ -107,7 +113,7 @@ static void server_cli_parser(void) at_server_t server = at_get_server(); rt_base_t int_lvl; static rt_device_t device_bak; - static char (*getchar_bak)(void); + static rt_err_t (*getchar_bak)(struct at_server *server, char *ch, rt_int32_t timeout); static char endmark_back[AT_END_MARK_LEN]; /* backup server device and getchar function */ @@ -122,7 +128,7 @@ static void server_cli_parser(void) /* setup server device as console device */ server->device = rt_console_get_device(); - server->get_char = console_getchar; + server->get_char = at_server_console_getchar; memset(server->end_mark, 0x00, AT_END_MARK_LEN); server->end_mark[0] = '\r'; diff --git a/components/net/at/src/at_server.c b/components/net/at/src/at_server.c index 31f1bec96f..81d00951f5 100644 --- a/components/net/at/src/at_server.c +++ b/components/net/at/src/at_server.c @@ -167,6 +167,79 @@ void rt_at_server_print_all_cmd(void) } } +/** + * Send data to AT Client by uart device. + * + * @param server current AT server object + * @param buf send data buffer + * @param size send fixed data size + * + * @return >0: send data size + * =0: send failed + */ +rt_size_t at_server_send(at_server_t server, const char *buf, rt_size_t size) +{ + RT_ASSERT(buf); + + if (server == RT_NULL) + { + LOG_E("input AT Server object is NULL, please create or get AT Server object!"); + return 0; + } + + return rt_device_write(server->device, 0, buf, size); +} + +/** + * AT Server receive fixed-length data. + * + * @param client current AT Server object + * @param buf receive data buffer + * @param size receive fixed data size + * @param timeout receive data timeout (ms) + * + * @note this function can only be used in execution function of AT commands + * + * @return >0: receive data size + * =0: receive failed + */ +rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32_t timeout) +{ + rt_size_t read_idx = 0; + rt_err_t result = RT_EOK; + char ch = 0; + + RT_ASSERT(buf); + + if (server == RT_NULL) + { + LOG_E("input AT Server object is NULL, please create or get AT Server object!"); + return 0; + } + + while (1) + { + if (read_idx < size) + { + /* check get data value */ + result = server->get_char(server, &ch, timeout); + if (result != RT_EOK) + { + LOG_E("AT Server receive failed, uart device get data error."); + return 0; + } + + buf[read_idx++] = ch; + } + else + { + break; + } + } + + return read_idx; +} + at_server_t at_get_server(void) { RT_ASSERT(at_server_local); @@ -339,17 +412,21 @@ static rt_err_t at_cmd_get_name(const char *cmd_buffer, char *cmd_name) return -RT_ERROR; } -static char at_server_gerchar(void) +static rt_err_t at_server_gerchar(at_server_t server, char *ch, rt_int32_t timeout) { - char ch; + rt_err_t result = RT_EOK; - while (rt_device_read(at_server_local->device, 0, &ch, 1) == 0) + while (rt_device_read(at_server_local->device, 0, ch, 1) == 0) { rt_sem_control(at_server_local->rx_notice, RT_IPC_CMD_RESET, RT_NULL); - rt_sem_take(at_server_local->rx_notice, RT_WAITING_FOREVER); + result = rt_sem_take(at_server_local->rx_notice, rt_tick_from_millisecond(timeout)); + if (result != RT_EOK) + { + return result; + } } - return ch; + return result; } static void server_parser(at_server_t server) @@ -365,14 +442,24 @@ static void server_parser(at_server_t server) RT_ASSERT(server); RT_ASSERT(server->status != AT_STATUS_UNINITIALIZED); - while (ESC_KEY != (ch = server->get_char())) + while (1) { + server->get_char(server, &ch, RT_WAITING_FOREVER); + if (ESC_KEY == ch) + { + break; + } + if (server->echo_mode) { if (ch == AT_CMD_CR || (ch == AT_CMD_LF && last_ch != AT_CMD_CR)) { at_server_printf("%c%c", AT_CMD_CR, AT_CMD_LF); } + else if (ch == AT_CMD_LF) + { + // skip the end sign check + } else if (ch == BACKSPACE_KEY || ch == DELECT_KEY) { if (server->cur_recv_len) diff --git a/components/net/lwip-1.4.1/src/arch/sys_arch.c b/components/net/lwip-1.4.1/src/arch/sys_arch.c index b8085e69d1..c31bd59c1d 100644 --- a/components/net/lwip-1.4.1/src/arch/sys_arch.c +++ b/components/net/lwip-1.4.1/src/arch/sys_arch.c @@ -198,7 +198,7 @@ int lwip_system_init(void) return 0; } -INIT_COMPONENT_EXPORT(lwip_system_init); +INIT_PREV_EXPORT(lwip_system_init); void sys_init(void) { diff --git a/components/net/lwip-1.4.1/src/core/dns.c b/components/net/lwip-1.4.1/src/core/dns.c index 18c73d0a8c..2e1356ca97 100644 --- a/components/net/lwip-1.4.1/src/core/dns.c +++ b/components/net/lwip-1.4.1/src/core/dns.c @@ -279,13 +279,14 @@ dns_setserver(u8_t numdns, ip_addr_t *dnsserver) dns_servers[numdns] = (*dnsserver); #ifdef RT_USING_NETDEV - extern struct netif *netif_default; + extern struct netif *netif_list; extern struct netdev *netdev_get_by_name(const char *name); extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); + struct netif *netif = NULL; /* set network interface device DNS server address */ - if (netif_default) { - netdev_low_level_set_dns_server(netdev_get_by_name(netif_default->name), numdns, dnsserver); + for (netif = netif_list; netif != NULL; netif = netif->next) { + netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver); } #endif /* RT_USING_NETDEV */ } diff --git a/components/net/lwip-1.4.1/src/netif/ethernetif.c b/components/net/lwip-1.4.1/src/netif/ethernetif.c index e240413c59..9d8fa650a4 100644 --- a/components/net/lwip-1.4.1/src/netif/ethernetif.c +++ b/components/net/lwip-1.4.1/src/netif/ethernetif.c @@ -253,6 +253,12 @@ void lwip_netdev_netstat(struct netdev *netif) #endif /* RT_LWIP_TCP || RT_LWIP_UDP */ #endif /* RT_USING_FINSH */ +static int lwip_netdev_set_default(struct netdev *netif) +{ + netif_set_default((struct netif *)netif->user_data); + return ERR_OK; +} + const struct netdev_ops lwip_netdev_ops = { lwip_netdev_set_up, @@ -282,6 +288,8 @@ const struct netdev_ops lwip_netdev_ops = lwip_netdev_netstat, #endif /* RT_LWIP_TCP || RT_LWIP_UDP */ #endif /* RT_USING_FINSH */ + + lwip_netdev_set_default, }; static int netdev_add(struct netif *lwip_netif) diff --git a/components/net/lwip-2.0.2/src/core/dns.c b/components/net/lwip-2.0.2/src/core/dns.c index c793b320a4..cd4de06229 100644 --- a/components/net/lwip-2.0.2/src/core/dns.c +++ b/components/net/lwip-2.0.2/src/core/dns.c @@ -370,13 +370,14 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver) dns_servers[numdns] = (*dnsserver); #ifdef RT_USING_NETDEV - extern struct netif *netif_default; + extern struct netif *netif_list; extern struct netdev *netdev_get_by_name(const char *name); extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); + struct netif *netif = NULL; /* set network interface device DNS server address */ - if (netif_default) { - netdev_low_level_set_dns_server(netdev_get_by_name(netif_default->name), numdns, dnsserver); + for (netif = netif_list; netif != NULL; netif = netif->next) { + netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver); } #endif /* RT_USING_NETDEV */ } else { diff --git a/components/net/lwip-2.0.2/src/netif/ethernetif.c b/components/net/lwip-2.0.2/src/netif/ethernetif.c index 6a1d71886c..a7bed3065f 100644 --- a/components/net/lwip-2.0.2/src/netif/ethernetif.c +++ b/components/net/lwip-2.0.2/src/netif/ethernetif.c @@ -261,6 +261,12 @@ void lwip_netdev_netstat(struct netdev *netif) #endif /* RT_LWIP_TCP || RT_LWIP_UDP */ #endif /* RT_USING_FINSH */ +static int lwip_netdev_set_default(struct netdev *netif) +{ + netif_set_default((struct netif *)netif->user_data); + return ERR_OK; +} + const struct netdev_ops lwip_netdev_ops = { lwip_netdev_set_up, @@ -290,6 +296,8 @@ const struct netdev_ops lwip_netdev_ops = lwip_netdev_netstat, #endif /* RT_LWIP_TCP || RT_LWIP_UDP */ #endif /* RT_USING_FINSH */ + + lwip_netdev_set_default, }; static int netdev_add(struct netif *lwip_netif) diff --git a/components/net/lwip-2.1.0/src/core/dns.c b/components/net/lwip-2.1.0/src/core/dns.c index 5129b7f3bc..c688cb2205 100644 --- a/components/net/lwip-2.1.0/src/core/dns.c +++ b/components/net/lwip-2.1.0/src/core/dns.c @@ -367,13 +367,14 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver) dns_servers[numdns] = (*dnsserver); #ifdef RT_USING_NETDEV - extern struct netif *netif_default; + extern struct netif *netif_list; extern struct netdev *netdev_get_by_name(const char *name); extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); + struct netif *netif = NULL; /* set network interface device DNS server address */ - if (netif_default) { - netdev_low_level_set_dns_server(netdev_get_by_name(netif_default->name), numdns, dnsserver); + for (netif = netif_list; netif != NULL; netif = netif->next) { + netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver); } #endif /* RT_USING_NETDEV */ } else { diff --git a/components/net/lwip-2.1.0/src/netif/ethernetif.c b/components/net/lwip-2.1.0/src/netif/ethernetif.c index 1725ce00bb..66ea1d2376 100755 --- a/components/net/lwip-2.1.0/src/netif/ethernetif.c +++ b/components/net/lwip-2.1.0/src/netif/ethernetif.c @@ -262,6 +262,12 @@ void lwip_netdev_netstat(struct netdev *netif) #endif /* RT_LWIP_TCP || RT_LWIP_UDP */ #endif /* RT_USING_FINSH */ +static int lwip_netdev_set_default(struct netdev *netif) +{ + netif_set_default((struct netif *)netif->user_data); + return ERR_OK; +} + const struct netdev_ops lwip_netdev_ops = { lwip_netdev_set_up, @@ -291,6 +297,8 @@ const struct netdev_ops lwip_netdev_ops = lwip_netdev_netstat, #endif /* RT_LWIP_TCP || RT_LWIP_UDP */ #endif /* RT_USING_FINSH */ + + lwip_netdev_set_default, }; static int netdev_add(struct netif *lwip_netif) diff --git a/components/net/netdev/include/netdev.h b/components/net/netdev/include/netdev.h index 1a61cba1c2..e11a8929b0 100644 --- a/components/net/netdev/include/netdev.h +++ b/components/net/netdev/include/netdev.h @@ -137,6 +137,9 @@ struct netdev_ops int (*ping)(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp); void (*netstat)(struct netdev *netdev); #endif + + /* set default network interface device in current network stack*/ + int (*set_default)(struct netdev *netdev); }; /* The network interface device registered and unregistered*/ diff --git a/components/net/netdev/src/netdev.c b/components/net/netdev/src/netdev.c index 451cc81025..68e5364a9e 100644 --- a/components/net/netdev/src/netdev.c +++ b/components/net/netdev/src/netdev.c @@ -34,11 +34,11 @@ struct netdev *netdev_default; /** * This function will register network interface device and * add it to network interface device list. - * + * * @param netdev the network interface device object * @param name the network interface device name * @param user_data user-specific data - * + * * @return 0: registered successfully * -1: registered failed */ @@ -105,9 +105,9 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data) /** * This function will unregister network interface device and * delete it from network interface device list. - * + * * @param netdev the network interface device object - * + * * @return 0: unregistered successfully * -1: unregistered failed */ @@ -164,11 +164,11 @@ int netdev_unregister(struct netdev *netdev) /** * This function will get the first network interface device * with the flags in network interface device list. - * + * * @param flags the network interface device flags - * + * * @return != NULL: network interface device object - * NULL: get failed + * NULL: get failed */ struct netdev *netdev_get_first_by_flags(uint16_t flags) { @@ -201,11 +201,11 @@ struct netdev *netdev_get_first_by_flags(uint16_t flags) /** * This function will get the first network interface device * in network interface device list by IP address. - * + * * @param addr the network interface device IP address - * + * * @return != NULL: network interface device object - * NULL: get failed + * NULL: get failed */ struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr) { @@ -238,11 +238,11 @@ struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr) /** * This function will get network interface device * in network interface device list by netdev name. - * + * * @param name the network interface device name - * + * * @return != NULL: network interface device object - * NULL: get failed + * NULL: get failed */ struct netdev *netdev_get_by_name(const char *name) { @@ -276,11 +276,11 @@ struct netdev *netdev_get_by_name(const char *name) /** * This function will get the first network interface device * in network interface device list by protocol family type. - * + * * @param family the network interface device protocol family type - * + * * @return != NULL: network interface device object - * NULL: get failed + * NULL: get failed */ struct netdev *netdev_get_by_family(int family) { @@ -325,15 +325,15 @@ struct netdev *netdev_get_by_family(int family) /** * This function will get the family type from network interface device - * + * * @param netdev network interface device object - * + * * @return the network interface device family type */ int netdev_family_get(struct netdev *netdev) { - RT_ASSERT(netdev); - + RT_ASSERT(netdev); + return ((struct sal_proto_family *)netdev->sal_user_data)->family; } @@ -341,7 +341,7 @@ int netdev_family_get(struct netdev *netdev) /** * This function will set default network interface device. - * + * * @param netdev the network interface device to change */ void netdev_set_default(struct netdev *netdev) @@ -349,15 +349,21 @@ void netdev_set_default(struct netdev *netdev) if (netdev) { netdev_default = netdev; - LOG_D("Setting default network interface device name(%s) successfully.", netdev->name); + + if (netdev->ops->set_default) + { + /* set default network interface device in the current network stack */ + netdev->ops->set_default(netdev); + } + LOG_D("Setting default network interface device name(%s) successfully.", netdev->name); } } /** * This function will enable network interface device . - * + * * @param netdev the network interface device to change - * + * * @return 0: set status successfully * -1: set status failed */ @@ -370,7 +376,7 @@ int netdev_set_up(struct netdev *netdev) LOG_E("The network interface device(%s) not support to set status.", netdev->name); return -RT_ERROR; } - + /* network interface device status flags check */ if (netdev_is_up(netdev)) { @@ -382,9 +388,9 @@ int netdev_set_up(struct netdev *netdev) } /** * This function will disable network interface device. - * + * * @param netdev the network interface device to change - * + * * @return 0: set status successfully * -1: set sttaus failed */ @@ -397,7 +403,7 @@ int netdev_set_down(struct netdev *netdev) LOG_E("The network interface device(%s) not support to set status.", netdev->name); return -RT_ERROR; } - + /* network interface device status flags check */ if (!netdev_is_up(netdev)) { @@ -410,10 +416,10 @@ int netdev_set_down(struct netdev *netdev) /** * This function will control network interface device DHCP capability enable or disable. - * + * * @param netdev the network interface device device to change * @param is_enable the new DHCP status - * + * * @return 0: set DHCP status successfully * -1: set DHCP status failed */ @@ -432,17 +438,17 @@ int netdev_dhcp_enabled(struct netdev *netdev, rt_bool_t is_enabled) { return RT_EOK; } - + /* execute network interface device DHCP capability control operations */ return netdev->ops->set_dhcp(netdev, is_enabled); } /** * This function will set network interface device IP address. - * + * * @param netdev the network interface device to change * @param ipaddr the new IP address - * + * * @return 0: set IP address successfully * -1: set IP address failed */ @@ -456,7 +462,7 @@ int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr) LOG_E("The network interface device(%s) not support to set IP address.", netdev->name); return -RT_ERROR; } - + if (netdev_is_dhcp_enabled(netdev)) { LOG_E("The network interface device(%s) DHCP capability is enable, not support set IP address.", netdev->name); @@ -469,10 +475,10 @@ int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr) /** * This function will set network interface device netmask address. - * + * * @param netdev the network interface device to change * @param netmask the new netmask address - * + * * @return 0: set netmask address successfully * -1: set netmask address failed */ @@ -486,7 +492,7 @@ int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask) LOG_E("The network interface device(%s) not support to set netmask address.", netdev->name); return -RT_ERROR; } - + if (netdev_is_dhcp_enabled(netdev)) { LOG_E("The network interface device(%s) DHCP capability is enable, not support set netmask address.", netdev->name); @@ -499,10 +505,10 @@ int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask) /** * This function will set network interface device gateway address. - * + * * @param netdev the network interface device to change - * @param gateway the new gateway address - * + * @param gateway the new gateway address + * * @return 0: set gateway address successfully * -1: set gateway address failed */ @@ -516,7 +522,7 @@ int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw) LOG_E("The network interface device(%s) not support to set gateway address.", netdev->name); return -RT_ERROR; } - + if (netdev_is_dhcp_enabled(netdev)) { LOG_E("The network interface device(%s) DHCP capability is enable, not support set gateway address.", netdev->name); @@ -529,10 +535,10 @@ int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw) /** * This function will set network interface device DNS server address. - * + * * @param netdev the network interface device to change * @param dns_server the new DNS server address - * + * * @return 0: set netmask address successfully * -1: set netmask address failed */ @@ -559,7 +565,7 @@ int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_ /** * This function will set callback to be called when the network interface device status has been changed. - * + * * @param netdev the network interface device to change * @param status_callback the callback be called when the status has been changed. */ @@ -573,7 +579,7 @@ void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status /** * This function will set callback to be called when the network interface device address has been changed. - * + * * @param netdev the network interface device to change * @param addr_callback the callback be called when the address has been changed. */ @@ -589,7 +595,7 @@ void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_cal /** * This function will set network interface device IP address. * @NOTE it can only be called in the network interface device driver. - * + * * @param netdev the network interface device to change * @param ipaddr the new IP address */ @@ -620,7 +626,7 @@ void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr /** * This function will set network interface device netmask address. * @NOTE it can only be called in the network interface device driver. - * + * * @param netdev the network interface device to change * @param netmask the new netmask address */ @@ -634,7 +640,7 @@ void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmas #ifdef RT_USING_SAL /* set network interface device flags to internet up */ - if (netdev_is_up(netdev) && netdev_is_link_up(netdev) && + if (netdev_is_up(netdev) && netdev_is_link_up(netdev) && !ip_addr_isany(&(netdev->ip_addr))) { sal_check_netdev_internet_up(netdev); @@ -652,7 +658,7 @@ void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmas /** * This function will set network interface device gateway address. * @NOTE it can only be called in the network interface device driver. - * + * * @param netdev the network interface device to change * @param gateway the new gateway address */ @@ -666,7 +672,7 @@ void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw) #ifdef RT_USING_SAL /* set network interface device flags to internet up */ - if (netdev_is_up(netdev) && netdev_is_link_up(netdev) && + if (netdev_is_up(netdev) && netdev_is_link_up(netdev) && !ip_addr_isany(&(netdev->ip_addr))) { sal_check_netdev_internet_up(netdev); @@ -684,10 +690,10 @@ void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw) /** * This function will set network interface device DNS server address. * @NOTE it can only be called in the network interface device driver. - * + * * @param netdev the network interface device to change * @param dns_server the new DNS server address - * + * */ void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server) { @@ -740,7 +746,7 @@ static void netdev_auto_change_default(struct netdev *netdev) /** * This function will set network interface device status. * @NOTE it can only be called in the network interface device driver. - * + * * @param netdev the network interface device to change * @param is_up the new status */ @@ -773,14 +779,14 @@ void netdev_low_level_set_status(struct netdev *netdev, rt_bool_t is_up) /** * This function will set network interface device active link status. * @NOTE it can only be called in the network interface device driver. - * + * * @param netdev the network interface device to change * @param is_up the new link status */ void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up) { if (netdev && netdev_is_link_up(netdev) != is_up) - { + { if (is_up) { netdev->flags |= NETDEV_FLAG_LINK_UP; @@ -796,7 +802,7 @@ void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up) else { netdev->flags &= ~NETDEV_FLAG_LINK_UP; - + /* set network interface device flags to internet down */ netdev->flags &= ~NETDEV_FLAG_INTERNET_UP; @@ -817,7 +823,7 @@ void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up) /** * This function will set network interface device DHCP status. * @NOTE it can only be called in the network interface device driver. - * + * * @param netdev the network interface device to change * @param is_up the new DHCP status */ @@ -883,13 +889,13 @@ static void netdev_list_if(void) } else if (netdev->hwaddr_len == NETDEV_IFCONFIG_IEMI_MAX_LEN) { - rt_kprintf("IEMI: "); + rt_kprintf("IMEI: "); for (index = 0; index < netdev->hwaddr_len; index++) { /* two numbers are displayed at one time*/ if (netdev->hwaddr[index] < 10 && index != netdev->hwaddr_len - 1) rt_kprintf("0"); - + rt_kprintf("%d", netdev->hwaddr[index]); } } @@ -915,9 +921,9 @@ static void netdev_list_if(void) { ip_addr_t *addr; int i; - + addr = &netdev->ip6_addr[0]; - + if (!ip_addr_isany(addr)) { rt_kprintf("ipv6 link-local: %s %s\n", inet_ntoa(*addr), @@ -929,7 +935,7 @@ static void netdev_list_if(void) rt_kprintf("ipv6[%d] address: %s %s\n", i, inet_ntoa(*addr), !ip_addr_isany(addr) ? "VALID" : "INVALID"); } - } + } } #endif /* NETDEV_IPV6 */ @@ -937,7 +943,7 @@ static void netdev_list_if(void) { rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index])); } - + if (rt_slist_next(node)) { rt_kprintf("\n"); @@ -1016,7 +1022,7 @@ int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size) struct netdev *netdev = RT_NULL; struct netdev_ping_resp ping_resp; int index, ret = 0; - + if (size == 0) { size = NETDEV_PING_DATA_SIZE; @@ -1031,20 +1037,34 @@ int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size) { /* using first internet up status network interface device */ netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP); - if (netdev == RT_NULL || NETDEV_PING_IS_COMMONICABLE(netdev) == 0) + if (netdev == RT_NULL) + { + rt_kprintf("ping: not found available network interface device.\n"); + return -RT_ERROR; + } + else if (netdev->ops == RT_NULL || netdev->ops->ping == RT_NULL) + { + rt_kprintf("ping: network interface device(%s) not support ping feature.\n", netdev->name); + return -RT_ERROR; + } + else if (!netdev_is_up(netdev) || !netdev_is_link_up(netdev)) { - rt_kprintf("ping: network interface device get error.\n"); + rt_kprintf("ping: network interface device(%s) status error.\n", netdev->name); return -RT_ERROR; } } for (index = 0; index < times; index++) { + int delay_tick = 0; + rt_tick_t start_tick = 0; + rt_memset(&ping_resp, 0x00, sizeof(struct netdev_ping_resp)); + start_tick = rt_tick_get(); ret = netdev->ops->ping(netdev, (const char *)target_name, size, NETDEV_PING_RECV_TIMEO, &ping_resp); if (ret == -RT_ETIMEOUT) { - rt_kprintf("ping: from %s icmp_seq=%d timeout\n", + rt_kprintf("ping: from %s icmp_seq=%d timeout\n", (ip_addr_isany(&(ping_resp.ip_addr))) ? target_name : inet_ntoa(ping_resp.ip_addr), index); } else if (ret == -RT_ERROR) @@ -1057,17 +1077,19 @@ int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size) { if (ping_resp.ttl == 0) { - rt_kprintf("%d bytes from %s icmp_seq=%d time=%d ms\n", + rt_kprintf("%d bytes from %s icmp_seq=%d time=%d ms\n", ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index, ping_resp.ticks); } else { - rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", + rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index, ping_resp.ttl, ping_resp.ticks); } } - - rt_thread_mdelay(NETDEV_PING_DELAY); + + /* if the response time is more than NETDEV_PING_DELAY, no nead to delay */ + delay_tick = ((rt_tick_get() - start_tick) > NETDEV_PING_DELAY) || (index == times) ? 0 : NETDEV_PING_DELAY; + rt_thread_delay(delay_tick); } return RT_EOK; @@ -1107,7 +1129,7 @@ static void netdev_list_dns(void) { rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index])); } - + if (rt_slist_next(node)) { rt_kprintf("\n"); @@ -1128,9 +1150,10 @@ static void netdev_set_dns(char *netdev_name, uint8_t dns_num, char *dns_server) } inet_aton(dns_server, &dns_addr); - netdev_set_dns_server(netdev, dns_num, &dns_addr); - - rt_kprintf("set network interface device(%s) dns server #0: %s\n", netdev_name, dns_server); + if (netdev_set_dns_server(netdev, dns_num, &dns_addr) == RT_EOK) + { + rt_kprintf("set network interface device(%s) dns server #%d: %s\n", netdev_name, dns_num, dns_server); + } } int netdev_dns(int argc, char **argv) @@ -1196,7 +1219,7 @@ int netdev_netstat(int argc, char **argv) { rt_kprintf("Please input: netstat \n"); } - else + else { netdev_cmd_netstat(); } diff --git a/components/net/sal_socket/socket/net_sockets.c b/components/net/sal_socket/socket/net_sockets.c index 12024c8173..a53b2f1f9c 100644 --- a/components/net/sal_socket/socket/net_sockets.c +++ b/components/net/sal_socket/socket/net_sockets.c @@ -105,9 +105,7 @@ int shutdown(int s, int how) rt_set_errno(-ENOTSOCK); error = -1; } - - /* socket has been closed, delete it from file system fd */ - fd_put(d); + fd_put(d); return error; diff --git a/components/net/sal_socket/src/sal_socket.c b/components/net/sal_socket/src/sal_socket.c index 44442d306f..2d8e703845 100644 --- a/components/net/sal_socket/src/sal_socket.c +++ b/components/net/sal_socket/src/sal_socket.c @@ -94,12 +94,12 @@ do { * SAL (Socket Abstraction Layer) initialize. * * @return result 0: initialize success - * -1: initialize failed + * -1: initialize failed */ int sal_init(void) { int cn; - + if (init_ok) { LOG_D("Socket Abstraction Layer is already initialized."); @@ -115,7 +115,7 @@ int sal_init(void) LOG_E("No memory for socket table.\n"); return -1; } - + /* create sal socket lock */ rt_mutex_init(&sal_core_lock, "sal_lock", RT_IPC_FLAG_FIFO); @@ -148,7 +148,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data) char send_data[SAL_INTERNET_BUFF_LEN], recv_data = 0; struct rt_delayed_work *delay_work = (struct rt_delayed_work *)work; - const char month[][SAL_INTERNET_MONTH_LEN] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; + const char month[][SAL_INTERNET_MONTH_LEN] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; char date[SAL_INTERNET_DATE_LEN]; int moth_num = 0; @@ -175,7 +175,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data) } skt_ops = pf->skt_ops; - if((sockfd = skt_ops->socket(AF_INET, SOCK_DGRAM, 0)) < 0) + if ((sockfd = skt_ops->socket(AF_INET, SOCK_DGRAM, 0)) < 0) { result = -RT_ERROR; goto __exit; @@ -224,7 +224,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data) send_data[11] = RT_REVISION; skt_ops->sendto(sockfd, send_data, SAL_INTERNET_BUFF_LEN, 0, - (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); + (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); result = skt_ops->recvfrom(sockfd, &recv_data, sizeof(recv_data), 0, (struct sockaddr *)&server_addr, &addr_len); if (result < 0) @@ -242,7 +242,7 @@ __exit: if (result > 0) { LOG_D("Set network interface device(%s) internet status up.", netdev->name); - netdev->flags |= NETDEV_FLAG_INTERNET_UP; + netdev->flags |= NETDEV_FLAG_INTERNET_UP; } else { @@ -277,7 +277,7 @@ int sal_check_netdev_internet_up(struct netdev *netdev) rt_delayed_work_init(net_work, check_netdev_internet_up_work, (void *)netdev); rt_work_submit(&(net_work->work), RT_TICK_PER_SECOND); - + return 0; } @@ -316,10 +316,7 @@ struct sal_socket *sal_get_socket(int socket) socket = socket - SAL_SOCKET_OFFSET; /* check socket structure valid or not */ - if (st->sockets[socket]->magic != SAL_SOCKET_MAGIC) - { - return RT_NULL; - } + RT_ASSERT(st->sockets[socket]->magic == SAL_SOCKET_MAGIC); return st->sockets[socket]; } @@ -374,9 +371,10 @@ int sal_netdev_cleanup(struct netdev *netdev) sal_unlock(); if (find_dev) { - rt_thread_mdelay(rt_tick_from_millisecond(100)); + rt_thread_mdelay(100); } - } while (find_dev); + } + while (find_dev); return 0; } @@ -428,7 +426,7 @@ static int socket_init(int family, int type, int protocol, struct sal_socket **r flag = RT_TRUE; } } - + if (flag == RT_FALSE) { /* get network interface device by protocol family */ @@ -452,8 +450,7 @@ static int socket_alloc(struct sal_socket_table *st, int f_socket) /* find an empty socket entry */ for (idx = f_socket; idx < (int) st->max_socket; idx++) { - if (st->sockets[idx] == RT_NULL || - st->sockets[idx]->netdev == RT_NULL) + if (st->sockets[idx] == RT_NULL) { break; } @@ -497,6 +494,15 @@ __result: return idx; } +static void socket_free(struct sal_socket_table *st, int idx) +{ + struct sal_socket *sock; + + sock = st->sockets[idx]; + st->sockets[idx] = RT_NULL; + rt_free(sock); +} + static int socket_new(void) { struct sal_socket *sock; @@ -529,18 +535,38 @@ __result: return idx + SAL_SOCKET_OFFSET; } +static void socket_delete(int socket) +{ + struct sal_socket *sock; + struct sal_socket_table *st = &socket_table; + int idx; + + idx = socket - SAL_SOCKET_OFFSET; + if (idx < 0 || idx >= (int) st->max_socket) + { + return; + } + sal_lock(); + sock = sal_get_socket(socket); + RT_ASSERT(sock != RT_NULL); + sock->magic = 0; + sock->netdev = RT_NULL; + socket_free(st, idx); + sal_unlock(); +} + int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen) { int new_socket; struct sal_socket *sock; - struct sal_proto_family *pf; + struct sal_proto_family *pf; /* get the socket object by socket descriptor */ SAL_SOCKET_OBJ_GET(sock, socket); /* check the network interface socket operations */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, accept); - + new_socket = pf->skt_ops->accept((int) sock->user_data, addr, addrlen); if (new_socket != -1) { @@ -550,18 +576,20 @@ int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen) /* allocate a new socket structure and registered socket options */ new_sal_socket = socket_new(); - if (new_sal_socket < 0) + new_sock = sal_get_socket(new_sal_socket); + if (new_sock == RT_NULL) { pf->skt_ops->closesocket(new_socket); return -1; } - new_sock = sal_get_socket(new_sal_socket); retval = socket_init(sock->domain, sock->type, sock->protocol, &new_sock); if (retval < 0) { pf->skt_ops->closesocket(new_socket); rt_memset(new_sock, 0x00, sizeof(struct sal_socket)); + /* socket init failed, delete socket */ + socket_delete(new_sal_socket); LOG_E("New socket registered failed, return error %d.", retval); return -1; } @@ -587,7 +615,7 @@ static void sal_sockaddr_to_ipaddr(const struct sockaddr *name, ip_addr_t *local #elif NETDEV_IPV6 #error "not only support IPV6" #endif /* NETDEV_IPV4 && NETDEV_IPV6*/ -} +} int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen) { @@ -636,7 +664,7 @@ int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen) sock->user_data = (void *) new_socket; } } - + /* check and get protocol families by the network interface device */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, bind); return pf->skt_ops->bind((int) sock->user_data, name, namelen); @@ -673,9 +701,6 @@ int sal_shutdown(int socket, int how) error = -1; } - /* free socket */ - rt_free(sock); - socket_table.sockets[socket] = RT_NULL; return error; } @@ -791,7 +816,7 @@ int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen) { return -1; } - + return ret; } #endif @@ -814,7 +839,7 @@ int sal_listen(int socket, int backlog) } int sal_recvfrom(int socket, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) + struct sockaddr *from, socklen_t *fromlen) { struct sal_socket *sock; struct sal_proto_family *pf; @@ -831,11 +856,11 @@ int sal_recvfrom(int socket, void *mem, size_t len, int flags, if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recv)) { int ret; - + if ((ret = proto_tls->ops->recv(sock->user_data_tls, mem, len)) < 0) { return -1; - } + } return ret; } else @@ -848,7 +873,7 @@ int sal_recvfrom(int socket, void *mem, size_t len, int flags, } int sal_sendto(int socket, const void *dataptr, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen) + const struct sockaddr *to, socklen_t tolen) { struct sal_socket *sock; struct sal_proto_family *pf; @@ -865,11 +890,11 @@ int sal_sendto(int socket, const void *dataptr, size_t size, int flags, if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, send)) { int ret; - + if ((ret = proto_tls->ops->send(sock->user_data_tls, dataptr, size)) < 0) { return -1; - } + } return ret; } else @@ -907,6 +932,7 @@ int sal_socket(int domain, int type, int protocol) if (retval < 0) { LOG_E("SAL socket protocol family input failed, return error %d.", retval); + socket_delete(socket); return -1; } @@ -922,6 +948,7 @@ int sal_socket(int domain, int type, int protocol) sock->user_data_tls = proto_tls->ops->socket(socket); if (sock->user_data_tls == RT_NULL) { + socket_delete(socket); return -1; } } @@ -964,9 +991,8 @@ int sal_closesocket(int socket) error = -1; } - /* free socket */ - rt_free(sock); - socket_table.sockets[socket] = RT_NULL; + /* delete socket */ + socket_delete(socket); return error; } @@ -1027,7 +1053,7 @@ struct hostent *sal_gethostbyname(const char *name) } int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf, - size_t buflen, struct hostent **result, int *h_errnop) + size_t buflen, struct hostent **result, int *h_errnop) { struct netdev *netdev = netdev_default; struct sal_proto_family *pf; @@ -1050,9 +1076,9 @@ int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf, } int sal_getaddrinfo(const char *nodename, - const char *servname, - const struct addrinfo *hints, - struct addrinfo **res) + const char *servname, + const struct addrinfo *hints, + struct addrinfo **res) { struct netdev *netdev = netdev_default; struct sal_proto_family *pf; diff --git a/components/utilities/Kconfig b/components/utilities/Kconfig index 250239aea6..9a50512989 100644 --- a/components/utilities/Kconfig +++ b/components/utilities/Kconfig @@ -146,7 +146,6 @@ config RT_USING_ULOG config ULOG_TIME_USING_TIMESTAMP bool "Enable timestamp format for time." default n - select RT_USING_LIBC depends on ULOG_OUTPUT_TIME config ULOG_OUTPUT_LEVEL diff --git a/components/utilities/ulog/backend/console_be.c b/components/utilities/ulog/backend/console_be.c index 04b0d91add..95dd547426 100644 --- a/components/utilities/ulog/backend/console_be.c +++ b/components/utilities/ulog/backend/console_be.c @@ -22,9 +22,9 @@ static struct ulog_backend console; void ulog_console_backend_output(struct ulog_backend *backend, rt_uint32_t level, const char *tag, rt_bool_t is_raw, const char *log, size_t len) { +#ifdef RT_USING_DEVICE rt_device_t dev = rt_console_get_device(); -#ifdef RT_USING_DEVICE if (dev == RT_NULL) { rt_hw_console_output(log); diff --git a/components/utilities/utest/utest.c b/components/utilities/utest/utest.c index f59f97bb64..6500ae2fbe 100644 --- a/components/utilities/utest/utest.c +++ b/components/utilities/utest/utest.c @@ -63,20 +63,20 @@ void utest_log_lv_set(rt_uint8_t lv) int utest_init(void) { /* initialize the utest commands table.*/ -#if defined(__CC_ARM) /* ARM C Compiler */ +#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM C Compiler */ extern const int UtestTcTab$$Base; extern const int UtestTcTab$$Limit; tc_table = (utest_tc_export_t)&UtestTcTab$$Base; tc_num = (utest_tc_export_t)&UtestTcTab$$Limit - tc_table; -#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */ +#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */ tc_table = (utest_tc_export_t)__section_begin("UtestTcTab"); tc_num = (utest_tc_export_t)__section_end("UtestTcTab") - tc_table; -#elif defined (__GNUC__) /* for GCC Compiler */ +#elif defined (__GNUC__) /* for GCC Compiler */ extern const int __rt_utest_tc_tab_start; extern const int __rt_utest_tc_tab_end; tc_table = (utest_tc_export_t)&__rt_utest_tc_tab_start; tc_num = (utest_tc_export_t) &__rt_utest_tc_tab_end - tc_table; -#endif /* defined(__CC_ARM) */ +#endif LOG_I("utest is initialize success."); LOG_I("total utest testcase num: (%d)", tc_num); @@ -215,7 +215,7 @@ static void utest_run(const char *utest_name) i++; } - if (i == tc_num && is_find == RT_FALSE) + if (i == tc_num && is_find == RT_FALSE && utest_name != RT_NULL) { LOG_I("[==========] [ utest ] Not find (%s)", utest_name); LOG_I("[==========] [ utest ] finished"); |
