diff --git a/device/pin.c b/device/pin.c index 5c9113a..71bda63 100644 --- a/device/pin.c +++ b/device/pin.c @@ -10,88 +10,21 @@ #ifdef MR_USING_PIN -/** - * @brief Pin irq structure. - */ -struct pin_irq -{ - int number; /**< Pin number */ - int desc; /**< Device descriptor */ - int (*call)(int desc, void *args); /**< Callback function */ - struct mr_list list; /**< List */ -}; +void _mr_fast_pin_init(struct mr_dev *dev); -static int pin_set_mode(struct mr_pin *pin, int number, int mode) +MR_INLINE int pin_set_mode(struct mr_pin *pin, int number, int mode) { struct mr_pin_ops *ops = (struct mr_pin_ops *)pin->dev.drv->ops; - /* Check number is valid */ if (number < 0) { return MR_EINVAL; } - /* Configure pin mode */ - int ret = ops->configure(pin, number, mode); - if (ret < 0) - { - return ret; - } - - /* Disable interrupt */ - mr_interrupt_disable(); - - /* If the irq exists, update it */ - for (struct mr_list *list = pin->irq_list.next; list != &pin->irq_list; list = list->next) - { - struct pin_irq *irq = (struct pin_irq *)MR_CONTAINER_OF(list, struct pin_irq, list); - if (irq->number == number) - { - if (mode < MR_PIN_MODE_IRQ_RISING) - { - /* Remove irq */ - mr_list_remove(list); - mr_free(irq); - } else - { - /* Update irq */ - irq->desc = pin->dev.rd_call.desc; - irq->call = pin->dev.rd_call.call; - } - - /* Enable interrupt */ - mr_interrupt_enable(); - return MR_EOK; - } - } - - /* If not exist, allocate new irq */ - if (mode >= MR_PIN_MODE_IRQ_RISING) - { - /* Allocate irq */ - struct pin_irq *irq = (struct pin_irq *)mr_malloc(sizeof(struct pin_irq)); - if (irq == MR_NULL) - { - /* Enable interrupt */ - mr_interrupt_enable(); - return MR_ENOMEM; - } - irq->number = number; - irq->desc = pin->dev.rd_call.desc; - irq->call = pin->dev.rd_call.call; - mr_list_init(&irq->list); - mr_list_insert_before(&pin->irq_list, &irq->list); - - /* Clear call */ - pin->dev.rd_call.call = MR_NULL; - } - - /* Enable interrupt */ - mr_interrupt_enable(); - return MR_EOK; + return ops->configure(pin, number, mode); } -static ssize_t mr_pin_read(struct mr_dev *dev, int off, void *buf, size_t size, int async) +static ssize_t mr_pin_read(struct mr_dev *dev, void *buf, size_t count) { struct mr_pin *pin = (struct mr_pin *)dev; struct mr_pin_ops *ops = (struct mr_pin_ops *)dev->drv->ops; @@ -99,22 +32,22 @@ static ssize_t mr_pin_read(struct mr_dev *dev, int off, void *buf, size_t size, ssize_t rd_size; #ifdef MR_USING_PIN_CHECK - /* Check offset is valid */ - if (off < 0) + /* Check number is valid */ + if (dev->position < 0) { return MR_EINVAL; } #endif /* MR_USING_PIN_CHECK */ - for (rd_size = 0; rd_size < size; rd_size += sizeof(*rd_buf)) + for (rd_size = 0; rd_size < count; rd_size += sizeof(*rd_buf)) { - *rd_buf = (uint8_t)ops->read(pin, off); + *rd_buf = (uint8_t)ops->read(pin, dev->position); rd_buf++; } return rd_size; } -static ssize_t mr_pin_write(struct mr_dev *dev, int off, const void *buf, size_t size, int async) +static ssize_t mr_pin_write(struct mr_dev *dev, const void *buf, size_t count) { struct mr_pin *pin = (struct mr_pin *)dev; struct mr_pin_ops *ops = (struct mr_pin_ops *)dev->drv->ops; @@ -122,34 +55,34 @@ static ssize_t mr_pin_write(struct mr_dev *dev, int off, const void *buf, size_t ssize_t wr_size; #ifdef MR_USING_PIN_CHECK - /* Check offset is valid */ - if (off < 0) + /* Check number is valid */ + if (dev->position < 0) { return MR_EINVAL; } #endif /* MR_USING_PIN_CHECK */ - for (wr_size = 0; wr_size < size; wr_size += sizeof(*wr_buf)) + for (wr_size = 0; wr_size < count; wr_size += sizeof(*wr_buf)) { - ops->write(pin, off, *wr_buf); + ops->write(pin, dev->position, *wr_buf); wr_buf++; } return wr_size; } -static int mr_pin_ioctl(struct mr_dev *dev, int off, int cmd, void *args) +static int mr_pin_ioctl(struct mr_dev *dev, int cmd, void *args) { struct mr_pin *pin = (struct mr_pin *)dev; switch (cmd) { - case MR_CTL_PIN_SET_MODE: + case MR_IOC_PIN_SET_MODE: { if (args != MR_NULL) { struct mr_pin_config config = *((struct mr_pin_config *)args); - int ret = pin_set_mode(pin, off, config.mode); + int ret = pin_set_mode(pin, dev->position, config.mode); if (ret < 0) { return ret; @@ -167,25 +100,13 @@ static int mr_pin_ioctl(struct mr_dev *dev, int off, int cmd, void *args) static ssize_t mr_pin_isr(struct mr_dev *dev, int event, void *args) { - struct mr_pin *pin = (struct mr_pin *)dev; - switch (event) { case MR_ISR_PIN_EXTI_INT: { ssize_t number = *(int *)args; - /* If the irq exists, call it */ - for (struct mr_list *list = pin->irq_list.next; list != &pin->irq_list; list = list->next) - { - struct pin_irq *irq = (struct pin_irq *)MR_CONTAINER_OF(list, struct pin_irq, list); - if (irq->number == number) - { - irq->call(irq->desc, &number); - return MR_EEXIST; - } - } - return MR_ENOTFOUND; + return number; } default: { @@ -198,12 +119,12 @@ static ssize_t mr_pin_isr(struct mr_dev *dev, int event, void *args) * @brief This function registers a pin. * * @param pin The pin. - * @param name The name of the pin. + * @param path The path of the pin. * @param drv The driver of the pin. * - * @return MR_EOK on success, otherwise an error code. + * @return 0 on success, otherwise an error code. */ -int mr_pin_register(struct mr_pin *pin, const char *name, struct mr_drv *drv) +int mr_pin_register(struct mr_pin *pin, const char *path, struct mr_drv *drv) { static struct mr_dev_ops ops = { @@ -216,15 +137,18 @@ int mr_pin_register(struct mr_pin *pin, const char *name, struct mr_drv *drv) }; MR_ASSERT(pin != MR_NULL); - MR_ASSERT(name != MR_NULL); + MR_ASSERT(path != MR_NULL); MR_ASSERT(drv != MR_NULL); MR_ASSERT(drv->ops != MR_NULL); - /* Initialize the fields */ - mr_list_init(&pin->irq_list); - /* Register the pin */ - return mr_dev_register(&pin->dev, name, Mr_Dev_Type_Pin, MR_SFLAG_RDWR, &ops, drv); + int ret = mr_dev_register(&pin->dev, path, MR_DEV_TYPE_PIN, MR_O_RDWR, &ops, drv); + if (ret == MR_EOK) + { + /* Initialize the fast pin */ + _mr_fast_pin_init(&pin->dev); + } + return ret; } #endif /* MR_USING_PIN */ diff --git a/document/device/pin/pin.md b/document/device/pin/pin.md index bdc0a50..5ab68c3 100644 --- a/document/device/pin/pin.md +++ b/document/device/pin/pin.md @@ -20,21 +20,21 @@ ## 打开PIN设备 ```c -int mr_dev_open(const char *name, int oflags); +int mr_dev_open(const char *path, int flags); ``` | 参数 | 描述 | |---------|---------| -| name | 设备名称 | -| oflags | 打开设备的标志 | +| path | 设备路径 | +| flags | 打开设备的标志 | | **返回值** | | | `>=0` | 设备描述符 | | `<0` | 错误码 | -- `name`:PIN设备名称一般为:`pin`。 -- `oflags`:打开设备的标志,支持 `MR_OFLAG_RDONLY`、 `MR_OFLAG_WRONLY`、 `MR_OFLAG_RDWR`。 +- `path`:PIN设备路径一般为:`pin`。 +- `flags`:打开设备的标志,支持 `MR_O_RDONLY`、 `MR_O_WRONLY`、 `MR_O_RDWR`。 -注:使用时应根据实际情况为不同的任务分别打开PIN设备,并使用适当的`oflags`进行管理和权限控制,以确保它们不会相互影响。 +注:使用时应根据实际情况为不同的任务分别打开PIN设备,并使用适当的`flags`进行管理和权限控制,以确保它们不会相互影响。 ## 关闭PIN设备 @@ -67,11 +67,11 @@ int mr_dev_ioctl(int desc, int cmd, void *args); | `<0` | 错误码 | - `cmd`:命令码,支持以下命令: - - `MR_CTL_PIN_SET_NUMBER`:设置引脚编号。 - - `MR_CTL_PIN_SET_MODE`:设置引脚模式。 - - `MR_CTL_PIN_SET_EXTI_CALL`:设置外部中断回调函数。 - - `MR_CTL_PIN_GET_NUMBER`:获取引脚编号。 - - `MR_CTL_PIN_GET_EXTI_CALL`:获取外部中断回调函数。 + - `MR_IOC_PIN_SET_NUMBER`:设置引脚编号。 + - `MR_IOC_PIN_SET_MODE`:设置引脚模式。 + - `MR_IOC_PIN_SET_EXTI_CALL`:设置外部中断回调函数。 + - `MR_IOC_PIN_GET_NUMBER`:获取引脚编号。 + - `MR_IOC_PIN_GET_EXTI_CALL`:获取外部中断回调函数。 ### 设置/获取引脚编号 @@ -89,11 +89,11 @@ int mr_dev_ioctl(int desc, int cmd, void *args); #define PIN_NUMBER 45 /* 设置引脚编号 */ -mr_dev_ioctl(ds, MR_CTL_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, PIN_NUMBER)); +mr_dev_ioctl(ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, PIN_NUMBER)); /* 获取引脚编号 */ int number; -mr_dev_ioctl(ds, MR_CTL_PIN_GET_NUMBER, &number); +mr_dev_ioctl(ds, MR_IOC_PIN_GET_NUMBER, &number); ``` 不依赖PIN接口: @@ -103,11 +103,11 @@ mr_dev_ioctl(ds, MR_CTL_PIN_GET_NUMBER, &number); #define PIN_NUMBER 45 /* 设置引脚编号 */ -mr_dev_ioctl(ds, MR_CTL_SET_OFFSET, MR_MAKE_LOCAL(int, PIN_NUMBER)); +mr_dev_ioctl(ds, MR_IOC_SPOS, MR_MAKE_LOCAL(int, PIN_NUMBER)); /* 获取引脚编号 */ int number; -mr_dev_ioctl(ds, MR_CTL_GET_OFFSET, &number); +mr_dev_ioctl(ds, MR_IOC_GPOS, &number); ``` ### 设置引脚模式 @@ -136,7 +136,7 @@ mr_dev_ioctl(ds, MR_CTL_GET_OFFSET, &number); #define PIN_MODE MR_PIN_MODE_OUTPUT /* 设置引脚模式 */ -mr_dev_ioctl(ds, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE)); +mr_dev_ioctl(ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE)); ``` 不依赖PIN接口: @@ -146,7 +146,7 @@ mr_dev_ioctl(ds, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE)); #define PIN_MODE 1 /* 设置引脚模式 */ -mr_dev_ioctl(ds, MR_CTL_SET_CONFIG, MR_MAKE_LOCAL(int, PIN_MODE)); +mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, PIN_MODE)); ``` ### 设置/获取外部中断回调函数 @@ -154,22 +154,22 @@ mr_dev_ioctl(ds, MR_CTL_SET_CONFIG, MR_MAKE_LOCAL(int, PIN_MODE)); ```c #define PIN_NUMBER 45 /* 定义外部中断回调函数 */ -int call(int desc, void *args) +void fn(int desc, void *args) { - /* 获取引脚编号 */ - ssize_t number = *(ssize_t *)args; - - /* 处理外部中断事件 */ - - return MR_EOK; + /* 获取引脚编号 */ + ssize_t number = *(ssize_t *)args; + if (number == PIN_NUMBER) + { + /* 处理外部中断事件 */ + } } /* 设置外部中断回调函数 */ -mr_dev_ioctl(ds, MR_CTL_PIN_SET_EXTI_CALL, call); +mr_dev_ioctl(ds, MR_IOC_PIN_SET_EXTI_CALL, fn); /* 获取外部中断回调函数 */ -int (*callback)(int desc, void *args); -mr_dev_ioctl(ds, MR_CTL_PIN_GET_EXTI_CALL, &callback); +void (*callback)(int desc, void *args); +mr_dev_ioctl(ds, MR_IOC_PIN_GET_EXTI_CALL, &callback); ``` 不依赖PIN接口: @@ -177,33 +177,32 @@ mr_dev_ioctl(ds, MR_CTL_PIN_GET_EXTI_CALL, &callback); ```c #define PIN_NUMBER 45 /* 定义外部中断回调函数 */ -int call(int desc, void *args) +void fn(int desc, void *args) { - /* 获取引脚编号 */ - ssize_t number = *(ssize_t *)args; - - /* 处理外部中断事件 */ - - return MR_EOK; + /* 获取引脚编号 */ + ssize_t number = *(ssize_t *)args; + if (number == PIN_NUMBER) + { + /* 处理外部中断事件 */ + } } /* 设置外部中断回调函数 */ -mr_dev_ioctl(ds, MR_CTL_SET_RD_CALL, call); +mr_dev_ioctl(ds, MR_IOC_SRCB, fn); /* 获取外部中断回调函数 */ -int (*callback)(int desc, void *args); -mr_dev_ioctl(ds, MR_CTL_GET_RD_CALL, &callback); +void (*callback)(int desc, void *args); +mr_dev_ioctl(ds, MR_IOC_GRCB, &callback); ``` 注: -- 设置外部中断模式前需要先配置回调函数,否则将成为无回调中断。 -- 即使PIN设备被关闭,回调函数也不会失效,直至引脚被设置为普通模式(PIN设备关闭时,外部中断将被忽略)。 +- 只要有引脚触发外部中断,即会调用所有回调函数,请一定检查是否引脚是否正确。 ## 读取PIN设备引脚电平 ```c -ssize_t mr_dev_read(int desc, void *buf, size_t size); +ssize_t mr_dev_read(int desc, void *buf, size_t count); ``` | 参数 | 描述 | @@ -229,7 +228,7 @@ if (ret != sizeof(pin_level)) ## 写入PIN设备引脚电平 ```c -ssize_t mr_dev_write(int desc, const void *buf, size_t size); +ssize_t mr_dev_write(int desc, const void *buf, size_t count); ``` | 参数 | 描述 | @@ -263,68 +262,63 @@ if (ret != sizeof(pin_level)) #define LED_PIN_NUMBER 45 #define KEY_PIN_NUMBER 0 -int key_call(int desc, void *args) +/* 定义LED和KEY描述符 */ +int led_ds = -1; +int key_ds = -1; + +void key_call(int desc, void *args) { ssize_t number = *((ssize_t *)args); if (number == KEY_PIN_NUMBER) { /* 打印回调函数描述符 */ - mr_printf("KEY callback, desc: %d\r\n", desc); - /* 翻转LED引脚电平 */ - uint8_t level = 0; - mr_dev_read(desc, &level, sizeof(level)); - level = !level; - mr_dev_write(desc, &level, sizeof(level)); - return MR_EOK; + mr_printf("KEY callback\r\n"); } - return MR_EINVAL; } -int led_key_init(void) +void led_key_init(void) { int ret = MR_EOK; /* 初始化LED */ - int led_ds = mr_dev_open("pin", MR_OFLAG_RDWR); + led_ds = mr_dev_open("pin", MR_O_WRONLY); if (led_ds < 0) { mr_printf("led open failed: %s\r\n", mr_strerror(led_ds)); - return led_ds; + return; } /* 打印LED描述符 */ mr_printf("LED desc: %d\r\n", led_ds); /* 设置到LED引脚 */ - mr_dev_ioctl(led_ds, MR_CTL_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, LED_PIN_NUMBER)); + mr_dev_ioctl(led_ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, LED_PIN_NUMBER)); /* 设置LED引脚为推挽输出模式 */ - ret = mr_dev_ioctl(led_ds, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT)); + ret = mr_dev_ioctl(led_ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT)); if (ret < 0) { mr_printf("led set mode failed: %s\r\n", mr_strerror(ret)); - return ret; + return; } - /* 设置KEY外部中断回调函数(为了演示描述符的继承机制,此处使用LED设备描述符配置KEY回调函数) */ - mr_dev_ioctl(led_ds, MR_CTL_PIN_SET_EXTI_CALL, key_call); /* 初始化KEY */ - int key_ds = mr_dev_open("pin", MR_OFLAG_RDWR); + key_ds = mr_dev_open("pin", MR_O_RDONLY); if (key_ds < 0) { mr_printf("key open failed: %s\r\n", mr_strerror(key_ds)); - return key_ds; + return; } /* 打印KEY描述符 */ mr_printf("KEY desc: %d\r\n", key_ds); /* 设置到KEY引脚 */ - mr_dev_ioctl(key_ds, MR_CTL_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, KEY_PIN_NUMBER)); - /* 设置KEY引脚为外部中断(下降沿)模式(未重新配置回调函数,则使用上一次的结果,即LED设置的回调函数) */ - ret = mr_dev_ioctl(key_ds, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_IRQ_FALLING)); + mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, KEY_PIN_NUMBER)); + /* 设置KEY外部中断回调函数 */ + mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_EXTI_CALL, key_call); + /* 设置KEY引脚为外部中断(下降沿)模式 */ + ret = mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_IRQ_FALLING)); if (ret < 0) { mr_printf("key set mode failed: %s\r\n", mr_strerror(ret)); - return ret; } - return MR_EOK; } /* 导出到自动初始化(APP级) */ MR_INIT_APP_EXPORT(led_key_init); @@ -336,9 +330,14 @@ int main(void) while(1) { - + /* 翻转LED引脚电平 */ + uint8_t level = 0; + mr_dev_read(led_ds, &level, sizeof(level)); + level = !level; + mr_dev_write(led_ds, &level, sizeof(level)); + mr_delay_ms(500); } } ``` -按下KEY后,LED将翻转。观察串口打印,可以看到LED和KEY的描述符。虽然KEY引脚的外部中断是KEY配置的,但未重新配置回调函数。故KEY引脚回调函数继承之前的配置,即LED配置的回调函数,所以KEY回调函数中打印的描述符为LED的描述符。 +按下KEY后,串口打印 "KEY callback",LED每500ms翻转一次。 diff --git a/document/device/pin/pin_EN.md b/document/device/pin/pin_EN.md index 059172f..8ab88c3 100644 --- a/document/device/pin/pin_EN.md +++ b/document/device/pin/pin_EN.md @@ -20,22 +20,22 @@ ## Open PIN Device ```c -int mr_dev_open(const char *name, int oflags); +int mr_dev_open(const char *path, int flags); ``` | Parameter | Description | |------------------|-------------------| -| name | Device name | -| oflags | Open device flags | +| path | Device path | +| flags | Open device flags | | **Return Value** | | | `>=0` | Device descriptor | | `<0` | Error code | -- `name`: The PIN device name is usually `"pin"`. -- `oflags`: Open device flags, supports `MR_OFLAG_RDONLY`, `MR_OFLAG_WRONLY`, `MR_OFLAG_RDWR`. +- `path`: The PIN device path is usually `"pin"`. +- `flags`: Open device flags, supports `MR_O_RDONLY`, `MR_O_WRONLY`, `MR_O_RDWR`. Note: When using, different tasks should open the PIN device separately according to actual situations and use -appropriate `oflags` for management and permission control to ensure they won't interfere with each other. +appropriate `flags` for management and permission control to ensure they won't interfere with each other. ## Close PIN Device @@ -69,11 +69,11 @@ int mr_dev_ioctl(int desc, int cmd, void *args); | `<0` | Error code | - `cmd`: Command code, supports: - - `MR_CTL_PIN_SET_NUMBER`: Set pin number - - `MR_CTL_PIN_SET_MODE`: Set pin mode - - `MR_CTL_PIN_SET_EXTI_CALL`: Set external interrupt callback function - - `MR_CTL_PIN_GET_NUMBER`: Get pin number - - `MR_CTL_PIN_GET_EXTI_CALL`: Get external interrupt callback function + - `MR_IOC_PIN_SET_NUMBER`: Set pin number + - `MR_IOC_PIN_SET_MODE`: Set pin mode + - `MR_IOC_PIN_SET_EXTI_CALL`: Set external interrupt callback function + - `MR_IOC_PIN_GET_NUMBER`: Get pin number + - `MR_IOC_PIN_GET_EXTI_CALL`: Get external interrupt callback function ### Set/Get Pin Number @@ -93,11 +93,11 @@ Note: This rule may not apply to all MCUs. Special requirements need to check th #define PIN_NUMBER 45 /* Set pin number */ -mr_dev_ioctl(ds, MR_CTL_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, PIN_NUMBER)); +mr_dev_ioctl(ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, PIN_NUMBER)); /* Get pin number */ int number; -mr_dev_ioctl(ds, MR_CTL_PIN_GET_NUMBER, &number); +mr_dev_ioctl(ds, MR_IOC_PIN_GET_NUMBER, &number); ``` Independent of PIN interface: @@ -107,11 +107,11 @@ Independent of PIN interface: #define PIN_NUMBER 45 /* Set pin number */ -mr_dev_ioctl(ds, MR_CTL_SET_OFFSET, MR_MAKE_LOCAL(int, PIN_NUMBER)); +mr_dev_ioctl(ds, MR_IOC_SPOS, MR_MAKE_LOCAL(int, PIN_NUMBER)); /* Get pin number */ int number; -mr_dev_ioctl(ds, MR_CTL_GET_OFFSET, &number); +mr_dev_ioctl(ds, MR_IOC_GPOS, &number); ``` ### Set Pin Mode @@ -140,7 +140,7 @@ And 5 external interrupt modes: #define PIN_MODE MR_PIN_MODE_OUTPUT /* Set pin mode */ -mr_dev_ioctl(ds, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE)); +mr_dev_ioctl(ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE)); ``` Independent of PIN interface: @@ -150,7 +150,7 @@ Independent of PIN interface: #define PIN_MODE 1 /* Set pin mode */ -mr_dev_ioctl(ds, MR_CTL_SET_CONFIG, MR_MAKE_LOCAL(int, PIN_MODE)); +mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, PIN_MODE)); ``` ### Set/Get External Interrupt Callback Function @@ -158,22 +158,22 @@ mr_dev_ioctl(ds, MR_CTL_SET_CONFIG, MR_MAKE_LOCAL(int, PIN_MODE)); ```c #define PIN_NUMBER 45 /* Define external interrupt callback function */ -int call(int desc, void *args) +void fn(int desc, void *args) { - /* Get pin number */ - ssize_t number = *(ssize_t *)args; - - /* Handle external interrupt event */ - - return MR_EOK; + /* Get pin number */ + ssize_t number = *(ssize_t *)args; + if (number == PIN_NUMBER) + { + /* Handle external interrupt event */ + } } /* Set external interrupt callback function */ -mr_dev_ioctl(ds, MR_CTL_PIN_SET_EXTI_CALL, call); +mr_dev_ioctl(ds, MR_IOC_PIN_SET_EXTI_CALL, fn); /* Get external interrupt callback function */ -int (*callback)(int desc, void *args); -mr_dev_ioctl(ds, MR_CTL_PIN_GET_EXTI_CALL, &callback); +void (*callback)(int desc, void *args); +mr_dev_ioctl(ds, MR_IOC_PIN_GET_EXTI_CALL, &callback); ``` Independent of PIN interface: @@ -181,35 +181,32 @@ Independent of PIN interface: ```c #define PIN_NUMBER 45 /* Define external interrupt callback function */ -int call(int desc, void *args) +void fn(int desc, void *args) { - /* Get pin number */ - ssize_t number = *(ssize_t *)args; - - /* Handle external interrupt event */ - - return MR_EOK; + /* Get pin number */ + ssize_t number = *(ssize_t *)args; + if (number == PIN_NUMBER) + { + /* Handle external interrupt event */ + } } /* Set external interrupt callback function */ -mr_dev_ioctl(ds, MR_CTL_SET_RD_CALL, call); +mr_dev_ioctl(ds, MR_IOC_SRCB, fn); /* Get external interrupt callback function */ -int (*callback)(int desc, void *args); -mr_dev_ioctl(ds, MR_CTL_GET_RD_CALL, &callback); +void (*callback)(int desc, void *args); +mr_dev_ioctl(ds, MR_IOC_GRCB, &callback); ``` Note: -- Before setting the external interrupt mode, you need to configure the callback function, otherwise, it becomes a - callback-free interrupt. -- Even if the PIN device is closed, the callback function will not be invalid until the pin is set to a common mode ( - external interrupts will be ignored when the PIN device is closed). +- All callbacks are called as soon as any pin triggers an external interrupt, be sure to check that the pin is correct. ## Read PIN Device Pin Level ```c -ssize_t mr_dev_read(int desc, void *buf, size_t size); +ssize_t mr_dev_read(int desc, void *buf, size_t count); ``` | Parameter | Description | @@ -235,7 +232,7 @@ if (ret != sizeof(pin_level)) ## Write PIN Device Pin Level ```c -ssize_t mr_dev_write(int desc, const void *buf, size_t size); +ssize_t mr_dev_write(int desc, const void *buf, size_t count); ``` | Parameter | Description | @@ -269,68 +266,63 @@ if (ret != sizeof(pin_level)) #define LED_PIN_NUMBER 45 #define KEY_PIN_NUMBER 0 -int key_call(int desc, void *args) +/* Define LED and KEY descriptors */ +int led_ds = -1; +int key_ds = -1; + +void key_call(int desc, void *args) { ssize_t number = *((ssize_t *)args); if (number == KEY_PIN_NUMBER) { /* Print the callback function descriptor */ - mr_printf("KEY callback, desc: %d\r\n", desc); - /* Toggle the LED pin level */ - uint8_t level = 0; - mr_dev_read(desc, &level, sizeof(level)); - level = !level; - mr_dev_write(desc, &level, sizeof(level)); - return MR_EOK; + mr_printf("KEY callback\r\n"); } - return MR_EINVAL; } -int led_key_init(void) +void led_key_init(void) { int ret = MR_EOK; /* Initialize LED */ - int led_ds = mr_dev_open("pin", MR_OFLAG_RDWR); + led_ds = mr_dev_open("pin", MR_O_WRONLY); if (led_ds < 0) { mr_printf("led open failed: %s\r\n", mr_strerror(led_ds)); - return led_ds; + return; } /* Print LED descriptor */ mr_printf("LED desc: %d\r\n", led_ds); /* Set to LED pin */ - mr_dev_ioctl(led_ds, MR_CTL_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, LED_PIN_NUMBER)); + mr_dev_ioctl(led_ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, LED_PIN_NUMBER)); /* Set LED pin to push-pull output mode */ - ret = mr_dev_ioctl(led_ds, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT)); + ret = mr_dev_ioctl(led_ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT)); if (ret < 0) { mr_printf("led set mode failed: %s\r\n", mr_strerror(ret)); - return ret; + return; } - /* Set KEY external interrupt callback function (for demonstrating descriptor inheritance, use LED device descriptor to configure KEY callback function) */ - mr_dev_ioctl(led_ds, MR_CTL_PIN_SET_EXTI_CALL, key_call); /* Initialize KEY */ - int key_ds = mr_dev_open("pin", MR_OFLAG_RDWR); + key_ds = mr_dev_open("pin", MR_O_RDONLY); if (key_ds < 0) { mr_printf("key open failed: %s\r\n", mr_strerror(key_ds)); - return key_ds; + return; } /* Print KEY descriptor */ mr_printf("KEY desc: %d\r\n", key_ds); /* Set to KEY pin */ - mr_dev_ioctl(key_ds, MR_CTL_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, KEY_PIN_NUMBER)); + mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, KEY_PIN_NUMBER)); + /* Set KEY external interrupt callback function */ + mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_EXTI_CALL, key_call); /* Set KEY pin to external interrupt (falling edge) mode (without reconfiguring the callback function, use the previous result, i.e. the callback function set by LED) */ - ret = mr_dev_ioctl(key_ds, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_IRQ_FALLING)); + ret = mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_IRQ_FALLING)); if (ret < 0) { mr_printf("key set mode failed: %s\r\n", mr_strerror(ret)); - return ret; } - return MR_EOK; } /* Export to auto initialization (APP level) */ MR_INIT_APP_EXPORT(led_key_init); @@ -342,14 +334,14 @@ int main(void) while(1) { - + /* Toggle LED pin level */ + uint8_t level = 0; + mr_dev_read(led_ds, &level, sizeof(level)); + level = !level; + mr_dev_write(led_ds, &level, sizeof(level)); + mr_delay_ms(500); } } ``` -After pressing the KEY, the LED will flip. -Observe the serial port print, you can see the LED and KEY descriptors. Although the external interrupt of the KEY pin -is configured by the KEY, -no callback function is configured. Therefore, the KEY pin callback function inherits the previous configuration, that -is, the callback function of the LED configuration, -so the descriptor printed in the KEY callback function is the descriptor of the LED. +After pressing the KEY, the serial port prints "KEY callback" and the LED flips every 500ms.