1.修复跟设备ops空指针访问。

2.新增设备手动设置操作者api。
3.PIN设备读写成功获得操作权后将释放操作锁(操作锁仅对PIN的open、close、ioctl时有效)。
4.日志输出优化。
This commit is contained in:
MacRsh
2024-04-28 23:51:14 +08:00
parent af87b83d4c
commit bce4d10943
7 changed files with 182 additions and 38 deletions

View File

@@ -26,8 +26,8 @@ extern "C" {
#define MR_PIN_MODE_OUTPUT (1) /**< Output push-pull mode */
#define MR_PIN_MODE_OUTPUT_OD (2) /**< Output open-drain mode */
#define MR_PIN_MODE_INPUT (3) /**< Input mode */
#define MR_PIN_MODE_INPUT_DOWN (4) /**< Input pull-down mode */
#define MR_PIN_MODE_INPUT_UP (5) /**< Input pull-up mode */
#define MR_PIN_MODE_INPUT_UP (4) /**< Input pull-up mode */
#define MR_PIN_MODE_INPUT_DOWN (5) /**< Input pull-down mode */
#define MR_PIN_MODE_IRQ_RISING (6) /**< Interrupt rising edge mode */
#define MR_PIN_MODE_IRQ_FALLING (7) /**< Interrupt falling edge mode */
#define MR_PIN_MODE_IRQ_EDGE (8) /**< Interrupt edge mode */

View File

@@ -130,6 +130,9 @@ static ssize_t pin_read(struct mr_device *device, int pos, void *buf,
uint8_t *rbuf = (uint8_t *)buf;
ssize_t rcount;
/* Release the read operator lock */
_MR_DEVICE_OPERATOR_RD_CLR(device);
#ifdef MR_USE_PIN_CHECK
struct mr_pin *pin = (struct mr_pin *)device;
@@ -165,6 +168,9 @@ static ssize_t pin_write(struct mr_device *device, int pos, const void *buf,
const uint8_t *wbuf = (const uint8_t *)buf;
ssize_t wcount;
/* Release the write operator lock */
_MR_DEVICE_OPERATOR_WR_CLR(device);
#ifdef MR_USE_PIN_CHECK
struct mr_pin *pin = (struct mr_pin *)device;

View File

@@ -95,7 +95,7 @@ MR_INLINE ssize_t _serial_write_fifo(struct mr_serial *serial,
int ret = ops->send_int_configure(driver, true);
if (ret >= 0)
{
/* Data has been written to the FIFO, if the boot send fails, wait
/* Data has been written to the FIFO, if the boot sent fails, wait
* for the next retry startup */
return wcount;
}
@@ -134,7 +134,7 @@ static int serial_open(struct mr_device *device)
return ret;
}
/* Allocate fifo */
/* Allocate FIFO */
mr_fifo_allocate(&serial->rfifo, serial->rfifo_size);
mr_fifo_allocate(&serial->wfifo, serial->wfifo_size);
return MR_EOK;
@@ -153,7 +153,7 @@ static int serial_close(struct mr_device *device)
return ret;
}
/* Release fifo */
/* Release FIFO */
mr_fifo_free(&serial->rfifo);
mr_fifo_free(&serial->wfifo);
return MR_EOK;
@@ -164,7 +164,7 @@ static ssize_t serial_read(struct mr_device *device, int pos, void *buf,
{
struct mr_serial *serial = (struct mr_serial *)device;
/* If fifo is set, read from fifo */
/* If FIFO is set, read from FIFO */
if (mr_fifo_size_get(&serial->rfifo) != 0)
{
return _serial_read_fifo(serial, buf, count);
@@ -179,7 +179,7 @@ static ssize_t serial_write(struct mr_device *device, int pos, const void *buf,
{
struct mr_serial *serial = (struct mr_serial *)device;
/* If fifo is set, write from fifo */
/* If FIFO is set, write from FIFO */
if (mr_fifo_size_get(&serial->wfifo) != 0)
{
return _serial_write_fifo(serial, buf, count);

View File

@@ -55,6 +55,8 @@ void mr_delay_ms(size_t ms);
const char *mr_strerror(int error);
int mr_printf_output(const char *buf, size_t size);
int mr_printf(const char *fmt, ...);
int mr_log_printf_output(const char *buf, size_t size);
int mr_log_printf(const char *tag, const char *fmt, ...);
/** @} */

View File

@@ -193,25 +193,29 @@ extern "C" {
* @{
*/
#define MR_LOG_TAG "null"
#define MR_LOG_TAG ("null")
#ifdef MR_USE_LOG_ERROR
#define MR_LOG_E(_fmt, ...) mr_printf("[E/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
#define MR_LOG_E(_fmt, ...) \
mr_log_printf(MR_LOG_TAG, "[E/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
#else
#define MR_LOG_E(_fmt, ...)
#endif /* MR_USE_LOG_ERROR */
#ifdef MR_USE_LOG_WARN
#define MR_LOG_W(_fmt, ...) mr_printf("[W/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
#define MR_LOG_W(_fmt, ...) \
mr_log_printf(MR_LOG_TAG, "[W/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
#else
#define MR_LOG_W(_fmt, ...)
#endif /* MR_USE_LOG_WARN */
#ifdef MR_USE_LOG_INFO
#define MR_LOG_I(_fmt, ...) mr_printf("[I/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
#define MR_LOG_I(_fmt, ...) \
mr_log_printf(MR_LOG_TAG, "[I/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
#else
#define MR_LOG_I(_fmt, ...)
#endif /* MR_USE_LOG_INFO */
#ifdef MR_USE_LOG_DEBUG
#define MR_LOG_D(_fmt, ...) mr_printf("[D/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
#define MR_LOG_D(_fmt, ...) \
mr_log_printf(MR_LOG_TAG, "[D/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
#else
#define MR_LOG_D(_fmt, ...)
#endif /* MR_USE_LOG_DEBUG */
@@ -361,6 +365,99 @@ MR_INLINE int mr_list_is_inited(struct mr_list *list)
* @{
*/
/**
* @brief This macro function gets the device read operator.
*
* @param _device The device.
*/
#define _MR_DEVICE_OPERATOR_RD_GET(_device) \
((((_device)->lock & _MR_OPERATE_MASK_RD) >> 16) - 1)
/**
* @brief This macro function gets the device write operator.
*
* @param _device The device.
*/
#define _MR_DEVICE_OPERATOR_WR_GET(_device) \
(((_device)->lock & _MR_OPERATE_MASK_WR) - 1)
/**
* @brief This macro function gets the device operator.
*
* @param _device The device.
*
* @note This feature is only available for non-full-duplex devices.
*/
#define _MR_DEVICE_OPERATOR_GET(_device) \
(((_device)->lock & _MR_OPERATE_MASK_WR) - 1)
/**
* @brief This macro function sets the device read operator.
*
* @param _device The device.
* @param _operator The operator.
*/
#define _MR_DEVICE_OPERATOR_RD_SET(_device, _operator) \
(((_device)->lock = \
((_device)->lock & ~_MR_OPERATE_MASK_RD) | ((_operator + 1) << 16)))
/**
* @brief This macro function sets the device write operator.
*
* @param _device The device.
* @param _operator The operator.
*/
#define _MR_DEVICE_OPERATOR_WR_SET(_device, _operator) \
(((_device)->lock = \
((_device)->lock & ~_MR_OPERATE_MASK_WR) | (_operator + 1)))
/**
* @brief This macro function sets the device operator.
*
* @param _device The device.
* @param _operator The operator.
*
* @note This feature is only available for non-full-duplex devices.
*/
#define _MR_DEVICE_OPERATOR_SET(_device, _operator) \
(_MR_DEVICE_OPERATOR_RD_SET(_device, _operator), \
_MR_DEVICE_OPERATOR_WR_SET(_device, _operator))
/**
* @brief This macro function clears the device operator.
*
* @param _device The device.
*/
#define _MR_DEVICE_OPERATOR_RD_CLR(_device) \
_MR_DEVICE_OPERATOR_RD_SET(_device, -1)
/**
* @brief This macro function clears the device operator.
*
* @param _device The device.
*/
#define _MR_DEVICE_OPERATOR_WR_CLR(_device) \
_MR_DEVICE_OPERATOR_WR_SET(_device, -1)
/**
* @brief This macro function clears the device operator.
*
* @param _device The device.
*
* @note This feature is only available for non-full-duplex devices.
*/
#define _MR_DEVICE_OPERATOR_CLR(_device) \
_MR_DEVICE_OPERATOR_SET(_device, -1)
/**
* @brief This macro function gets the device parent.
*
* @param _device The device.
*
* @return The device parent.
*/
#define _MR_DEVICE_PARENT_GET(_device) ((void *)((_device)->parent))
/**
* @brief This macro function gets the device driver.
*

View File

@@ -403,6 +403,7 @@ static int _device_register(struct mr_device *device, const char *path,
/* Set default ops if not specified */
ops = (ops == NULL) ? &null_ops : ops;
to_device->ops = (to_device->ops == NULL) ? &null_ops : to_device->ops;
/* Initialize the device */
mr_list_init(&device->list);
@@ -456,8 +457,8 @@ static int _device_unregister(struct mr_device *device)
ret = parent->ops->detach(parent, device);
if (ret < 0)
{
/* Revert the list operation */
mr_list_insert_before(&parent->clist, &device->list);
/* Detach failed, revert the registration */
mr_list_insert_after(&parent->clist, &device->list);
goto _exit;
}
}
@@ -812,29 +813,6 @@ size_t _mr_descriptor_map_get(struct mr_descriptor **descriptor_map)
return sizeof(_descriptor_map) / sizeof(struct mr_descriptor);
}
/**
* @brief This function gets the operators of the device
*
* @param device The device.
* @param read The read operator.
* @param write The write operator.
*
* @note The operators are device descriptors.
*/
void _mr_device_operators_get(struct mr_device *device, int *read, int *write)
{
MR_ASSERT(device != NULL);
if (read != NULL)
{
*read = ((int)(device->lock & _MR_OPERATE_MASK_RD) >> 16) - 1;
}
if (write != NULL)
{
*write = ((int)(device->lock & _MR_OPERATE_MASK_WR)) - 1;
}
}
/**
* @brief This function register a device to a path.
*

View File

@@ -190,7 +190,7 @@ MR_WEAK int mr_printf_output(const char *buf, size_t size)
descriptor = ret;
}
/* Write data to the serial device */
/* Write data to the device */
return (int)mr_device_write(descriptor, buf, size);
}
@@ -219,6 +219,67 @@ int mr_printf(const char *fmt, ...)
return mr_printf_output(buf, ret);
}
/**
* @brief This function log printf output.
*
* @param buf The buffer to output.
* @param size The size of the buffer.
*
* @return The size of the actual output, otherwise an error code.
*/
MR_WEAK int mr_log_printf_output(const char *buf, size_t size)
{
static int descriptor = -1;
/* Try to open the serial device */
if (descriptor == -1)
{
#ifndef MR_CFG_LOG_PRINTF_NAME
#define MR_CFG_LOG_PRINTF_NAME ("serial1")
#endif /* MR_CFG_LOG_PRINTF_NAME */
int ret = mr_device_open(MR_CFG_LOG_PRINTF_NAME, MR_FLAG_WRONLY);
if (ret < 0)
{
return ret;
}
descriptor = ret;
}
/* Write data to the device */
return (int)mr_device_write(descriptor, buf, size);
}
/**
* @brief This function log printf.
*
* @param tag The log tag.
* @param fmt The format string.
* @param ... The arguments.
*
* @return The actual output size.
*/
int mr_log_printf(const char *tag, const char *fmt, ...)
{
#ifndef MR_CFG_LOG_PRINTF_BUFSZ
#define MR_CFG_LOG_PRINTF_BUFSZ (256)
#endif /* MR_CFG_LOG_PRINTF_BUFSZ */
char buf[MR_CFG_LOG_PRINTF_BUFSZ] = {0};
va_list args;
if (strcmp(tag, "null") == 0)
{
return 0;
}
/* Format the string */
va_start(args, fmt);
int ret = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
/* Output the string */
return mr_log_printf_output(buf, ret);
}
/**
* @brief This function assert handler.
*