1.修复跟设备ops空指针访问。
2.新增设备手动设置操作者api。 3.PIN设备读写成功获得操作权后将释放操作锁(操作锁仅对PIN的open、close、ioctl时有效)。 4.日志输出优化。
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ...);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user