1.修复非阻塞模式下写入缓冲区为0时的非阻塞发送锁持续上锁,导致无法继续写入的问题。

This commit is contained in:
MacRsh
2024-01-31 22:41:48 +08:00
parent de64eb3ead
commit 7d5d7f2d3d
3 changed files with 148 additions and 160 deletions

View File

@@ -41,7 +41,7 @@ static int mr_serial_close(struct mr_dev *dev)
return ops->configure(serial, &close_config);
}
static ssize_t mr_serial_read(struct mr_dev *dev, int off, void *buf, size_t size, int async)
static ssize_t mr_serial_read(struct mr_dev *dev, void *buf, size_t count)
{
struct mr_serial *serial = (struct mr_serial *)dev;
struct mr_serial_ops *ops = (struct mr_serial_ops *)dev->drv->ops;
@@ -50,35 +50,35 @@ static ssize_t mr_serial_read(struct mr_dev *dev, int off, void *buf, size_t siz
if (mr_ringbuf_get_bufsz(&serial->rd_fifo) == 0)
{
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 = ops->read(serial);
rd_buf++;
}
} else
{
rd_size = (ssize_t)mr_ringbuf_read(&serial->rd_fifo, buf, size);
rd_size = (ssize_t)mr_ringbuf_read(&serial->rd_fifo, buf, count);
}
return rd_size;
}
static ssize_t mr_serial_write(struct mr_dev *dev, int off, const void *buf, size_t size, int async)
static ssize_t mr_serial_write(struct mr_dev *dev, const void *buf, size_t count)
{
struct mr_serial *serial = (struct mr_serial *)dev;
struct mr_serial_ops *ops = (struct mr_serial_ops *)dev->drv->ops;
uint8_t *wr_buf = (uint8_t *)buf;
ssize_t wr_size;
if ((async == MR_SYNC) || (mr_ringbuf_get_bufsz(&serial->wr_fifo) == 0))
if (dev->sync == MR_SYNC)
{
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(serial, *wr_buf);
wr_buf++;
}
} else
{
wr_size = (ssize_t)mr_ringbuf_write(&serial->wr_fifo, buf, size);
wr_size = (ssize_t)mr_ringbuf_write(&serial->wr_fifo, buf, count);
if (wr_size > 0)
{
/* Start interrupt sending */
@@ -88,14 +88,14 @@ static ssize_t mr_serial_write(struct mr_dev *dev, int off, const void *buf, siz
return wr_size;
}
static int mr_serial_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
{
struct mr_serial *serial = (struct mr_serial *)dev;
struct mr_serial_ops *ops = (struct mr_serial_ops *)dev->drv->ops;
switch (cmd)
{
case MR_CTL_SERIAL_SET_CONFIG:
case MR_IOC_SERIAL_SET_CONFIG:
{
if (args != MR_NULL)
{
@@ -111,7 +111,7 @@ static int mr_serial_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_SERIAL_SET_RD_BUFSZ:
case MR_IOC_SERIAL_SET_RD_BUFSZ:
{
if (args != MR_NULL)
{
@@ -128,7 +128,7 @@ static int mr_serial_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_SERIAL_SET_WR_BUFSZ:
case MR_IOC_SERIAL_SET_WR_BUFSZ:
{
if (args != MR_NULL)
{
@@ -145,17 +145,17 @@ static int mr_serial_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_SERIAL_CLR_RD_BUF:
case MR_IOC_SERIAL_CLR_RD_BUF:
{
mr_ringbuf_reset(&serial->rd_fifo);
return MR_EOK;
}
case MR_CTL_SERIAL_CLR_WR_BUF:
case MR_IOC_SERIAL_CLR_WR_BUF:
{
mr_ringbuf_reset(&serial->wr_fifo);
return MR_EOK;
}
case MR_CTL_SERIAL_GET_CONFIG:
case MR_IOC_SERIAL_GET_CONFIG:
{
if (args != MR_NULL)
{
@@ -166,7 +166,7 @@ static int mr_serial_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_SERIAL_GET_RD_BUFSZ:
case MR_IOC_SERIAL_GET_RD_BUFSZ:
{
if (args != MR_NULL)
{
@@ -177,7 +177,7 @@ static int mr_serial_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_SERIAL_GET_WR_BUFSZ:
case MR_IOC_SERIAL_GET_WR_BUFSZ:
{
if (args != MR_NULL)
{
@@ -188,7 +188,7 @@ static int mr_serial_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_SERIAL_GET_RD_DATASZ:
case MR_IOC_SERIAL_GET_RD_DATASZ:
{
if (args != MR_NULL)
{
@@ -199,7 +199,7 @@ static int mr_serial_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_SERIAL_GET_WR_DATASZ:
case MR_IOC_SERIAL_GET_WR_DATASZ:
{
if (args != MR_NULL)
{
@@ -239,12 +239,12 @@ static ssize_t mr_serial_isr(struct mr_dev *dev, int event, void *args)
if (mr_ringbuf_pop(&serial->wr_fifo, &data) == sizeof(data))
{
ops->write(serial, data);
return MR_EBUSY;
} else
{
ops->stop_tx(serial);
return MR_EOK;
}
return (ssize_t)mr_ringbuf_get_data_size(&serial->wr_fifo);
}
default:
{
@@ -257,12 +257,12 @@ static ssize_t mr_serial_isr(struct mr_dev *dev, int event, void *args)
* @brief This function register a serial.
*
* @param serial The serial.
* @param name The name of the serial.
* @param path The path of the serial.
* @param drv The driver of the serial.
*
* @return MR_EOK on success, otherwise an error code.
* @return 0 on success, otherwise an error code.
*/
int mr_serial_register(struct mr_serial *serial, const char *name, struct mr_drv *drv)
int mr_serial_register(struct mr_serial *serial, const char *path, struct mr_drv *drv)
{
static struct mr_dev_ops ops =
{
@@ -276,7 +276,7 @@ int mr_serial_register(struct mr_serial *serial, const char *name, struct mr_drv
struct mr_serial_config default_config = MR_SERIAL_CONFIG_DEFAULT;
MR_ASSERT(serial != MR_NULL);
MR_ASSERT(name != MR_NULL);
MR_ASSERT(path != MR_NULL);
MR_ASSERT(drv != MR_NULL);
MR_ASSERT(drv->ops != MR_NULL);
@@ -294,7 +294,7 @@ int mr_serial_register(struct mr_serial *serial, const char *name, struct mr_drv
serial->wr_bufsz = MR_CFG_SERIAL_WR_BUFSZ;
/* Register the serial */
return mr_dev_register(&serial->dev, name, Mr_Dev_Type_Serial, MR_SFLAG_RDWR | MR_SFLAG_NONBLOCK, &ops, drv);
return mr_dev_register(&serial->dev, path, MR_DEV_TYPE_SERIAL, MR_O_RDWR | MR_O_NONBLOCK, &ops, drv);
}
#endif /* MR_USING_SERIAL */

View File

@@ -20,21 +20,21 @@
## 打开SERIAL设备
```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`SERIAL设备名称一般为:`serialx`,例如:`serial1``serial2``serial3`
- `oflags`:打开设备的标志,支持 `MR_OFLAG_RDONLY``MR_OFLAG_WRONLY``MR_OFLAG_RDWR``MR_OFLAG_NONBLOCK`
- `path`SERIAL设备路径一般为:`serialx`,例如:`serial1``serial2``serial3`
- `flags`:打开设备的标志,支持 `MR_O_RDONLY``MR_O_WRONLY``MR_O_RDWR``MR_O_NONBLOCK`
使用时应根据实际情况为不同的任务分别打开SERIAL设备并使用适当的`oflags`进行管理和权限控制,以确保它们不会相互影响。
使用时应根据实际情况为不同的任务分别打开SERIAL设备并使用适当的`flags`进行管理和权限控制,以确保它们不会相互影响。
## 关闭SERIAL设备
@@ -65,20 +65,20 @@ int mr_dev_ioctl(int desc, int cmd, void *args);
| `<0` | 错误码 |
- `cmd`:命令码,支持以下命令:
- `MR_CTL_SERIAL_SET_CONFIG`设置SERIAL设备配置。
- `MR_CTL_SERIAL_SET_RD_BUFSZ`:设置读缓冲区大小。
- `MR_CTL_SERIAL_SET_WR_BUFSZ`:设置写缓冲区大小。
- `MR_CTL_SERIAL_CLR_RD_BUF`:清空读缓冲区。
- `MR_CTL_SERIAL_CLR_WR_BUF`:清空写缓冲区。
- `MR_CTL_SERIAL_SET_RD_CALL`:设置读回调函数。
- `MR_CTL_SERIAL_SET_WR_CALL`:设置写回调函数。
- `MR_CTL_SERIAL_GET_CONFIG`获取SERIAL设备配置。
- `MR_CTL_SERIAL_GET_RD_BUFSZ`:获取读缓冲区大小。
- `MR_CTL_SERIAL_GET_WR_BUFSZ`:获取写缓冲区大小。
- `MR_CTL_SERIAL_GET_RD_DATASZ`:获取读缓冲区数据大小。
- `MR_CTL_SERIAL_GET_WR_DATASZ`:获取写缓冲区数据大小。
- `MR_CTL_SERIAL_GET_RD_CALL`:获取读回调函数。
- `MR_CTL_SERIAL_GET_WR_CALL`:获取写回调函数。
- `MR_IOC_SERIAL_SET_CONFIG`设置SERIAL设备配置。
- `MR_IOC_SERIAL_SET_RD_BUFSZ`:设置读缓冲区大小。
- `MR_IOC_SERIAL_SET_WR_BUFSZ`:设置写缓冲区大小。
- `MR_IOC_SERIAL_CLR_RD_BUF`:清空读缓冲区。
- `MR_IOC_SERIAL_CLR_WR_BUF`:清空写缓冲区。
- `MR_IOC_SERIAL_SET_RD_CALL`:设置读回调函数。
- `MR_IOC_SERIAL_SET_WR_CALL`:设置写回调函数。
- `MR_IOC_SERIAL_GET_CONFIG`获取SERIAL设备配置。
- `MR_IOC_SERIAL_GET_RD_BUFSZ`:获取读缓冲区大小。
- `MR_IOC_SERIAL_GET_WR_BUFSZ`:获取写缓冲区大小。
- `MR_IOC_SERIAL_GET_RD_DATASZ`:获取读缓冲区数据大小。
- `MR_IOC_SERIAL_GET_WR_DATASZ`:获取写缓冲区数据大小。
- `MR_IOC_SERIAL_GET_RD_CALL`:获取读回调函数。
- `MR_IOC_SERIAL_GET_WR_CALL`:获取写回调函数。
### 设置/获取SERIAL设备配置
@@ -96,9 +96,9 @@ SERIAL设备配置
struct mr_serial_config config = MR_SERIAL_CONFIG_DEFAULT;
/* 设置SERIAL设备配置 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_CONFIG, &config);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_CONFIG, &config);
/* 获取SERIAL设备配置 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_CONFIG, &config);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_CONFIG, &config);
```
不依赖SERIAL接口
@@ -108,9 +108,9 @@ mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_CONFIG, &config);
int config[] = {115200, 8, 1, 0, 0, 0};
/* 设置SERIAL设备配置 */
mr_dev_ioctl(ds, MR_CTL_SET_CONFIG, &config);
mr_dev_ioctl(ds, MR_IOC_SCFG, &config);
/* 获取SERIAL设备配置 */
mr_dev_ioctl(ds, MR_CTL_GET_CONFIG, &config);
mr_dev_ioctl(ds, MR_IOC_GCFG, &config);
```
注:如未手动配置,默认配置为:
@@ -128,14 +128,14 @@ mr_dev_ioctl(ds, MR_CTL_GET_CONFIG, &config);
size_t size = 256;
/* 设置读缓冲区大小 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_RD_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_RD_BUFSZ, &size);
/* 获取读缓冲区大小 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_RD_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_RD_BUFSZ, &size);
/* 设置写缓冲区大小 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_WR_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_WR_BUFSZ, &size);
/* 获取写缓冲区大小 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_WR_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_WR_BUFSZ, &size);
```
不依赖SERIAL接口
@@ -144,14 +144,14 @@ mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_WR_BUFSZ, &size);
size_t size = 256;
/* 设置读缓冲区大小 */
mr_dev_ioctl(ds, MR_CTL_SET_RD_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SRBSZ, &size);
/* 获取读缓冲区大小 */
mr_dev_ioctl(ds, MR_CTL_GET_RD_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_GRBSZ, &size);
/* 设置写缓冲区大小 */
mr_dev_ioctl(ds, MR_CTL_SET_WR_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SWBSZ, &size);
/* 获取写缓冲区大小 */
mr_dev_ioctl(ds, MR_CTL_GET_WR_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_GWBSZ, &size);
```
注:如未手动配置,将使用 `Kconfig`中配置的大小默认为32Byte
@@ -159,15 +159,15 @@ mr_dev_ioctl(ds, MR_CTL_GET_WR_BUFSZ, &size);
### 清空读/写缓冲区
```c
mr_dev_ioctl(ds, MR_CTL_SERIAL_CLR_RD_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_CTL_SERIAL_CLR_WR_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_IOC_SERIAL_CLR_RD_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_IOC_SERIAL_CLR_WR_BUF, MR_NULL);
```
不依赖SERIAL接口
```c
mr_dev_ioctl(ds, MR_CTL_CLR_RD_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_CTL_CLR_WR_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_IOC_CRBD, MR_NULL);
mr_dev_ioctl(ds, MR_IOC_CWBD, MR_NULL);
```
### 获取读/写缓冲区数据大小
@@ -176,10 +176,10 @@ mr_dev_ioctl(ds, MR_CTL_CLR_WR_BUF, MR_NULL);
size_t size = 0;
/* 获取读缓冲区数据大小 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_RD_DATASZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_RD_DATASZ, &size);
/* 获取写缓冲区数据大小 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_WR_DATASZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_WR_DATASZ, &size);
```
不依赖SERIAL接口
@@ -188,68 +188,64 @@ mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_WR_DATASZ, &size);
size_t size = 0;
/* 获取读缓冲区数据大小 */
mr_dev_ioctl(ds, MR_CTL_GET_RD_DATASZ, &size);
mr_dev_ioctl(ds, MR_IOC_GRBDSZ, &size);
/* 获取写缓冲区数据大小 */
mr_dev_ioctl(ds, MR_CTL_GET_WR_DATASZ, &size);
mr_dev_ioctl(ds, MR_IOC_GWBDSZ, &size);
```
### 设置/获取读/写回调函数
```c
/* 定义回调函数 */
int call(int desc, void *args)
void fn(int desc, void *args)
{
/* 获取缓冲区数据大小 */
ssize_t data_size = *(ssize_t *)args;
/* 处理中断 */
return MR_EOK;
}
int (*callback)(int, void *args);
void (*callback)(int desc, void *args);
/* 设置读回调函数 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_RD_CALL, &call);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_RD_CALL, &fn);
/* 获取读回调函数 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_RD_CALL, &callback);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_RD_CALL, &callback);
/* 设置写回调函数 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_WR_CALL, &call);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_WR_CALL, &fn);
/* 获取写回调函数 */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_WR_CALL, &callback);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_WR_CALL, &callback);
```
不依赖SERIAL接口
```c
/* 定义回调函数 */
int call(int desc, void *args)
void fn(int desc, void *args)
{
/* 获取缓冲区数据大小 */
ssize_t data_size = *(ssize_t *)args;
/* 处理中断 */
return MR_EOK;
}
int (*callback)(int, void *args);
void (*callback)(int desc, void *args);
/* 设置读回调函数 */
mr_dev_ioctl(ds, MR_CTL_SET_RD_CALL, &call);
mr_dev_ioctl(ds, MR_IOC_SRCB, &fn);
/* 获取读回调函数 */
mr_dev_ioctl(ds, MR_CTL_GET_RD_CALL, &callback);
mr_dev_ioctl(ds, MR_IOC_GRCB, &callback);
/* 设置写回调函数 */
mr_dev_ioctl(ds, MR_CTL_SET_WR_CALL, &call);
mr_dev_ioctl(ds, MR_IOC_SWCB, &fn);
/* 获取写回调函数 */
mr_dev_ioctl(ds, MR_CTL_GET_WR_CALL, &callback);
mr_dev_ioctl(ds, MR_IOC_GWCB, &callback);
```
## 读取SERIAL设备数据
```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);
```
| 参数 | 描述 |
@@ -277,7 +273,7 @@ if (size < 0)
## 写入SERIAL设备数据
```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);
```
| 参数 | 描述 |
@@ -300,7 +296,7 @@ if (size < 0)
}
```
注:当未设置写缓冲区且未使用 `MR_OFLAG_NONBLOCK` 打开时将使用轮询方式同步写入数据。
注:当未设置写缓冲区且未使用 `MR_O_NONBLOCK` 打开时将使用轮询方式同步写入数据。
当设置写缓冲区后会将数据写入写缓冲区返回实际写入的数据大小通过中断或DMA异步发送数据发送完成后会触发写回调函数。
当有数据在异步发送时,写入锁将自动上锁,此时无法同步写入,直至异步发送完成。
@@ -312,24 +308,22 @@ if (size < 0)
/* 定义串口设备描述符 */
int serial_ds = -1;
int serial_init(void)
void serial_init(void)
{
/* 初始化串口 */
serial_ds = mr_dev_open("serial1", MR_OFLAG_RDWR);
serial_ds = mr_dev_open("serial1", MR_O_RDWR);
if (serial_ds < 0)
{
mr_printf("serial open failed: %s\r\n", mr_strerror(serial_ds));
return serial_ds;
return;
}
/* 设置串口配置 */
struct mr_serial_config config = MR_SERIAL_CONFIG_DEFAULT;
int ret = mr_dev_ioctl(serial_ds, MR_CTL_SERIAL_SET_CONFIG, &config);
int ret = mr_dev_ioctl(serial_ds, MR_IOC_SERIAL_SET_CONFIG, &config);
if (ret < 0)
{
mr_printf("serial set config failed: %s\r\n", mr_strerror(ret));
return ret;
}
return MR_EOK;
}
/* 导出到自动初始化APP级 */
MR_INIT_APP_EXPORT(serial_init);
@@ -349,4 +343,4 @@ int main(void)
}
```
电脑连接串口1在串口软件中进行回环测试发送数据后会在串口软件中显示接收到的数据。
连接串口1在串口软件中进行回环测试发送数据后会在串口软件中显示接收到的数据。

View File

@@ -20,23 +20,23 @@
## Open SERIAL 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 | Flags for opening the device |
| path | Device path |
| flags | Flags for opening the device |
| **Return Value** | |
| `>=0` | Device descriptor |
| `<0` | Error code |
- `name`: The SERIAL device name is usually `serialx`, such as `serial1`, `serial2`, `serial3`.
- `oflags`: Flags for opening the device,
supports `MR_OFLAG_RDONLY`, `MR_OFLAG_WRONLY`, `MR_OFLAG_RDWR`, `MR_OFLAG_NONBLOCK`.
- `path`: The SERIAL device name is usually `serialx`, such as `serial1`, `serial2`, `serial3`.
- `flags`: Flags for opening the device,
supports `MR_O_RDONLY`, `MR_O_WRONLY`, `MR_O_RDWR`, `MR_O_NONBLOCK`.
Note: When using it, different tasks should open the SERIAL device separately according to actual situations, and use
appropriate `oflags` for management and permission control to ensure they do not interfere with each other.
appropriate `flags` for management and permission control to ensure they do not interfere with each other.
## Close SERIAL Device
@@ -67,20 +67,20 @@ int mr_dev_ioctl(int desc, int cmd, void *args);
| `<0` | Error code |
- `cmd`: Command code, supports the following commands:
- `MR_CTL_SERIAL_SET_CONFIG`: Set SERIAL device configuration.
- `MR_CTL_SERIAL_SET_RD_BUFSZ`: Set read buffer size.
- `MR_CTL_SERIAL_SET_WR_BUFSZ`: Set write buffer size.
- `MR_CTL_SERIAL_CLR_RD_BUF`: Clear read buffer.
- `MR_CTL_SERIAL_CLR_WR_BUF`: Clear write buffer.
- `MR_CTL_SERIAL_SET_RD_CALL`: Set read callback function.
- `MR_CTL_SERIAL_SET_WR_CALL`: Set write callback function.
- `MR_CTL_SERIAL_GET_CONFIG`: Get SERIAL device configuration.
- `MR_CTL_SERIAL_GET_RD_BUFSZ`: Get read buffer size.
- `MR_CTL_SERIAL_GET_WR_BUFSZ`: Get write buffer size.
- `MR_CTL_SERIAL_GET_RD_DATASZ`: Get read buffer data size.
- `MR_CTL_SERIAL_GET_WR_DATASZ`: Get write buffer data size.
- `MR_CTL_SERIAL_GET_RD_CALL`: Get read callback function.
- `MR_CTL_SERIAL_GET_WR_CALL`: Get write callback function.
- `MR_IOC_SERIAL_SET_CONFIG`: Set SERIAL device configuration.
- `MR_IOC_SERIAL_SET_RD_BUFSZ`: Set read buffer size.
- `MR_IOC_SERIAL_SET_WR_BUFSZ`: Set write buffer size.
- `MR_IOC_SERIAL_CLR_RD_BUF`: Clear read buffer.
- `MR_IOC_SERIAL_CLR_WR_BUF`: Clear write buffer.
- `MR_IOC_SERIAL_SET_RD_CALL`: Set read callback function.
- `MR_IOC_SERIAL_SET_WR_CALL`: Set write callback function.
- `MR_IOC_SERIAL_GET_CONFIG`: Get SERIAL device configuration.
- `MR_IOC_SERIAL_GET_RD_BUFSZ`: Get read buffer size.
- `MR_IOC_SERIAL_GET_WR_BUFSZ`: Get write buffer size.
- `MR_IOC_SERIAL_GET_RD_DATASZ`: Get read buffer data size.
- `MR_IOC_SERIAL_GET_WR_DATASZ`: Get write buffer data size.
- `MR_IOC_SERIAL_GET_RD_CALL`: Get read callback function.
- `MR_IOC_SERIAL_GET_WR_CALL`: Get write callback function.
### Set/Get SERIAL Device Configuration
@@ -98,10 +98,10 @@ SERIAL device configuration:
struct mr_serial_config config = MR_SERIAL_CONFIG_DEFAULT;
/* Set SERIAL device configuration */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_CONFIG, &config);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_CONFIG, &config);
/* Get SERIAL device configuration */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_CONFIG, &config);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_CONFIG, &config);
```
Independent of SERIAL interface:
@@ -111,10 +111,10 @@ Independent of SERIAL interface:
int config[] = {115200, 8, 1, 0, 0, 0};
/* Set SERIAL device configuration */
mr_dev_ioctl(ds, MR_CTL_SET_CONFIG, &config);
mr_dev_ioctl(ds, MR_IOC_SCFG, &config);
/* Get SERIAL device configuration */
mr_dev_ioctl(ds, MR_CTL_GET_CONFIG, &config);
mr_dev_ioctl(ds, MR_IOC_GCFG, &config);
```
Note: If not configured manually, the default configuration is:
@@ -132,16 +132,16 @@ Note: If not configured manually, the default configuration is:
size_t size = 256;
/* Set read buffer size */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_RD_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_RD_BUFSZ, &size);
/* Get read buffer size */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_RD_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_RD_BUFSZ, &size);
/* Set write buffer size */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_WR_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_WR_BUFSZ, &size);
/* Get write buffer size */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_WR_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_WR_BUFSZ, &size);
```
Independent of SERIAL interface:
@@ -150,16 +150,16 @@ Independent of SERIAL interface:
size_t size = 256;
/* Set read buffer size */
mr_dev_ioctl(ds, MR_CTL_SET_RD_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SRBSZ, &size);
/* Get read buffer size */
mr_dev_ioctl(ds, MR_CTL_GET_RD_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_GRBSZ, &size);
/* Set write buffer size */
mr_dev_ioctl(ds, MR_CTL_SET_WR_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_SWBSZ, &size);
/* Get write buffer size */
mr_dev_ioctl(ds, MR_CTL_GET_WR_BUFSZ, &size);
mr_dev_ioctl(ds, MR_IOC_GWBSZ, &size);
```
Note: If not configured manually, the size configured in `Kconfig` will be used (default is 32Byte).
@@ -167,15 +167,15 @@ Note: If not configured manually, the size configured in `Kconfig` will be used
### Clear Read/Write Buffer
```c
mr_dev_ioctl(ds, MR_CTL_SERIAL_CLR_RD_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_CTL_SERIAL_CLR_WR_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_IOC_SERIAL_CLR_RD_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_IOC_SERIAL_CLR_WR_BUF, MR_NULL);
```
Independent of SERIAL interface:
```c
mr_dev_ioctl(ds, MR_CTL_CLR_RD_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_CTL_CLR_WR_BUF, MR_NULL);
mr_dev_ioctl(ds, MR_IOC_CRBD, MR_NULL);
mr_dev_ioctl(ds, MR_IOC_CWBD, MR_NULL);
```
### Get Read/Write Buffer Data Size
@@ -184,10 +184,10 @@ mr_dev_ioctl(ds, MR_CTL_CLR_WR_BUF, MR_NULL);
size_t size = 0;
/* Get read buffer data size */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_RD_DATASZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_RD_DATASZ, &size);
/* Get write buffer data size */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_WR_DATASZ, &size);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_WR_DATASZ, &size);
```
Independent of SERIAL interface:
@@ -196,72 +196,68 @@ Independent of SERIAL interface:
size_t size = 0;
/* Get read buffer data size */
mr_dev_ioctl(ds, MR_CTL_GET_RD_DATASZ, &size);
mr_dev_ioctl(ds, MR_IOC_GRBDSZ, &size);
/* Get write buffer data size */
mr_dev_ioctl(ds, MR_CTL_GET_WR_DATASZ, &size);
mr_dev_ioctl(ds, MR_IOC_GWBDSZ, &size);
```
### Set/Get Read/Write Callback Function
```c
/* Define callback function */
int call(int desc, void *args)
void fn(int desc, void *args)
{
/* Get buffer data size */
ssize_t data_size = *(ssize_t *)args;
/* Handle interrupt */
return MR_EOK;
}
int (*callback)(int, void *args);
void (*callback)(int desc, void *args);
/* Set read callback function */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_RD_CALL, &call);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_RD_CALL, &fn);
/* Get read callback function */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_RD_CALL, &callback);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_RD_CALL, &callback);
/* Set write callback function */
mr_dev_ioctl(ds, MR_CTL_SERIAL_SET_WR_CALL, &call);
mr_dev_ioctl(ds, MR_IOC_SERIAL_SET_WR_CALL, &fn);
/* Get write callback function */
mr_dev_ioctl(ds, MR_CTL_SERIAL_GET_WR_CALL, &callback);
mr_dev_ioctl(ds, MR_IOC_SERIAL_GET_WR_CALL, &callback);
```
Independent of SERIAL interface:
```c
/* Define callback function */
int call(int desc, void *args)
void fn(int desc, void *args)
{
/* Get buffer data size */
ssize_t data_size = *(ssize_t *)args;
/* Handle interrupt */
return MR_EOK;
}
int (*callback)(int, void *args);
void (*callback)(int desc, void *args);
/* Set read callback function */
mr_dev_ioctl(ds, MR_CTL_SET_RD_CALL, &call);
mr_dev_ioctl(ds, MR_IOC_SRCB, &fn);
/* Get read callback function */
mr_dev_ioctl(ds, MR_CTL_GET_RD_CALL, &callback);
mr_dev_ioctl(ds, MR_IOC_GRCB, &callback);
/* Set write callback function */
mr_dev_ioctl(ds, MR_CTL_SET_WR_CALL, &call);
mr_dev_ioctl(ds, MR_IOC_SWCB, &fn);
/* Get write callback function */
mr_dev_ioctl(ds, MR_CTL_GET_WR_CALL, &callback);
mr_dev_ioctl(ds, MR_IOC_GWCB, &callback);
```
## Read Data from SERIAL Device
```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 |
@@ -291,7 +287,7 @@ number of bytes read).
## Write Data to SERIAL Device
```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 |
@@ -314,7 +310,7 @@ if (size < 0)
}
```
Note: When no write buffer is set and not using `MR_OFLAG_NONBLOCK` for opening, it will use polling mode for
Note: When no write buffer is set and not using `MR_O_NONBLOCK` for opening, it will use polling mode for
synchronous writing. When a write buffer is set, it will write the data to the write buffer (return the actual number of
bytes written), and asynchronously send the data through interrupt or DMA. The write callback function will be triggered
after sending is complete. When data is being asynchronously sent, the write lock will automatically be locked, and
@@ -328,25 +324,23 @@ synchronous writing is not allowed until asynchronous sending is complete.
/* Define serial device descriptor */
int serial_ds = -1;
int serial_init(void)
void serial_init(void)
{
/* Initialize serial */
serial_ds = mr_dev_open("serial1", MR_OFLAG_RDWR);
serial_ds = mr_dev_open("serial1", MR_O_RDWR);
if (serial_ds < 0)
{
mr_printf("serial open failed: %s\r\n", mr_strerror(serial_ds));
return serial_ds;
mr_printf("serial open failed: %s\r\n", mr_strerror(serial_ds));
return;
}
/* Set serial configuration */
struct mr_serial_config config = MR_SERIAL_CONFIG_DEFAULT;
int ret = mr_dev_ioctl(serial_ds, MR_CTL_SERIAL_SET_CONFIG, &config);
int ret = mr_dev_ioctl(serial_ds, MR_IOC_SERIAL_SET_CONFIG, &config);
if (ret < 0)
{
mr_printf("serial set config failed: %s\r\n", mr_strerror(ret));
return ret;
mr_printf("serial set config failed: %s\r\n", mr_strerror(ret));
}
return MR_EOK;
}
/* Export to auto initialization (APP level) */
MR_INIT_APP_EXPORT(serial_init);
@@ -366,5 +360,5 @@ int main(void)
}
```
Connect the computer to serial port 1. Loopback test can be performed by sending data in the serial port software and
Connect the serial port 1. Loopback test can be performed by sending data in the serial port software and
seeing the received data displayed in the serial port software.