1.更新内置命令名。2.移除驱动类型。3.设备回调支持每个设备描述符独立挂载,不限上限。4.offset修改为position,更强调写入位置概念。5.设备中断概念修正,父系设备中断不仅唤起自身的回调函数,同时也将递归唤醒子设备回调函数(更强调依赖关系)。

This commit is contained in:
MacRsh
2024-01-31 22:31:10 +08:00
parent 2158ff700a
commit 26197d3b0d
2 changed files with 630 additions and 619 deletions

View File

@@ -20,82 +20,92 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/** /**
* @brief Mr-library version. * @addtogroup Version
* @{
*/ */
#define _MR_VERSION_MAJOR 0 /**< Major version */ #define MR_VERSION_MAJOR 0 /**< Major version (X.y.z) */
#define _MR_VERSION_MINOR 0 /**< Minor version */ #define MR_VERSION_MINOR 0 /**< Minor version (x.Y.z) */
#define _MR_VERSION_PATCH 8 /**< Patch version */ #define MR_VERSION_PATCH 9 /**< Patch version (x.y.Z) */
#define _MR_VERSION_STR(major, minor, patch) \
MR_STR(major) "." MR_STR(minor) "." MR_STR(patch)
#define MR_VERSION (_MR_VERSION_MAJOR << 16 | _MR_VERSION_MINOR << 8 | _MR_VERSION_PATCH)
#define MR_VERSION_STR _MR_VERSION_STR(_MR_VERSION_MAJOR, _MR_VERSION_MINOR, _MR_VERSION_PATCH)
/** /**
* @brief Compiler related. * @brief Version hex.
*
* @note [23:16] major version, [15:8] minor version, [7:0] patch version, [31:24] reserved.
*/
#define MR_VERSION (MR_VERSION_MAJOR << 16 | MR_VERSION_MINOR << 8 | MR_VERSION_PATCH)
/** @} */
/**
* @addtogroup Compiler
* @{
*/ */
#if defined(__ARMCC_VERSION) #if defined(__ARMCC_VERSION)
#define MR_SECTION(x) __attribute__((section(x))) #define MR_SECTION(x) __attribute__((section(x))) /**< Section */
#define MR_USED __attribute__((used)) #define MR_USED __attribute__((used)) /**< Used */
#define MR_WEAK __attribute__((weak)) #define MR_WEAK __attribute__((weak)) /**< Weak */
#define MR_INLINE static __inline #define MR_INLINE static __inline /**< Inline */
typedef int ssize_t; typedef int ssize_t; /**< ssize_t type */
#elif defined (__IAR_SYSTEMS_ICC__) #elif defined (__IAR_SYSTEMS_ICC__)
#define MR_SECTION(x) @ x #define MR_SECTION(x) @ x /**< Section */
#define MR_USED __root #define MR_USED __root /**< Used */
#define MR_WEAK __weak #define MR_WEAK __weak /**< Weak */
#define MR_INLINE static inline #define MR_INLINE static inline /**< Inline */
#elif defined (__GNUC__) #elif defined (__GNUC__)
#define MR_SECTION(x) __attribute__((section(x))) #define MR_SECTION(x) __attribute__((section(x))) /**< Section */
#define MR_USED __attribute__((used)) #define MR_USED __attribute__((used)) /**< Used */
#define MR_WEAK __attribute__((weak)) #define MR_WEAK __attribute__((weak)) /**< Weak */
#define MR_INLINE static __inline #define MR_INLINE static __inline /**< Inline */
#elif defined (__ADSPBLACKFIN__) #elif defined (__ADSPBLACKFIN__)
#define MR_SECTION(x) __attribute__((section(x))) #define MR_SECTION(x) __attribute__((section(x))) /**< Section */
#define MR_USED __attribute__((used)) #define MR_USED __attribute__((used)) /**< Used */
#define MR_WEAK __attribute__((weak)) #define MR_WEAK __attribute__((weak)) /**< Weak */
#define MR_INLINE static inline #define MR_INLINE static inline /**< Inline */
#elif defined (_MSC_VER) #elif defined (_MSC_VER)
#define MR_SECTION(x) #define MR_SECTION(x) /**< Section */
#define MR_USED #define MR_USED /**< Used */
#define MR_WEAK #define MR_WEAK /**< Weak */
#define MR_INLINE static __inline #define MR_INLINE static __inline /**< Inline */
#elif defined (__TASKING__) #elif defined (__TASKING__)
#define MR_SECTION(x) __attribute__((section(x))) #define MR_SECTION(x) __attribute__((section(x))) /**< Section */
#define MR_USED __attribute__((used, protect)) #define MR_USED \
#define MR_WEAK __attribute__((weak)) __attribute__((used, protect)) /**< Used */
#define MR_INLINE static inline #define MR_WEAK __attribute__((weak)) /**< Weak */
#define MR_INLINE static inline /**< Inline */
#else
#define MR_SECTION(x) __attribute__((section(x))) /**< Section */
#define MR_USED __attribute__((used)) /**< Used */
#define MR_WEAK __attribute__((weak)) /**< Weak */
#define MR_INLINE static __inline /**< Inline */
#endif /* __ARMCC_VERSION */ #endif /* __ARMCC_VERSION */
/** @} */
typedef int (*mr_init_fn_t)(void);
/** /**
* @brief Exports an auto initialization function with level. * @addtogroup Auto-init
* @{
*/ */
#define _MR_INIT_EXPORT(fn, level) \ typedef void (*mr_init_fn_t)(void); /**< Auto initialization function */
#define MR_INIT_EXPORT(fn, level) \
MR_USED const mr_init_fn_t _mr_auto_init_##fn MR_SECTION("mr_auto_init."level) = fn MR_USED const mr_init_fn_t _mr_auto_init_##fn MR_SECTION("mr_auto_init."level) = fn
#define MR_INIT_BOARD_EXPORT(fn) MR_INIT_EXPORT(fn, "1") /**< Exports a Board initialization function */
#define MR_INIT_DRV_EXPORT(fn) MR_INIT_EXPORT(fn, "2") /**< Exports a Driver initialization function */
#define MR_INIT_DEV_EXPORT(fn) MR_INIT_EXPORT(fn, "3") /**< Exports a Device initialization function */
#define MR_INIT_APP_EXPORT(fn) MR_INIT_EXPORT(fn, "4") /**< Exports an App initialization function */
/** @} */
/** /**
* @brief Exports a board auto initialization function. * @addtogroup Basic
* @{
*/ */
#define MR_INIT_BOARD_EXPORT(fn) _MR_INIT_EXPORT(fn, "1") #define MR_NULL ((void *)0) /**< Null pointer */
#define MR_DISABLE (0) /**< Disable */
#define MR_ENABLE (1) /**< Enable */
#define MR_FALSE (0) /**< False */
#define MR_TRUE (1) /**< True */
/** @} */
/** /**
* @brief Exports a driver auto initialization function. * @addtogroup Error
*/ * @{
#define MR_INIT_DRV_EXPORT(fn) _MR_INIT_EXPORT(fn, "2")
/**
* @brief Exports a device auto initialization function.
*/
#define MR_INIT_DEV_EXPORT(fn) _MR_INIT_EXPORT(fn, "3")
/**
* @brief Exports a app auto initialization function.
*/
#define MR_INIT_APP_EXPORT(fn) _MR_INIT_EXPORT(fn, "4")
/**
* @brief Error code.
*/ */
#define MR_EOK (0) /**< No error */ #define MR_EOK (0) /**< No error */
#define MR_ENOMEM (-1) /**< No enough memory */ #define MR_ENOMEM (-1) /**< No enough memory */
@@ -105,32 +115,43 @@ typedef int (*mr_init_fn_t)(void);
#define MR_EEXIST (-5) /**< Exists */ #define MR_EEXIST (-5) /**< Exists */
#define MR_ENOTSUP (-6) /**< Operation not supported */ #define MR_ENOTSUP (-6) /**< Operation not supported */
#define MR_EINVAL (-7) /**< Invalid argument */ #define MR_EINVAL (-7) /**< Invalid argument */
/** @} */
/** /**
* @brief Null pointer. * @addtogroup Memory
* @{
*/ */
#define MR_NULL ((void *)0)
/** /**
* @brief Disable/enable. * @brief Heap block structure.
*/ */
#define MR_DISABLE (0) /**< Disable */ struct mr_heap_block
#define MR_ENABLE (1) /**< Enable */ {
struct mr_heap_block *next; /**< Point to next block */
uint32_t size: 31; /**< Size of this block */
uint32_t allocated: 1; /**< Allocated flag */
};
/** @} */
/** /**
* @brief True/false. * @addtogroup List
* @{
*/ */
#define MR_FALSE (0) /**< False */
#define MR_TRUE (1) /**< True */
/** /**
* @brief Double linked list structure. * @brief List structure.
*/ */
struct mr_list struct mr_list
{ {
struct mr_list *next; /**< Point to next node */ struct mr_list *next; /**< Point to next node */
struct mr_list *prev; /**< Point to prev node */ struct mr_list *prev; /**< Point to prev node */
}; };
/** @} */
/**
* @addtogroup Ringbuffer
* @{
*/
/** /**
* @brief Ring buffer structure. * @brief Ring buffer structure.
@@ -145,6 +166,12 @@ struct mr_ringbuf
size_t read_index; /**< Read index */ size_t read_index; /**< Read index */
size_t write_index; /**< Write index */ size_t write_index; /**< Write index */
}; };
/** @} */
/**
* @addtogroup AVL-tree
* @{
*/
/** /**
* @brief AVL tree structure. * @brief AVL tree structure.
@@ -156,108 +183,63 @@ struct mr_avl
struct mr_avl *left_child; /**< Point to left-child node */ struct mr_avl *left_child; /**< Point to left-child node */
struct mr_avl *right_child; /**< Point to right-child node */ struct mr_avl *right_child; /**< Point to right-child node */
}; };
/** @} */
/** /**
* @brief Synchronous/asynchronous operation flag. * @addtogroup Device
* @{
*/ */
#define MR_MAGIC_NUMBER (0xdeadbeef) /**< Magic number */
#define MR_SYNC (0) /**< Synchronous */ #define MR_SYNC (0) /**< Synchronous */
#define MR_ASYNC (1) /**< Asynchronous */ #define MR_ASYNC (1) /**< Asynchronous */
/** /* [31:24] are for lock, [23:0] reserved */
* @brief Magic number. #define MR_LOCK_RD (0x01 << 24) /**< Read lock */
*/ #define MR_LOCK_WR (0x02 << 24) /**< Write lock */
#define MR_MAGIC_NUMBER (0xdeadbeef) #define MR_LOCK_RDWR (0x03 << 24) /**< Read/write lock */
#define MR_LOCK_NONBLOCK (0x04 << 24) /**< Non-blocking lock */
#define MR_LOCK_SLEEP (0x08 << 24) /**< Sleep lock */
/** /* [31:24] are for basic flags, [23:0] can define user flags */
* @brief Lock flags. #define MR_O_CLOSED (0) /**< Closed flag */
*/ #define MR_O_QUERY (0) /**< Query flag */
#define MR_LFLAG_RD (0x01) /**< Read lock */ #define MR_O_RDONLY (0x01 << 24) /**< Read only flag */
#define MR_LFLAG_WR (0x02) /**< Write lock */ #define MR_O_WRONLY (0x02 << 24) /**< Write only flag */
#define MR_LFLAG_RDWR (0x03) /**< Read/write lock */ #define MR_O_RDWR (0x03 << 24) /**< Read/write flag */
#define MR_LFLAG_NONBLOCK (0x04) /**< Non-blocking lock */ #define MR_O_NONBLOCK (0x04 << 24) /**< Non-blocking flag */
#define MR_LFLAG_SLEEP (0x08) /**< Sleep lock */
/** /* [31:24] are for basic commands, [23:0] can define user commands. (>0): user -> device, (<0): user <- device */
* @brief Open flags. #define MR_IOC_SPOS (0x01 << 24) /**< Set position command */
*/ #define MR_IOC_SRCB (0x02 << 24) /**< Set read callback command */
#define MR_OFLAG_CLOSED (0) /**< Closed */ #define MR_IOC_SWCB (0x03 << 24) /**< Set write callback command */
#define MR_OFLAG_RDONLY (0x01) /**< Read only */ #define MR_IOC_SCFG (0x04 << 24) /**< Set configuration command */
#define MR_OFLAG_WRONLY (0x02) /**< Write only */ #define MR_IOC_SRBSZ (0x05 << 24) /**< Set read buffer size command */
#define MR_OFLAG_RDWR (0x03) /**< Read/write */ #define MR_IOC_SWBSZ (0x06 << 24) /**< Set write buffer size command */
#define MR_OFLAG_NONBLOCK (0x04) /**< Non-blocking */ #define MR_IOC_CRBD (0x07 << 24) /**< Clear read buffer data command */
#define MR_OFLAG_DMA (0x08) /**< DMA */ #define MR_IOC_CWBD (0x08 << 24) /**< Clear write buffer data command */
/** #define MR_IOC_GPOS (-(0x01 << 24)) /**< Get position command */
* @brief Support flags. #define MR_IOC_GRCB (-(0x02 << 24)) /**< Get read callback command */
*/ #define MR_IOC_GWCB (-(0x03 << 24)) /**< Get write callback command */
#define MR_SFLAG_NONRDWR MR_OFLAG_CLOSED /**< Non-read/write */ #define MR_IOC_GCFG (-(0x04 << 24)) /**< Get configuration command */
#define MR_SFLAG_RDONLY MR_OFLAG_RDONLY /**< Read only */ #define MR_IOC_GRBSZ (-(0x05 << 24)) /**< Get read buffer size command */
#define MR_SFLAG_WRONLY MR_OFLAG_WRONLY /**< Write only */ #define MR_IOC_GWBSZ (-(0x06 << 24)) /**< Get write buffer size command */
#define MR_SFLAG_RDWR MR_OFLAG_RDWR /**< Read/write */ #define MR_IOC_GRBDSZ (-(0x07 << 24)) /**< Get read buffer data size command */
#define MR_SFLAG_NONBLOCK MR_OFLAG_NONBLOCK /**< Non-blocking */ #define MR_IOC_GWBDSZ (-(0x08 << 24)) /**< Get write buffer data size command */
#define MR_SFLAG_DMA MR_OFLAG_DMA /**< DMA */
#define MR_SFLAG_NONDRV (0x10) /**< Non-driver */
#define MR_SFLAG_ONLY (0x20) /**< Only */
/** /* [31:24] are for interrupt flags, [23:0] can define user flags */
* @brief Device control command. #define MR_ISR_RD (0x01 << 24) /**< Read interrupt */
* #define MR_ISR_WR (0x02 << 24) /**< Write interrupt */
* @note [31:24] are for basic commands, [23:0] can define custom commands. #define MR_ISR_MASK (0x7f << 24) /**< Interrupt mask */
* (> 0) is set command, (< 0) is get command.
*/
#define MR_CTL_SET_OFFSET (0x02 << 24) /**< Set offset */
#define MR_CTL_SET_RD_CALL (0x06 << 24) /**< Set read callback */
#define MR_CTL_SET_WR_CALL (0x07 << 24) /**< Set write callback */
#define MR_CTL_SET_CONFIG (0x08 << 24) /**< Set configuration */
#define MR_CTL_SET_RD_BUFSZ (0x09 << 24) /**< Set read buffer size */
#define MR_CTL_SET_WR_BUFSZ (0x0a << 24) /**< Set write buffer size */
#define MR_CTL_CLR_RD_BUF (0x0b << 24) /**< Clear read buffer */
#define MR_CTL_CLR_WR_BUF (0x0c << 24) /**< Clear write buffer */
#define MR_CTL_GET_OFLAGS (-(0x01 << 24)) /**< Get open flags */
#define MR_CTL_GET_OFFSET (-(0x02 << 24)) /**< Get offset */
#define MR_CTL_GET_SFLAGS (-(0x03 << 24)) /**< Get support flags */
#define MR_CTL_GET_PATH (-(0x04 << 24)) /**< Get path */
#define MR_CTL_GET_NAME (-(0x05 << 24)) /**< Get name */
#define MR_CTL_GET_RD_CALL (-(0x06 << 24)) /**< Get read callback */
#define MR_CTL_GET_WR_CALL (-(0x07 << 24)) /**< Get write callback */
#define MR_CTL_GET_CONFIG (-(0x08 << 24)) /**< Get configuration */
#define MR_CTL_GET_RD_BUFSZ (-(0x09 << 24)) /**< Get read buffer size */
#define MR_CTL_GET_WR_BUFSZ (-(0x0a << 24)) /**< Get write buffer size */
#define MR_CTL_GET_RD_DATASZ (-(0x0b << 24)) /**< Get read data size */
#define MR_CTL_GET_WR_DATASZ (-(0x0c << 24)) /**< Get write data size */
/**
* @brief ISR event.
*/
#define MR_ISR_RD (0x01) /**< Read interrupt */
#define MR_ISR_WR (0x02) /**< Write interrupt */
#define MR_ISR_MASK (0xff) /**< Interrupt mask */
/**
* @brief Driver types.
*/
enum mr_drv_type
{
Mr_Drv_Type_ADC, /**< ADC */
Mr_Drv_Type_CAN, /**< CAN */
Mr_Drv_Type_DAC, /**< DAC */
Mr_Drv_Type_I2C, /**< I2C */
Mr_Drv_Type_Pin, /**< PIN */
Mr_Drv_Type_Serial, /**< SERIAL */
Mr_Drv_Type_SPI, /**< SPI */
Mr_Drv_Type_Timer, /**< Timer */
Mr_Drv_Type_PWM, /**< PWM */
};
/** /**
* @brief Driver structure. * @brief Driver structure.
*/ */
struct mr_drv struct mr_drv
{ {
int type; /**< Driver type */ void *ops; /**< Operations */
void *ops; /**< Driver operations */ void *data; /**< Data */
void *data; /**< Driver data */
}; };
/** /**
@@ -265,17 +247,17 @@ struct mr_drv
*/ */
enum mr_dev_type enum mr_dev_type
{ {
Mr_Dev_Type_Root = -1, /**< Root */ MR_DEV_TYPE_ROOT = 0, /**< Root device */
Mr_Dev_Type_ADC = Mr_Drv_Type_ADC, /**< ADC */ MR_DEV_TYPE_ADC, /**< ADC device */
Mr_Dev_Type_CAN = Mr_Drv_Type_CAN, /**< CAN */ MR_DEV_TYPE_CAN, /**< CAN device */
Mr_Dev_Type_DAC = Mr_Drv_Type_DAC, /**< DAC */ MR_DEV_TYPE_DAC, /**< DAC device */
Mr_Dev_Type_I2C = Mr_Drv_Type_I2C, /**< I2C */ MR_DEV_TYPE_I2C, /**< I2C device */
Mr_Dev_Type_Pin = Mr_Drv_Type_Pin, /**< PIN */ MR_DEV_TYPE_PIN, /**< PIN device */
Mr_Dev_Type_Serial = Mr_Drv_Type_Serial, /**< SERIAL */ MR_DEV_TYPE_SERIAL, /**< Serial device */
Mr_Dev_Type_SPI = Mr_Drv_Type_SPI, /**< SPI */ MR_DEV_TYPE_SPI, /**< SPI device */
Mr_Dev_Type_Timer = Mr_Drv_Type_Timer, /**< Timer */ MR_DEV_TYPE_TIMER, /**< Timer device */
Mr_Dev_Type_PWM = Mr_Drv_Type_PWM, /**< PWM */ MR_DEV_TYPE_PWM, /**< PWM device */
Mr_Dev_Type_Component, /**< Component */ MR_DEV_TYPE_COMPONENT, /**< Component device */
}; };
struct mr_dev; struct mr_dev;
@@ -287,43 +269,64 @@ struct mr_dev_ops
{ {
int (*open)(struct mr_dev *dev); int (*open)(struct mr_dev *dev);
int (*close)(struct mr_dev *dev); int (*close)(struct mr_dev *dev);
ssize_t (*read)(struct mr_dev *dev, int off, void *buf, size_t size, int async); ssize_t (*read)(struct mr_dev *dev, void *buf, size_t count);
ssize_t (*write)(struct mr_dev *dev, int off, const void *buf, size_t size, int async); ssize_t (*write)(struct mr_dev *dev, const void *buf, size_t count);
int (*ioctl)(struct mr_dev *dev, int off, int cmd, void *args); int (*ioctl)(struct mr_dev *dev, int cmd, void *args);
ssize_t (*isr)(struct mr_dev *dev, int event, void *args); ssize_t (*isr)(struct mr_dev *dev, int event, void *args);
}; };
/**
* @brief Device callback structure.
*/
struct mr_dev_call
{
void (*fn)(int desc, void *args);
struct mr_list list;
};
/** /**
* @brief Device structure. * @brief Device structure.
*/ */
struct mr_dev struct mr_dev
{ {
int magic; /**< Magic number */ uint32_t magic; /**< Magic number */
#ifndef MR_CFG_DEV_NAME_MAX #ifndef MR_CFG_DEV_NAME_LEN
#define MR_CFG_DEV_NAME_MAX (8) #define MR_CFG_DEV_NAME_LEN (8)
#endif /* MR_CFG_DEV_NAME_MAX */ #endif /* MR_CFG_DEV_NAME_LEN */
char name[MR_CFG_DEV_NAME_MAX]; /**< Name */ char name[MR_CFG_DEV_NAME_LEN]; /**< Name */
int type; /**< Device type */ uint32_t type; /**< Type */
void *parent; /**< Parent */ int flags; /**< Flags */
struct mr_list list; /**< List */ void *parent; /**< Parent device */
struct mr_list clist; /**< Child list */ struct mr_list list; /**< Same level device list */
struct mr_list clist; /**< Child device list */
size_t ref_count; /**< Reference count */ size_t ref_count; /**< Reference count */
int sflags; /**< Support flags */
#ifdef MR_USING_RDWR_CTL #ifdef MR_USING_RDWR_CTL
volatile int lflags; /**< Lock flags */ volatile uint32_t lock; /**< Lock flags */
#endif /* MR_USING_RDWR_CTL */ #endif /* MR_USING_RDWR_CTL */
int sync; /**< Sync flag */
int position; /**< Position */
struct struct mr_list rd_call_list; /**< Read callback list */
{ struct mr_list wr_call_list; /**< Write callback list */
int desc; /**< Device descriptor */
int (*call)(int desc, void *args); /**< Callback function */
} rd_call, wr_call; /**< Read/write call */
const struct mr_dev_ops *ops; /**< Device operations */ const struct mr_dev_ops *ops; /**< Operations */
const struct mr_drv *drv; /**< Driver */ const struct mr_drv *drv; /**< Driver */
}; };
/**
* @brief Device descriptor structure.
*/
struct mr_dev_desc
{
struct mr_dev *dev; /**< Device */
int flags; /**< Open flags */
int position; /**< Current position */
struct mr_dev_call rd_call; /**< Read callback */
struct mr_dev_call wr_call; /**< Write callback */
};
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

File diff suppressed because it is too large Load Diff