From 8f9f2300af52797756f22bc26b390571e7b191a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A6=8F=E6=98=8E?= Date: Thu, 21 Jul 2022 17:04:00 +0800 Subject: [PATCH] IssueID:1919:improve PWM and ADC driver framework [Detail] Improve PWM driver framework. Improve ADC driver framework. New VFS support. Userspace support. [Verified Cases] Build Pass: helloworld_demo@haaseduk1 Test Pass: helloworld_demo@haaseduk1 --- .../drivers/core/base/include/aos/device.h | 4 +- .../core/base/include/aos/device_core.h | 24 ++- components/drivers/core/base/src/device.c | 83 ++++----- .../drivers/peripheral/adc/include/aos/adc.h | 67 ++++--- .../peripheral/adc/include/aos/adc_core.h | 8 +- .../drivers/peripheral/adc/package.yaml | 22 +-- components/drivers/peripheral/adc/src/adc.c | 167 ++++++++++++++++-- .../drivers/peripheral/pwm/include/aos/pwm.h | 43 +++-- .../peripheral/pwm/include/aos/pwm_core.h | 8 +- .../drivers/peripheral/pwm/package.yaml | 23 ++- components/drivers/peripheral/pwm/src/pwm.c | 90 ++++++++-- 11 files changed, 369 insertions(+), 170 deletions(-) diff --git a/components/drivers/core/base/include/aos/device.h b/components/drivers/core/base/include/aos/device.h index 1bce5c104d..ced2e2f523 100644 --- a/components/drivers/core/base/include/aos/device.h +++ b/components/drivers/core/base/include/aos/device.h @@ -16,10 +16,10 @@ typedef enum { AOS_DEV_TYPE_WATCHDOG, AOS_DEV_TYPE_ETHERNET, AOS_DEV_TYPE_WLAN, - AOS_DEV_TYPE_BLOCK, + AOS_DEV_TYPE_DISK, + AOS_DEV_TYPE_DISKPART, AOS_DEV_TYPE_FLASH, AOS_DEV_TYPE_FLASHPART, - AOS_DEV_TYPE_MTD, AOS_DEV_TYPE_RTC, AOS_DEV_TYPE_SPI, AOS_DEV_TYPE_I2C, diff --git a/components/drivers/core/base/include/aos/device_core.h b/components/drivers/core/base/include/aos/device_core.h index 6442d220d1..8e03c0035c 100644 --- a/components/drivers/core/base/include/aos/device_core.h +++ b/components/drivers/core/base/include/aos/device_core.h @@ -8,29 +8,22 @@ #include #include #include +#include +#ifdef AOS_COMP_DEVFS +#include +#endif +#if defined(CONFIG_DRV_CORE) && CONFIG_DRV_CORE != 0 #include -#ifdef AOS_COMP_VFS -#include #endif -#include struct aos_dev_ops; -#ifdef AOS_COMP_VFS -#define AOS_DEV_NAME_MAX_LEN 63 - -typedef struct { - char name[AOS_DEV_NAME_MAX_LEN + 1]; - const struct file_ops *ops; -} aos_dev_vfs_helper_t; -#endif - typedef struct aos_dev { aos_dev_type_t type; uint32_t id; const struct aos_dev_ops *ops; -#ifdef AOS_COMP_VFS - aos_dev_vfs_helper_t vfs_helper; +#ifdef AOS_COMP_DEVFS + aos_devfs_node_t devfs_node; #endif struct k_rbtree_node_t rb_node; aos_sem_t rb_sem; @@ -53,6 +46,9 @@ typedef struct aos_dev_ops { extern "C" { #endif +#if !(defined(CONFIG_DRV_CORE) && CONFIG_DRV_CORE != 0) +aos_status_t aos_dev_core_init(void); +#endif aos_status_t aos_dev_register(aos_dev_t *dev); aos_status_t aos_dev_unregister(aos_dev_type_t type, uint32_t id); aos_status_t aos_dev_ref(aos_dev_ref_t *ref, aos_dev_t *dev); diff --git a/components/drivers/core/base/src/device.c b/components/drivers/core/base/src/device.c index 771d624b09..c83fe2fcc2 100644 --- a/components/drivers/core/base/src/device.c +++ b/components/drivers/core/base/src/device.c @@ -2,7 +2,6 @@ * Copyright (C) 2020-2021 Alibaba Group Holding Limited */ -#include #include #define REF_COUNT_PENDING UINT32_MAX @@ -11,6 +10,24 @@ static struct k_rbtree_root_t device_map = RBT_ROOT; static aos_mutex_t device_map_mutex; +static aos_status_t device_core_init(void) +{ + return aos_mutex_new(&device_map_mutex); +} + +#if defined(CONFIG_DRV_CORE) && CONFIG_DRV_CORE != 0 +static int dev_core_init(void) +{ + return (int)device_core_init(); +} +CORE_DRIVER_ENTRY(dev_core_init) +#else +aos_status_t aos_dev_core_init(void) +{ + return device_core_init(); +} +#endif + static void device_map_lock(void) { (void)aos_mutex_lock(&device_map_mutex, AOS_WAIT_FOREVER); @@ -96,37 +113,6 @@ static void remove_device(aos_dev_t *dev) k_rbtree_erase(&dev->rb_node, &device_map); } -#ifdef AOS_COMP_VFS -static aos_status_t add_to_vfs(aos_dev_t *dev) -{ - const char prefix[] = "/dev/"; - char path[sizeof(prefix) - 1 + sizeof(dev->vfs_helper.name)]; - - if (dev->vfs_helper.name[0] == '\0' || !dev->vfs_helper.ops) - return 0; - - memcpy(path, prefix, sizeof(prefix) - 1); - strncpy(&path[sizeof(prefix) - 1], dev->vfs_helper.name, sizeof(dev->vfs_helper.name) - 1); - path[sizeof(path) - 1] = '\0'; - - return aos_register_driver(path, dev->vfs_helper.ops, dev); -} - -static void remove_from_vfs(aos_dev_t *dev) -{ - const char prefix[] = "/dev/"; - char path[sizeof(prefix) - 1 + sizeof(dev->vfs_helper.name)]; - - if (dev->vfs_helper.name[0] == '\0' || !dev->vfs_helper.ops) - return; - - memcpy(path, prefix, sizeof(prefix) - 1); - strncpy(&path[sizeof(prefix) - 1], dev->vfs_helper.name, sizeof(dev->vfs_helper.name) - 1); - path[sizeof(path) - 1] = '\0'; - (void)aos_unregister_driver(path); -} -#endif /* AOS_COMP_VFS */ - aos_status_t aos_dev_register(aos_dev_t *dev) { aos_status_t ret; @@ -157,15 +143,17 @@ aos_status_t aos_dev_register(aos_dev_t *dev) insert_device(dev); device_map_unlock(); -#ifdef AOS_COMP_VFS - ret = add_to_vfs(dev); - if (ret) { - device_map_lock(); - remove_device(dev); - device_map_unlock(); - aos_mutex_free(&dev->mutex); - aos_sem_free(&dev->rb_sem); - return ret; +#ifdef AOS_COMP_DEVFS + if (aos_devfs_node_is_valid(&dev->devfs_node)) { + ret = aos_devfs_add_node(&dev->devfs_node); + if (ret) { + device_map_lock(); + remove_device(dev); + device_map_unlock(); + aos_mutex_free(&dev->mutex); + aos_sem_free(&dev->rb_sem); + return ret; + } } #endif @@ -179,7 +167,6 @@ aos_status_t aos_dev_register(aos_dev_t *dev) aos_status_t aos_dev_unregister(aos_dev_type_t type, uint32_t id) { aos_dev_t *dev; - aos_status_t ret; device_map_lock(); dev = find_device(type, id); @@ -206,8 +193,9 @@ aos_status_t aos_dev_unregister(aos_dev_type_t type, uint32_t id) aos_dev_unlock(dev); device_allow_removal(dev); -#ifdef AOS_COMP_VFS - remove_from_vfs(dev); +#ifdef AOS_COMP_DEVFS + if (aos_devfs_node_is_valid(&dev->devfs_node)) + (void)aos_devfs_remove_node(&dev->devfs_node); #endif device_map_lock(); device_wait_removal(dev); @@ -302,10 +290,3 @@ void aos_dev_put(aos_dev_ref_t *ref) aos_dev_unlock(ref->dev); aos_dev_ref_init(ref); } - -static int device_core_init(void) -{ - return (int)aos_mutex_new(&device_map_mutex); -} - -CORE_DRIVER_ENTRY(device_core_init) diff --git a/components/drivers/peripheral/adc/include/aos/adc.h b/components/drivers/peripheral/adc/include/aos/adc.h index 9f5b218405..a54060d510 100644 --- a/components/drivers/peripheral/adc/include/aos/adc.h +++ b/components/drivers/peripheral/adc/include/aos/adc.h @@ -2,39 +2,61 @@ * Copyright (C) 2021 Alibaba Group Holding Limited */ -#ifndef _AOS_ADC_H -#define _AOS_ADC_H +#ifndef AOS_ADC_H +#define AOS_ADC_H -#include -#include +#ifdef AOS_KERNEL_BUILD #include - -#ifdef __cplusplus -extern "C" { +#else +#include #endif -/** @defgroup driver_api driver - * @ingroup aos_components - * @{ - */ - -/** @} */ - /** - * @defgroup aos_adc_app ADC + * @defgroup adc_api ADC * @ingroup driver_api - * 给应用提供ADC操作的AOS API. - * + * @brief AOS API for ADC. * @{ */ -typedef aos_dev_ref_t aos_adc_ref_t; /**< ADC设备的引用 */ - typedef enum { AOS_ADC_MODE_SINGLE, /**< 单次采样模式 */ AOS_ADC_MODE_CONTINUE, /**< 连续采样模式 */ } aos_adc_mode_t; +#if (defined(AOS_KERNEL_BUILD) && defined(AOS_COMP_DEVFS)) || !defined(AOS_KERNEL_BUILD) + +typedef struct { + int32_t channel; + uint32_t time; +} aos_adc_set_sample_time_args_t; + +typedef struct { + int32_t channel; + uint32_t range; +} aos_adc_get_range_args_t; + +typedef struct { + int32_t channel; + int32_t data; +} aos_adc_read_args_t; + +#define AOS_ADC_IOC_SET_SAMPLE_TIME 0x4101 +#define AOS_ADC_IOC_SET_MODE 0x4102 +#define AOS_ADC_IOC_GET_RESOLUTION 0x4103 +#define AOS_ADC_IOC_GET_RANGE 0x4104 +#define AOS_ADC_IOC_READ 0x4105 +#define AOS_ADC_IOC_READ_VOLTAGE 0x4106 + +#endif /* (defined(AOS_KERNEL_BUILD) && defined(AOS_COMP_DEVFS)) || !defined(AOS_KERNEL_BUILD) */ + +#ifdef AOS_KERNEL_BUILD + +typedef aos_dev_ref_t aos_adc_ref_t; /**< ADC设备的引用 */ + +#ifdef __cplusplus +extern "C" { +#endif + /** * 获取一个ADC设备的引用 * @@ -120,9 +142,12 @@ aos_status_t aos_adc_read(aos_adc_ref_t *ref, int32_t channel, int32_t *data); */ aos_status_t aos_adc_read_voltage(aos_adc_ref_t *ref, int32_t channel, int32_t *data); -/** @} */ #ifdef __cplusplus } #endif -#endif /* _AOS_ADC_H */ +#endif /* AOS_KERNEL_BUILD */ + +/** @} */ + +#endif /* AOS_ADC_H */ diff --git a/components/drivers/peripheral/adc/include/aos/adc_core.h b/components/drivers/peripheral/adc/include/aos/adc_core.h index c9d538190b..1c92e2bbc6 100644 --- a/components/drivers/peripheral/adc/include/aos/adc_core.h +++ b/components/drivers/peripheral/adc/include/aos/adc_core.h @@ -2,11 +2,9 @@ * Copyright (C) 2021 Alibaba Group Holding Limited */ -#ifndef _AOS_ADC_CORE_H -#define _AOS_ADC_CORE_H +#ifndef AOS_ADC_CORE_H +#define AOS_ADC_CORE_H -#include -#include #include #include @@ -84,4 +82,4 @@ aos_status_t aos_adc_unregister(uint32_t id); } #endif -#endif /* _AOS_ADC_CORE_H */ +#endif /* AOS_ADC_CORE_H */ diff --git a/components/drivers/peripheral/adc/package.yaml b/components/drivers/peripheral/adc/package.yaml index 6d8db33521..18d0df213c 100644 --- a/components/drivers/peripheral/adc/package.yaml +++ b/components/drivers/peripheral/adc/package.yaml @@ -1,13 +1,12 @@ - ## 第一部分: 基础信息 name: adc # <必选项> 包名称 (符合C语言变量命名规则),长度少于等于64字节 -version: master # <必选项> 组件版本号 -description: ADC 通用驱动 # <必选项> 建议至少20字以上 +version: master # <必选项> 组件版本号 +description: ADC通用驱动 # <必选项> 建议至少20字以上 type: common # <必选项> 组件类型,为:solution, chip, board, common, sdk tag: 第三方驱动 # <可选项> 组件分类,缺省值: '' keywords: # <可选项> 标签,会影响到组件被搜索的效果,合理的标签很重要 - - adc core and vfs driver + - adc driver license: Apache license v2.0 # <可选项> 源代码的许可证,要确保所有代码、文件的许可证不冲突。如:MIT,Apache license v2.0,BSD ## 第二部分:依赖信息 @@ -18,7 +17,7 @@ license: Apache license v2.0 # <可选项> 源代码的 # - aos: >=v7.2.0 depends: - base: master - - vfs: master + - csi: master ? ## 第四部分:编译连接信息 # build_config: # <可选项> 编译配置项 @@ -47,11 +46,8 @@ build_config: # source_file: # <可选项> 指定参与编译的源代码文件,支持通配符,采用相对路径 # - src/*.c # 例:组件 src 目录下所有的扩展名为 c 的源代码文件 source_file: - -# ADC - - src/adc_dev.c ? - - src/adc.c ? - - src/adc_csi.c ? + - src/adc.c + - src/adc_csi.c ? ## 第五部分:配置信息 # def_config: # 组件的可配置项 @@ -59,8 +55,7 @@ source_file: # CONFIG_PARAM_NOT_CHECK: y # CONFIG_CLI: y def_config: - CONFIG_U_ADC_DEV: 1 # ADC device node named witch "/dev/adc[x]" - CONFIG_U_ADC_CORE: 0 # ADC subsys AOS API driver + AOS_COMP_ADC: 1 ## 第六部分:安装信息 # install: @@ -68,8 +63,9 @@ def_config: # source: # 安装源列表 # - src/*.h # 支持通配符,相对路径 install: - - dest: "include/devices" + - dest: "include/aos" source: + - "include/aos/adc.h" ## 第七部分:导出部分 # export: diff --git a/components/drivers/peripheral/adc/src/adc.c b/components/drivers/peripheral/adc/src/adc.c index fe57147a07..12b4c84662 100644 --- a/components/drivers/peripheral/adc/src/adc.c +++ b/components/drivers/peripheral/adc/src/adc.c @@ -2,13 +2,11 @@ * Copyright (C) 2021 Alibaba Group Holding Limited */ -#include -#include -#include -#include -#include -#include #include +#ifdef AOS_COMP_DEVFS +#include +#include +#endif #define AOS_ADC_CHECK_NULL(x) \ do { \ @@ -166,10 +164,155 @@ static const aos_dev_ops_t dev_adc_ops = { .put = dev_adc_put, }; -aos_status_t aos_adc_register(aos_adc_t *adc) +#ifdef AOS_COMP_DEVFS + +static aos_status_t devfs_adc_ioctl(aos_devfs_file_t *file, int cmd, uintptr_t arg) { + aos_adc_ref_t *ref = aos_devfs_file2ref(file); aos_status_t ret; + switch (cmd) { + case AOS_ADC_IOC_SET_SAMPLE_TIME: + { + aos_adc_set_sample_time_args_t args; + if (!aos_devfs_file_is_writable(file)) { + ret = -EPERM; + break; + } + if (!aos_umem_check((const void *)arg, sizeof(args))) { + ret = -EFAULT; + break; + } + if (aos_umem_copy(&args, (const void *)arg, sizeof(args))) { + ret = -EFAULT; + break; + } + ret = aos_adc_set_sample_time(ref, args.channel, args.time); + } + break; + case AOS_ADC_IOC_SET_MODE: + { + aos_adc_mode_t mode; + if (!aos_devfs_file_is_writable(file)) { + ret = -EPERM; + break; + } + if (!aos_umem_check((const void *)arg, sizeof(mode))) { + ret = -EFAULT; + break; + } + if (aos_umem_copy(&mode, (const void *)arg, sizeof(mode))) { + ret = -EFAULT; + break; + } + ret = aos_adc_set_mode(ref, mode); + } + break; + case AOS_ADC_IOC_GET_RESOLUTION: + { + uint32_t resolution; + if (!aos_devfs_file_is_readable(file)) { + ret = -EPERM; + break; + } + ret = aos_adc_get_resolution(ref, &resolution); + if (ret) + break; + if (!aos_umem_check((const void *)arg, sizeof(resolution))) { + ret = -EFAULT; + break; + } + ret = aos_umem_copy((void *)arg, &resolution, sizeof(resolution)) ? -EFAULT : 0; + } + break; + case AOS_ADC_IOC_GET_RANGE: + { + aos_adc_get_range_args_t args; + if (!aos_devfs_file_is_readable(file)) { + ret = -EPERM; + break; + } + if (!aos_umem_check((const void *)arg, sizeof(args))) { + ret = -EFAULT; + break; + } + if (aos_umem_copy(&args, (const void *)arg, sizeof(args))) { + ret = -EFAULT; + break; + } + ret = aos_adc_get_range(ref, args.channel, &args.range); + if (ret) + break; + ret = aos_umem_copy((void *)arg, &args, sizeof(args)) ? -EFAULT : 0; + } + break; + case AOS_ADC_IOC_READ: + { + aos_adc_read_args_t args; + if (!aos_devfs_file_is_readable(file)) { + ret = -EPERM; + break; + } + if (!aos_umem_check((const void *)arg, sizeof(args))) { + ret = -EFAULT; + break; + } + if (aos_umem_copy(&args, (const void *)arg, sizeof(args))) { + ret = -EFAULT; + break; + } + ret = aos_adc_read(ref, args.channel, &args.data); + if (ret) + break; + ret = aos_umem_copy((void *)arg, &args, sizeof(args)) ? -EFAULT : 0; + } + break; + case AOS_ADC_IOC_READ_VOLTAGE: + { + aos_adc_read_args_t args; + if (!aos_devfs_file_is_readable(file)) { + ret = -EPERM; + break; + } + if (!aos_umem_check((const void *)arg, sizeof(args))) { + ret = -EFAULT; + break; + } + if (aos_umem_copy(&args, (const void *)arg, sizeof(args))) { + ret = -EFAULT; + break; + } + ret = aos_adc_read_voltage(ref, args.channel, &args.data); + if (ret) + break; + ret = aos_umem_copy((void *)arg, &args, sizeof(args)) ? -EFAULT : 0; + } + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static const aos_devfs_file_ops_t devfs_adc_ops = { + .ioctl = devfs_adc_ioctl, + .poll = NULL, + .mmap = NULL, + .read = NULL, + .write = NULL, + .lseek = NULL, +}; + +#endif /* AOS_COMP_DEVFS */ + +aos_status_t aos_adc_register(aos_adc_t *adc) +{ +#ifdef AOS_COMP_DEVFS + int name_len; +#endif + AOS_ADC_CHECK_NULL(adc); /* startup/shutdown/read must be set. */ @@ -183,10 +326,12 @@ aos_status_t aos_adc_register(aos_adc_t *adc) adc->dev.type = AOS_DEV_TYPE_ADC; adc->dev.ops = &dev_adc_ops; -#ifdef AOS_COMP_VFS - /* TODO: support vfs ops. */ - adc->dev.vfs_helper.name[0] = '\0'; - adc->dev.vfs_helper.ops = NULL; +#ifdef AOS_COMP_DEVFS + aos_devfs_node_init(&adc->dev.devfs_node); + adc->dev.devfs_node.ops = &devfs_adc_ops; + name_len = snprintf(adc->dev.devfs_node.name, sizeof(adc->dev.devfs_node.name), "adc%" PRIu32, adc->dev.id); + if (name_len < 0 || name_len >= sizeof(adc->dev.devfs_node.name)) + return -EINVAL; #endif return aos_dev_register(&(adc->dev)); diff --git a/components/drivers/peripheral/pwm/include/aos/pwm.h b/components/drivers/peripheral/pwm/include/aos/pwm.h index cbf354f304..a11d3f7a5d 100644 --- a/components/drivers/peripheral/pwm/include/aos/pwm.h +++ b/components/drivers/peripheral/pwm/include/aos/pwm.h @@ -2,25 +2,22 @@ * Copyright (C) 2021 Alibaba Group Holding Limited */ -#ifndef _AOS_PWM_H -#define _AOS_PWM_H +#ifndef AOS_PWM_H +#define AOS_PWM_H -#include -#include +#ifdef AOS_KERNEL_BUILD #include +#else +#include +#endif /** - * @defgroup aos_pwm_app PWM + * @defgroup pwm_api PWM * @ingroup driver_api - * 给应用提供PWM操作的AOS API. - * + * @brief AOS API for PWM. * @{ */ -#ifdef __cplusplus -extern "C" { -#endif - typedef enum { AOS_PWM_POLARITY_NORMAL, AOS_PWM_POLARITY_INVERSE, @@ -32,16 +29,22 @@ typedef struct { aos_pwm_polarity_t polarity; bool enabled; } aos_pwm_attr_t; -/** - * @defgroup aos_pwm_app PWM应用操作 - * @ingroup driver_api - * 给应用提供PWM操作的AOS PWM API. - * - * @{ - */ + +#if (defined(AOS_KERNEL_BUILD) && defined(AOS_COMP_DEVFS)) || !defined(AOS_KERNEL_BUILD) + +#define AOS_PWM_IOC_GET_ATTR 0x5001 +#define AOS_PWM_IOC_SET_ATTR 0x5002 + +#endif /* (defined(AOS_KERNEL_BUILD) && defined(AOS_COMP_DEVFS)) || !defined(AOS_KERNEL_BUILD) */ + +#ifdef AOS_KERNEL_BUILD typedef aos_dev_ref_t aos_pwm_ref_t; /**< PWM设备的引用 */ +#ifdef __cplusplus +extern "C" { +#endif + /** * 获取一个PWM设备的引用 * @@ -85,6 +88,8 @@ aos_status_t aos_pwm_get_attr(aos_pwm_ref_t *ref, aos_pwm_attr_t *attr); } #endif +#endif /* AOS_KERNEL_BUILD */ + /** @} */ -#endif /* _AOS_PWM_H */ +#endif /* AOS_PWM_H */ diff --git a/components/drivers/peripheral/pwm/include/aos/pwm_core.h b/components/drivers/peripheral/pwm/include/aos/pwm_core.h index adc9c9b7b1..96e9b29e91 100644 --- a/components/drivers/peripheral/pwm/include/aos/pwm_core.h +++ b/components/drivers/peripheral/pwm/include/aos/pwm_core.h @@ -2,11 +2,9 @@ * Copyright (C) 2021 Alibaba Group Holding Limited */ -#ifndef _AOS_PWM_CORE_H -#define _AOS_PWM_CORE_H +#ifndef AOS_PWM_CORE_H +#define AOS_PWM_CORE_H -#include -#include #include #include @@ -76,4 +74,4 @@ aos_status_t aos_pwm_unregister(uint32_t id); } #endif -#endif /* _AOS_PWM_CORE_H */ +#endif /* AOS_PWM_CORE_H */ diff --git a/components/drivers/peripheral/pwm/package.yaml b/components/drivers/peripheral/pwm/package.yaml index 26bc6f5f64..500010a9ae 100644 --- a/components/drivers/peripheral/pwm/package.yaml +++ b/components/drivers/peripheral/pwm/package.yaml @@ -1,13 +1,12 @@ - ## 第一部分: 基础信息 name: pwm # <必选项> 包名称 (符合C语言变量命名规则),长度少于等于64字节 -version: master # <必选项> 组件版本号 -description: PWM 通用驱动 # <必选项> 建议至少20字以上 +version: master # <必选项> 组件版本号 +description: PWM通用驱动 # <必选项> 建议至少20字以上 type: common # <必选项> 组件类型,为:solution, chip, board, common, sdk tag: 第三方驱动 # <可选项> 组件分类,缺省值: '' keywords: # <可选项> 标签,会影响到组件被搜索的效果,合理的标签很重要 - - pwm core and vfs driver + - pwm driver license: Apache license v2.0 # <可选项> 源代码的许可证,要确保所有代码、文件的许可证不冲突。如:MIT,Apache license v2.0,BSD ## 第二部分:依赖信息 @@ -18,7 +17,7 @@ license: Apache license v2.0 # <可选项> 源代码的 # - aos: >=v7.2.0 depends: - base: master - - vfs: master + - csi: master ? ## 第四部分:编译连接信息 # build_config: # <可选项> 编译配置项 @@ -47,19 +46,16 @@ build_config: # source_file: # <可选项> 指定参与编译的源代码文件,支持通配符,采用相对路径 # - src/*.c # 例:组件 src 目录下所有的扩展名为 c 的源代码文件 source_file: - -# PWM - - src/pwm_dev.c ? - - src/pwm.c ? - - src/pwm_csi.c ? -# - example/aos_pwm_example.c ? -# - example/pwm_example.c ? + - src/pwm.c + - src/pwm_csi.c ? ## 第五部分:配置信息 # def_config: # 组件的可配置项 # CONFIG_DEBUG: y # CONFIG_PARAM_NOT_CHECK: y # CONFIG_CLI: y +def_config: + AOS_COMP_PWM: 1 ## 第六部分:安装信息 # install: @@ -67,8 +63,9 @@ source_file: # source: # 安装源列表 # - src/*.h # 支持通配符,相对路径 install: - - dest: "include/devices" + - dest: "include/aos" source: + - "include/aos/pwm.h" ## 第七部分:导出部分 # export: diff --git a/components/drivers/peripheral/pwm/src/pwm.c b/components/drivers/peripheral/pwm/src/pwm.c index e9033f6c23..e4ea8a43d7 100644 --- a/components/drivers/peripheral/pwm/src/pwm.c +++ b/components/drivers/peripheral/pwm/src/pwm.c @@ -2,14 +2,11 @@ * Copyright (C) 2021 Alibaba Group Holding Limited */ -#include -#include -#include -#include -#include -#include +#include #include -#include +#ifdef AOS_COMP_DEVFS +#include +#endif #define AOS_MAX_PERIOD (1000000000U) #define AOS_PWM_CHECK_NULL(x) \ @@ -45,11 +42,11 @@ aos_status_t aos_pwm_set_attr(aos_pwm_ref_t *ref, aos_pwm_attr_t const *attr) pwm = aos_container_of(ref->dev, aos_pwm_t, dev); memcpy(&l_attr, attr, sizeof(aos_pwm_attr_t)); if (l_attr.period > AOS_MAX_PERIOD) { - ddkc_warn("warning:period exceeds 1s\r\n"); + printf("warning:period exceeds 1s\r\n"); l_attr.period = AOS_MAX_PERIOD; } if (l_attr.duty_cycle > l_attr.period) { - ddkc_warn("warning: duty exceeds period\r\n"); + printf("warning: duty exceeds period\r\n"); l_attr.duty_cycle = l_attr.period; } if (l_attr.period == pwm->period && @@ -74,7 +71,6 @@ aos_status_t aos_pwm_set_attr(aos_pwm_ref_t *ref, aos_pwm_attr_t const *attr) aos_status_t aos_pwm_get_attr(aos_pwm_ref_t *ref, aos_pwm_attr_t *attr) { - aos_status_t ret; aos_pwm_t *pwm; AOS_PWM_CHECK_NULL(ref); @@ -83,7 +79,7 @@ aos_status_t aos_pwm_get_attr(aos_pwm_ref_t *ref, aos_pwm_attr_t *attr) aos_dev_lock(ref->dev); attr->period = pwm->period; attr->duty_cycle = pwm->duty_cycle; - attr->enabled = pwm->enabled; + attr->enabled = pwm->enabled; attr->polarity = pwm->polarity; aos_dev_unlock(ref->dev); return 0; @@ -124,10 +120,70 @@ static const aos_dev_ops_t dev_pwm_ops = { .put = dev_pwm_put, }; -aos_status_t aos_pwm_register(aos_pwm_t *pwm) +#ifdef AOS_COMP_DEVFS + +static aos_status_t devfs_pwm_ioctl(aos_devfs_file_t *file, int cmd, uintptr_t arg) { + aos_pwm_ref_t *ref = aos_devfs_file2ref(file); aos_status_t ret; + switch (cmd) { + case AOS_PWM_IOC_GET_ATTR: + { + aos_pwm_attr_t attr; + if (!aos_devfs_file_is_readable(file)) { + ret = -EPERM; + break; + } + ret = aos_pwm_get_attr(ref, &attr); + if (ret) + break; + if (!aos_umem_check((const void *)arg, sizeof(attr))) + return -EFAULT; + ret = aos_umem_copy((void *)arg, &attr, sizeof(attr)) ? -EFAULT : 0; + } + break; + case AOS_PWM_IOC_SET_ATTR: + { + aos_pwm_attr_t attr; + if (!aos_devfs_file_is_writable(file)) { + ret = -EPERM; + break; + } + if (!aos_umem_check((const void *)arg, sizeof(attr))) + return -EFAULT; + if (aos_umem_copy(&attr, (const void *)arg, sizeof(attr))) { + ret = -EFAULT; + break; + } + ret = aos_pwm_set_attr(ref, &attr); + } + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static const aos_devfs_file_ops_t devfs_pwm_ops = { + .ioctl = devfs_pwm_ioctl, + .poll = NULL, + .mmap = NULL, + .read = NULL, + .write = NULL, + .lseek = NULL, +}; + +#endif /* AOS_COMP_DEVFS */ + +aos_status_t aos_pwm_register(aos_pwm_t *pwm) +{ +#ifdef AOS_COMP_DEVFS + int name_len; +#endif + AOS_PWM_CHECK_NULL(pwm); /* startup/shutdown/unregister/apply/startup must be set. */ @@ -142,10 +198,12 @@ aos_status_t aos_pwm_register(aos_pwm_t *pwm) pwm->duty_cycle = 0; pwm->period = 0; pwm->polarity = 0; -#ifdef AOS_COMP_VFS - /* TODO: support vfs ops. */ - pwm->dev.vfs_helper.name[0] = '\0'; - pwm->dev.vfs_helper.ops = NULL; +#ifdef AOS_COMP_DEVFS + aos_devfs_node_init(&pwm->dev.devfs_node); + pwm->dev.devfs_node.ops = &devfs_pwm_ops; + name_len = snprintf(pwm->dev.devfs_node.name, sizeof(pwm->dev.devfs_node.name), "pwm%" PRIu32, pwm->dev.id); + if (name_len < 0 || name_len >= sizeof(pwm->dev.devfs_node.name)) + return -EINVAL; #endif return aos_dev_register(&(pwm->dev)); -- GitLab