参考代码
This commit is contained in:
103
components/system/include/drivers/chip/_hal.h
Executable file
103
components/system/include/drivers/chip/_hal.h
Executable file
@@ -0,0 +1,103 @@
|
||||
#ifndef ___HAL_H__
|
||||
#define ___HAL_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef uint8_t hal_id_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "drivers/chip/gpio.h"
|
||||
#include "drivers/chip/clk.h"
|
||||
#include "drivers/chip/irq.h"
|
||||
#include "drivers/chip/uart.h"
|
||||
#include "drivers/chip/i2c.h"
|
||||
#include "drivers/chip/spi.h"
|
||||
#include "drivers/chip/phy.h"
|
||||
#include "drivers/chip/adc.h"
|
||||
#include "drivers/chip/cmp.h"
|
||||
#include "drivers/chip/dac.h"
|
||||
#include "drivers/chip/dma.h"
|
||||
#include "drivers/chip/tim.h"
|
||||
#include "drivers/chip/tick.h"
|
||||
#include "drivers/chip/fmc.h"
|
||||
#include "drivers/chip/wdt.h"
|
||||
#include "drivers/chip/lpm.h"
|
||||
#include "drivers/chip/misc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pin;
|
||||
gpio_dir_t dir;
|
||||
gpio_pud_t pull;
|
||||
} hal_pin_hdl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
hal_pin_hdl_t pin_txd;
|
||||
hal_pin_hdl_t pin_rxd;
|
||||
hal_id_t id;
|
||||
uint8_t irq_prior;
|
||||
uint32_t br;
|
||||
} hal_uart_hdl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
hal_pin_hdl_t pin_sck;
|
||||
hal_pin_hdl_t pin_sda;
|
||||
hal_id_t id;
|
||||
uint8_t irq_prior;
|
||||
uint32_t freq;
|
||||
} hal_i2c_hdl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
hal_pin_hdl_t pin_sck;
|
||||
hal_pin_hdl_t pin_mosi;
|
||||
hal_pin_hdl_t pin_miso;
|
||||
hal_id_t id;
|
||||
spi_mode_t mode;
|
||||
uint8_t irq_prior;
|
||||
uint32_t freq;
|
||||
} hal_spi_hdl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
hal_id_t id;
|
||||
uint16_t vref_mv;
|
||||
uint32_t value_max;
|
||||
uint32_t channel_mask;
|
||||
} hal_adc_hdl_t;
|
||||
|
||||
void drv_hal_init(void);
|
||||
void drv_hal_deinit(void);
|
||||
|
||||
int drv_hal_gpio_pin_init(const hal_pin_hdl_t *gpio_hdl);
|
||||
int drv_hal_uart_init(const hal_uart_hdl_t *uart_hdl);
|
||||
int drv_hal_i2c_init(const hal_i2c_hdl_t *i2c_hdl);
|
||||
int drv_hal_spi_init(const hal_spi_hdl_t *spi_hdl);
|
||||
int drv_hal_drv_adc_init(const hal_adc_hdl_t *adc_hdl);
|
||||
|
||||
void drv_hal_debug_enable(void);
|
||||
void drv_hal_debug_disable(void);
|
||||
|
||||
void drv_hal_sys_reset(void);
|
||||
void drv_hal_sys_exit(int status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
40
components/system/include/drivers/chip/adc.h
Executable file
40
components/system/include/drivers/chip/adc.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef __ADC_H__
|
||||
#define __ADC_H__
|
||||
|
||||
#include "drivers/chip/_hal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void (*adc_isr_cb_fn)(uint8_t channel_id);
|
||||
|
||||
void drv_adc_pin_configure(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_adc_enable(hal_id_t id);
|
||||
void drv_adc_disable(hal_id_t id);
|
||||
|
||||
void drv_adc_init(hal_id_t id, unsigned channel_mask, uint32_t sampling_length);
|
||||
void drv_adc_deinit(hal_id_t id, unsigned channel_mask);
|
||||
|
||||
int drv_adc_irq_callback_enable(hal_id_t id, uint8_t channel_id, adc_isr_cb_fn cb);
|
||||
int drv_adc_irq_callback_disable(hal_id_t id, uint8_t channel_id);
|
||||
|
||||
void drv_adc_irq_enable(hal_id_t id, int priority);
|
||||
void drv_adc_irq_disable(hal_id_t id);
|
||||
|
||||
void drv_adc_start(hal_id_t id, unsigned channel_mask);
|
||||
void drv_adc_stop(hal_id_t id, unsigned channel_mask);
|
||||
|
||||
bool drv_adc_is_busy(hal_id_t id, uint8_t channel_id);
|
||||
bool drv_adc_is_ready(hal_id_t id, uint8_t channel_id);
|
||||
|
||||
int drv_adc_read(hal_id_t id, uint8_t channel_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
17
components/system/include/drivers/chip/clk.h
Executable file
17
components/system/include/drivers/chip/clk.h
Executable file
@@ -0,0 +1,17 @@
|
||||
#ifndef __CLK_H__
|
||||
#define __CLK_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
unsigned drv_clk_get_cpu_clk(void);
|
||||
|
||||
int drv_clk_calibration(unsigned tar_clk, unsigned cur_clk);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
components/system/include/drivers/chip/cmp.h
Executable file
57
components/system/include/drivers/chip/cmp.h
Executable file
@@ -0,0 +1,57 @@
|
||||
#ifndef __HAL_CMP_H__
|
||||
#define __HAL_CMP_H__
|
||||
|
||||
#include "drivers/chip/_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void (*cmp_isr_cb_fn)(void);
|
||||
|
||||
typedef enum __packed
|
||||
{
|
||||
_CMP_OUTPUT_NONE, // 没有任何输出动作
|
||||
_CMP_OUTPUT_IO, // 输出到 IO
|
||||
_CMP_OUTPUT_EXTI, // 触发 中断线
|
||||
_CMP_OUTPUT_TIM, // 触发 定时器的输入
|
||||
} cmp_output_t;
|
||||
|
||||
typedef enum __packed
|
||||
{
|
||||
_CMP_INT_EDGE_NONE,
|
||||
_CMP_INT_EDGE_FALL,
|
||||
_CMP_INT_EDGE_RISE,
|
||||
_CMP_INT_EDGE_BOTH,
|
||||
} cmp_int_edge_t;
|
||||
|
||||
void drv_cmp_pin_configure_in(hal_id_t id, uint8_t pin);
|
||||
void drv_cmp_pin_configure_out(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_cmp_enable(hal_id_t id);
|
||||
void drv_cmp_disable(hal_id_t id);
|
||||
|
||||
void drv_cmp_init(hal_id_t id, cmp_output_t output);
|
||||
void drv_cmp_deinit(hal_id_t id);
|
||||
|
||||
int drv_cmp_get_out_value(hal_id_t id);
|
||||
|
||||
int drv_cmp_irq_callback_enable(hal_id_t id, cmp_isr_cb_fn cb);
|
||||
int drv_cmp_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_cmp_irq_enable(hal_id_t id, cmp_int_edge_t edge, int priority);
|
||||
void drv_cmp_irq_disable(hal_id_t id);
|
||||
|
||||
void drv_cmp_start(hal_id_t id);
|
||||
void drv_cmp_stop(hal_id_t id);
|
||||
|
||||
void drv_cmp_set_cmp_value(hal_id_t id, uint16_t value);
|
||||
|
||||
uint8_t drv_cmp_read(hal_id_t id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
33
components/system/include/drivers/chip/dac.h
Executable file
33
components/system/include/drivers/chip/dac.h
Executable file
@@ -0,0 +1,33 @@
|
||||
#ifndef __DAC_H__
|
||||
#define __DAC_H__
|
||||
|
||||
#include "drivers/chip/_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void (*dac_isr_cb_fn)(void);
|
||||
|
||||
void drv_dac_pin_configure(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_dac_enable(hal_id_t id);
|
||||
void drv_dac_disable(hal_id_t id);
|
||||
|
||||
int drv_dac_init(hal_id_t id, unsigned channel_mask, unsigned bit_width);
|
||||
int drv_dac_deinit(hal_id_t id, unsigned channel_mask);
|
||||
|
||||
int drv_dac_irq_callback_enable(hal_id_t id, dac_isr_cb_fn cb);
|
||||
int drv_dac_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_dac_irq_enable(hal_id_t id, int priority);
|
||||
void drv_dac_irq_disable(hal_id_t id);
|
||||
|
||||
void drv_dac_write(hal_id_t id, unsigned channel_id, int value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
42
components/system/include/drivers/chip/dma.h
Executable file
42
components/system/include/drivers/chip/dma.h
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef __DMA_H__
|
||||
#define __DMA_H__
|
||||
|
||||
#include "drivers/chip/_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef enum __packed
|
||||
{
|
||||
_DMA_DIR_MEM_TO_MEM,
|
||||
_DMA_DIR_PER_TO_MEM,
|
||||
_DMA_DIR_MEM_TO_PER,
|
||||
} dma_dir_t;
|
||||
|
||||
typedef void (*dma_isr_cb_fn)(void);
|
||||
|
||||
void drv_dma_enable(hal_id_t id);
|
||||
void drv_dma_disable(hal_id_t id);
|
||||
|
||||
int drv_dma_init(hal_id_t id, unsigned channel, unsigned prio_level);
|
||||
int drv_dma_deinit(hal_id_t id, unsigned channel);
|
||||
|
||||
int drv_dma_irq_callback_enable(hal_id_t id, unsigned channel, dma_isr_cb_fn cb);
|
||||
int drv_dma_irq_callback_disable(hal_id_t id, unsigned channel);
|
||||
|
||||
void drv_dma_irq_enable(hal_id_t id, unsigned channel, int priority);
|
||||
void drv_dma_irq_disable(hal_id_t id, unsigned channel);
|
||||
|
||||
void drv_dma_set(hal_id_t id, unsigned channel, void *dest, unsigned dest_bit_width, bool dest_inc_mode, const void *src, unsigned src_bit_width, bool src_inc_mode, unsigned count, dma_dir_t dir);
|
||||
void drv_dma_start(hal_id_t id, unsigned channel);
|
||||
void drv_dma_stop(hal_id_t id, unsigned channel);
|
||||
|
||||
unsigned drv_dma_get_remain(hal_id_t id, unsigned channel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
40
components/system/include/drivers/chip/fmc.h
Executable file
40
components/system/include/drivers/chip/fmc.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef __FMC_H__
|
||||
#define __FMC_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void drv_fmc_enable(void);
|
||||
void drv_fmc_disable(void);
|
||||
|
||||
void drv_fmc_lock(void);
|
||||
void drv_fmc_unlock(void);
|
||||
|
||||
unsigned drv_fmc_get_rom_base(void);
|
||||
unsigned drv_fmc_get_rom_size(void);
|
||||
unsigned drv_fmc_get_sector_base(unsigned addr);
|
||||
unsigned drv_fmc_get_sector_size(unsigned addr);
|
||||
|
||||
int drv_fmc_sector_erase(unsigned addr);
|
||||
int drv_fmc_data_write(unsigned addr, const void *src, unsigned size);
|
||||
int drv_fmc_data_read(void *dest, unsigned addr, unsigned size);
|
||||
|
||||
bool drv_fmc_is_busy(void);
|
||||
|
||||
int drv_fmc_set_read_protection(bool enable);
|
||||
int drv_fmc_set_write_protection(bool enable, unsigned start_offset, unsigned size);
|
||||
|
||||
bool drv_fmc_is_read_protection(void);
|
||||
bool drv_fmc_is_write_protection(unsigned addr);
|
||||
|
||||
int drv_fmc_set_wdt(unsigned time_ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
60
components/system/include/drivers/chip/gpio.h
Executable file
60
components/system/include/drivers/chip/gpio.h
Executable file
@@ -0,0 +1,60 @@
|
||||
#ifndef __GPIO_H__
|
||||
#define __GPIO_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef enum __packed
|
||||
{
|
||||
_GPIO_DIR_IN,
|
||||
_GPIO_DIR_ANALOG,
|
||||
_GPIO_DIR_OUT,
|
||||
_GPIO_DIR_OPEN_DRAIN,
|
||||
} gpio_dir_t;
|
||||
|
||||
typedef enum __packed
|
||||
{
|
||||
_GPIO_PUD_NONE,
|
||||
_GPIO_PUD_PULL_UP,
|
||||
_GPIO_PUD_PULL_DOWN,
|
||||
} gpio_pud_t;
|
||||
|
||||
typedef enum __packed
|
||||
{
|
||||
_GPIO_EXTI_EDGE_NONE,
|
||||
_GPIO_EXTI_EDGE_FALL,
|
||||
_GPIO_EXTI_EDGE_RISE,
|
||||
_GPIO_EXTI_EDGE_BOTH,
|
||||
} gpio_exti_edge_t;
|
||||
|
||||
typedef void (*gpio_exti_cb_fn)(void);
|
||||
|
||||
void drv_gpio_enable_all(void);
|
||||
void drv_gpio_disable_all(void);
|
||||
|
||||
int drv_gpio_pin_configure(uint8_t pin, gpio_dir_t dir, gpio_pud_t pull);
|
||||
int drv_gpio_pin_read(uint8_t pin);
|
||||
void drv_gpio_pin_write(uint8_t pin, int value);
|
||||
|
||||
void drv_gpio_exti_callback_enable(gpio_exti_cb_fn cb);
|
||||
void drv_gpio_exti_callback_disable(void);
|
||||
|
||||
void drv_gpio_exti_irq_enable(uint8_t pin, gpio_exti_edge_t polarity, int priority);
|
||||
void drv_gpio_exti_irq_disable(uint8_t pin);
|
||||
|
||||
int drv_gpio_exti_get_pin(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
38
components/system/include/drivers/chip/i2c.h
Executable file
38
components/system/include/drivers/chip/i2c.h
Executable file
@@ -0,0 +1,38 @@
|
||||
#ifndef __I2C_H__
|
||||
#define __I2C_H__
|
||||
|
||||
#include "drivers/chip/_hal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void (*i2c_isr_cb_fn)(void);
|
||||
|
||||
void drv_i2c_pin_configure_sck(hal_id_t id, uint8_t pin);
|
||||
void drv_i2c_pin_configure_sda(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_i2c_enable(hal_id_t id);
|
||||
void drv_i2c_disable(hal_id_t id);
|
||||
|
||||
void drv_i2c_init(hal_id_t id, uint32_t freq);
|
||||
void drv_i2c_deinit(hal_id_t id);
|
||||
|
||||
int drv_i2c_write(hal_id_t id, char dev_addr, const void *src, unsigned count);
|
||||
int drv_i2c_read(hal_id_t id, void *dest, char dev_addr, unsigned count);
|
||||
|
||||
int drv_i2c_irq_callback_enable(hal_id_t id, i2c_isr_cb_fn cb);
|
||||
int drv_i2c_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_i2c_irq_enable(hal_id_t id, int priority);
|
||||
void drv_i2c_irq_disable(hal_id_t id);
|
||||
|
||||
bool drv_i2c_is_busy(hal_id_t id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
23
components/system/include/drivers/chip/irq.h
Executable file
23
components/system/include/drivers/chip/irq.h
Executable file
@@ -0,0 +1,23 @@
|
||||
#ifndef __IRQ_H__
|
||||
#define __IRQ_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
unsigned drv_irq_disable(void);
|
||||
void drv_irq_enable(unsigned nest);
|
||||
|
||||
unsigned drv_irq_get_nest(void);
|
||||
|
||||
void drv_fiq_disable(void);
|
||||
void drv_fiq_enable(void);
|
||||
|
||||
void drv_irq_hardfault_callback(void ((*cb)(void)));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
19
components/system/include/drivers/chip/lpm.h
Executable file
19
components/system/include/drivers/chip/lpm.h
Executable file
@@ -0,0 +1,19 @@
|
||||
#ifndef __LPM_H__
|
||||
#define __LPM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void drv_lpm_wkup_enable(unsigned id);
|
||||
void drv_lpm_wkup_disable(unsigned id);
|
||||
|
||||
void drv_lpm_sleep(void);
|
||||
void drv_lpm_deep_sleep(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
68
components/system/include/drivers/chip/misc.h
Executable file
68
components/system/include/drivers/chip/misc.h
Executable file
@@ -0,0 +1,68 @@
|
||||
#ifndef __MISC_H__
|
||||
#define __MISC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 让 CPU 空转延时
|
||||
*
|
||||
* @param us 微秒
|
||||
*/
|
||||
void drv_misc_busy_wait(unsigned us);
|
||||
|
||||
/**
|
||||
* @brief 获取变量的位带映射地址
|
||||
*
|
||||
* @param mem 变量地址
|
||||
* @return 位带映射地址。如无返回 NULL
|
||||
*/
|
||||
unsigned *drv_misc_bitband(void *mem);
|
||||
|
||||
/**
|
||||
* @brief 读取 MCU 身份信息的 MD5 值
|
||||
*
|
||||
* @param out[out] 输出
|
||||
* @retval 0 成功
|
||||
* @retval -1 失败
|
||||
*/
|
||||
int drv_misc_read_id_md5(unsigned char out[16]);
|
||||
|
||||
/**
|
||||
* @brief 设置中断向量地址
|
||||
*
|
||||
* @param vector 中断向量地址
|
||||
*/
|
||||
void drv_misc_set_vector(void *vector);
|
||||
|
||||
/**
|
||||
* @brief 获取中断向量地址
|
||||
*
|
||||
* @return void* 中断向量地址
|
||||
*/
|
||||
void *drv_misc_get_vector(void);
|
||||
|
||||
/**
|
||||
* @brief 根据具体平台,以尽可能快的速度把内存置0
|
||||
*
|
||||
* @param src 内存地址
|
||||
* @param len 内存长度
|
||||
*/
|
||||
void mem_reset(void *src, unsigned len);
|
||||
|
||||
/**
|
||||
* @brief 根据具体平台,以尽可能快的速度复制内存数据
|
||||
*
|
||||
* @param dest[out] 目录内存
|
||||
* @param src 源内存
|
||||
* @param len 长度
|
||||
*/
|
||||
void mem_cpy(void *dest, const void *src, unsigned len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
48
components/system/include/drivers/chip/phy.h
Executable file
48
components/system/include/drivers/chip/phy.h
Executable file
@@ -0,0 +1,48 @@
|
||||
#ifndef __PHY_H__
|
||||
#define __PHY_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Defines the PHY link speed. This is align with the speed for MAC. */
|
||||
enum phy_speed
|
||||
{
|
||||
PHY_SPEED_10M = 0U, /* PHY 10M speed. */
|
||||
PHY_SPEED_100M /* PHY 100M speed. */
|
||||
};
|
||||
|
||||
/* Defines the PHY link duplex. */
|
||||
enum phy_duplex
|
||||
{
|
||||
PHY_HALF_DUPLEX = 0U, /* PHY half duplex. */
|
||||
PHY_FULL_DUPLEX /* PHY full duplex. */
|
||||
};
|
||||
|
||||
/*! @brief Defines the PHY loopback mode. */
|
||||
enum phy_loop
|
||||
{
|
||||
PHY_LOCAL_LOOP = 0U, /* PHY local loopback. */
|
||||
PHY_REMOTE_LOOP /* PHY remote loopback. */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
enum phy_speed speed;
|
||||
enum phy_duplex duplex;
|
||||
enum phy_loop loop;
|
||||
} phy_param_t;
|
||||
|
||||
int drv_phy_init(unsigned phy_addr, unsigned src_clock_hz, phy_param_t *param);
|
||||
int drv_phy_read(unsigned reg, unsigned *data);
|
||||
int drv_phy_write(unsigned reg, unsigned data);
|
||||
int drv_phy_loopback(unsigned mode, unsigned speed, unsigned enable);
|
||||
int drv_phy_get_link_status(unsigned *status);
|
||||
int drv_phy_get_link_speed_duplex(unsigned *speed, unsigned *duplex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
74
components/system/include/drivers/chip/spi.h
Executable file
74
components/system/include/drivers/chip/spi.h
Executable file
@@ -0,0 +1,74 @@
|
||||
#ifndef __SPI_H__
|
||||
#define __SPI_H__
|
||||
|
||||
#include "drivers/chip/_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef enum __packed
|
||||
{
|
||||
_SPI_MODE_0, // clock polarity is low level and phase is first edge
|
||||
_SPI_MODE_1, // clock polarity is low level and phase is second edge
|
||||
_SPI_MODE_2, // clock polarity is high level and phase is first edge
|
||||
_SPI_MODE_3, // clock polarity is high level and phase is second edge
|
||||
} spi_mode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool ms; // false: master, true: slave
|
||||
spi_mode_t mode;
|
||||
bool quad_mode;
|
||||
bool lsb_first;
|
||||
unsigned freq;
|
||||
} spi_init_t;
|
||||
|
||||
typedef void (*spi_isr_cb_fn)(void);
|
||||
|
||||
void drv_spi_pin_configure_nss(hal_id_t id, uint8_t pin);
|
||||
void drv_spi_pin_configure_sck(hal_id_t id, uint8_t pin);
|
||||
void drv_spi_pin_configure_mosi(hal_id_t id, uint8_t pin);
|
||||
void drv_spi_pin_configure_miso(hal_id_t id, uint8_t pin);
|
||||
void drv_spi_pin_configure_io2(hal_id_t id, uint8_t pin);
|
||||
void drv_spi_pin_configure_io3(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_spi_enable(hal_id_t id);
|
||||
void drv_spi_disable(hal_id_t id);
|
||||
|
||||
void drv_spi_init(hal_id_t id, const spi_init_t *param);
|
||||
void drv_spi_deinit(hal_id_t id);
|
||||
|
||||
int drv_spi_poll_read(hal_id_t id, void *dest);
|
||||
int drv_spi_poll_write(hal_id_t id, uint8_t data);
|
||||
|
||||
int drv_spi_irq_callback_enable(hal_id_t id, spi_isr_cb_fn cb);
|
||||
int drv_spi_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_spi_irq_enable(hal_id_t id, bool rx, bool tx, int priority);
|
||||
void drv_spi_irq_disable(hal_id_t id, bool rx, bool tx);
|
||||
|
||||
bool drv_spi_is_tx_ready(hal_id_t id);
|
||||
bool drv_spi_is_rx_ready(hal_id_t id);
|
||||
|
||||
void drv_spi_dma_enable(hal_id_t id, bool tx_dma, bool rx_dma, unsigned prio_level);
|
||||
void drv_spi_dma_disable(hal_id_t id, bool tx_dma, bool rx_dma);
|
||||
|
||||
int drv_spi_dma_irq_callback_enable(hal_id_t id, spi_isr_cb_fn cb);
|
||||
int drv_spi_dma_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_spi_dma_irq_enable(hal_id_t id, int priority);
|
||||
void drv_spi_dma_irq_disable(hal_id_t id);
|
||||
|
||||
int drv_spi_dma_set_read(hal_id_t id, void *dest, unsigned len);
|
||||
int drv_spi_dma_set_write(hal_id_t id, const void *src, unsigned len);
|
||||
void drv_spi_dma_start(hal_id_t id);
|
||||
|
||||
bool drv_spi_dma_is_busy(hal_id_t id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
18
components/system/include/drivers/chip/tick.h
Executable file
18
components/system/include/drivers/chip/tick.h
Executable file
@@ -0,0 +1,18 @@
|
||||
#ifndef __TICK_H__
|
||||
#define __TICK_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void drv_tick_enable(unsigned freq);
|
||||
void drv_tick_disable(void);
|
||||
|
||||
unsigned drv_tick_get_counter(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
136
components/system/include/drivers/chip/tim.h
Executable file
136
components/system/include/drivers/chip/tim.h
Executable file
@@ -0,0 +1,136 @@
|
||||
#ifndef __TIM_H__
|
||||
#define __TIM_H__
|
||||
|
||||
#include "drivers/chip/_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @param channel_id: 0..n
|
||||
* @param channel_mask: 1 << 0, 1 << 1, ... 1 << n
|
||||
*/
|
||||
|
||||
typedef void (*tim_isr_cb_fn)(void);
|
||||
|
||||
/** @defgroup time base
|
||||
* @{
|
||||
*/
|
||||
|
||||
void drv_tim_enable(hal_id_t id);
|
||||
void drv_tim_disable(hal_id_t id);
|
||||
|
||||
void drv_tim_init(hal_id_t id, unsigned period_ns, unsigned reload_enable);
|
||||
void drv_tim_deinit(hal_id_t id);
|
||||
|
||||
int drv_tim_irq_callback_enable(hal_id_t id, tim_isr_cb_fn cb);
|
||||
int drv_tim_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_tim_irq_enable(hal_id_t id, int priority);
|
||||
void drv_tim_irq_disable(hal_id_t id);
|
||||
|
||||
void drv_tim_base_start(hal_id_t id);
|
||||
void drv_tim_base_stop(hal_id_t id);
|
||||
|
||||
unsigned drv_tim_get_period_ns(hal_id_t id);
|
||||
unsigned drv_tim_get_cost_ns(hal_id_t id);
|
||||
unsigned drv_tim_get_remain_ns(hal_id_t id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup PWM
|
||||
* @{
|
||||
*/
|
||||
|
||||
void drv_pwm_pin_configure(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_pwm_enable(hal_id_t id);
|
||||
void drv_pwm_disable(hal_id_t id);
|
||||
|
||||
void drv_pwm_init(hal_id_t id, unsigned period_ns, unsigned reload_enable);
|
||||
void drv_pwm_deinit(hal_id_t id);
|
||||
|
||||
int drv_pwm_irq_callback_enable(hal_id_t id, tim_isr_cb_fn cb);
|
||||
int drv_pwm_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_pwm_irq_enable(hal_id_t id, unsigned channel_mask, int priority);
|
||||
void drv_pwm_irq_disable(hal_id_t id, unsigned channel_mask);
|
||||
|
||||
void drv_pwm_start(hal_id_t id, unsigned channel_mask, unsigned active_level, unsigned pulse_ns);
|
||||
void drv_pwm_stop(hal_id_t id, unsigned channel_mask, unsigned active_level);
|
||||
|
||||
bool drv_pwm_is_busy(hal_id_t id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup one pluse
|
||||
* @{
|
||||
*/
|
||||
|
||||
void drv_pluse_pin_configure(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_pluse_enable(hal_id_t id);
|
||||
void drv_pluse_disable(hal_id_t id);
|
||||
|
||||
void drv_pluse_init(hal_id_t id);
|
||||
void drv_pluse_deinit(hal_id_t id);
|
||||
|
||||
int drv_pluse_irq_callback_enable(hal_id_t id, tim_isr_cb_fn cb);
|
||||
int drv_pluse_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_pluse_irq_enable(hal_id_t id, unsigned channel_mask, int priority);
|
||||
void drv_pluse_irq_disable(hal_id_t id, unsigned channel_mask);
|
||||
|
||||
void drv_pluse_set(hal_id_t id, unsigned channel_mask, unsigned active_level, unsigned period_ns, unsigned pulse_ns);
|
||||
|
||||
bool drv_pluse_is_busy(hal_id_t id, unsigned channel);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup input capture
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum __packed
|
||||
{
|
||||
_IC_EDGE_RISING,
|
||||
_IC_EDGE_FALLING,
|
||||
_IC_EDGE_BOTH,
|
||||
} capture_edge_t;
|
||||
|
||||
void drv_capture_pin_configure(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_capture_enable(hal_id_t id);
|
||||
void drv_capture_disable(hal_id_t id);
|
||||
|
||||
void drv_capture_init(hal_id_t id, unsigned channel_mask, capture_edge_t polarity);
|
||||
void drv_capture_deinit(hal_id_t id);
|
||||
|
||||
int drv_capture_irq_callback_enable(hal_id_t id, tim_isr_cb_fn cb);
|
||||
int drv_capture_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_capture_irq_enable(hal_id_t id, unsigned channel_mask, int priority);
|
||||
void drv_capture_irq_disable(hal_id_t id, unsigned channel_mask);
|
||||
|
||||
void drv_capture_start(hal_id_t id, unsigned channel_mask);
|
||||
void drv_capture_stop(hal_id_t id, unsigned channel_mask);
|
||||
|
||||
unsigned drv_capture_get_cap_value(hal_id_t id, uint8_t channel_id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
56
components/system/include/drivers/chip/uart.h
Executable file
56
components/system/include/drivers/chip/uart.h
Executable file
@@ -0,0 +1,56 @@
|
||||
#ifndef __UART_H__
|
||||
#define __UART_H__
|
||||
|
||||
#include "drivers/chip/_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t br;
|
||||
uint8_t length; /* 7..9 */
|
||||
uint8_t stop_bit; /* 1 or 2 */
|
||||
uint8_t parity; /* 0: none 1: even 2: odd */
|
||||
uint8_t flow_ctrl; /* 0: none 1: RTS 2: CTS 3: RTS+CTS */
|
||||
|
||||
} uart_param_t;
|
||||
|
||||
typedef void (*uart_isr_cb_fn)(void);
|
||||
|
||||
void drv_uart_pin_configure_txd(hal_id_t id, uint8_t pin);
|
||||
void drv_uart_pin_configure_rxd(hal_id_t id, uint8_t pin);
|
||||
|
||||
void drv_uart_enable(hal_id_t id);
|
||||
void drv_uart_disable(hal_id_t id);
|
||||
|
||||
void drv_uart_init(hal_id_t id, const uart_param_t *param);
|
||||
void drv_uart_deinit(hal_id_t id);
|
||||
|
||||
void drv_uart_set_br(hal_id_t id, unsigned clk, unsigned baudrate);
|
||||
unsigned drv_uart_get_br(hal_id_t id, unsigned clk);
|
||||
|
||||
int drv_uart_poll_read(hal_id_t id, void *data);
|
||||
int drv_uart_poll_write(hal_id_t id, uint8_t data);
|
||||
|
||||
int drv_uart_fifo_read(hal_id_t id, void *data, int size);
|
||||
int drv_uart_fifo_fill(hal_id_t id, const void *data, int size);
|
||||
|
||||
int drv_uart_irq_callback_enable(hal_id_t id, uart_isr_cb_fn cb);
|
||||
int drv_uart_irq_callback_disable(hal_id_t id);
|
||||
|
||||
void drv_uart_irq_enable(hal_id_t id, bool rx, bool tx, int priority);
|
||||
void drv_uart_irq_disable(hal_id_t id, bool rx, bool tx);
|
||||
|
||||
bool drv_uart_wait_tx_busy(hal_id_t id);
|
||||
|
||||
bool drv_uart_is_tx_ready(hal_id_t id);
|
||||
bool drv_uart_is_rx_ready(hal_id_t id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
32
components/system/include/drivers/chip/wdt.h
Executable file
32
components/system/include/drivers/chip/wdt.h
Executable file
@@ -0,0 +1,32 @@
|
||||
#ifndef __WDT_H__
|
||||
#define __WDT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
_WDT_MODE_RESET,
|
||||
_WDT_MODE_INTERRUPT_RESET
|
||||
} wdt_mode_t;
|
||||
|
||||
void wdt_enable(void);
|
||||
void wdt_disable(void);
|
||||
|
||||
void wdt_irq_enable(int priority);
|
||||
void wdt_irq_disable(void);
|
||||
|
||||
void wdt_set_config(wdt_mode_t mode, int int_ms, int reset_ms);
|
||||
|
||||
void wdt_reload(void);
|
||||
unsigned wdt_get_time_cost(void);
|
||||
|
||||
void wdt_clear_int_flag(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
285
components/system/include/list/dlist.h
Executable file
285
components/system/include/list/dlist.h
Executable file
@@ -0,0 +1,285 @@
|
||||
/**
|
||||
* @file dlist.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DUPLEXLIST_H__
|
||||
#define __DUPLEXLIST_H__
|
||||
|
||||
#include "sys_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef LIST_NODE_TYPE
|
||||
#define LIST_NODE_TYPE 0 /* 0 -- 使用指针连结(推荐);1 -- 使用偏移量连结,内存的地址允许被迁移并继续管理(推荐) */
|
||||
#endif
|
||||
|
||||
#if LIST_NODE_TYPE == 1
|
||||
typedef int list_node_t;
|
||||
#else
|
||||
typedef void * list_node_t;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
list_node_t next;
|
||||
list_node_t prev;
|
||||
} dlist_node_t;
|
||||
typedef struct
|
||||
{
|
||||
list_node_t head;
|
||||
} dlist_t;
|
||||
|
||||
__static_inline void dlist_init_list (dlist_t *list);
|
||||
__static_inline void dlist_init_node (dlist_node_t *node);
|
||||
|
||||
__static_inline int dlist_insert_font (dlist_t *list, dlist_node_t *node);
|
||||
__static_inline int dlist_insert_tail (dlist_t *list, dlist_node_t *node);
|
||||
__static_inline int dlist_remove (dlist_t *list, dlist_node_t *node);
|
||||
|
||||
__static_inline int dlist_insert_next (dlist_t *list, dlist_node_t *tar_node, dlist_node_t *new_node);
|
||||
__static_inline int dlist_insert_prev (dlist_t *list, dlist_node_t *tar_node, dlist_node_t *new_node);
|
||||
|
||||
__static_inline void dlist_set_next (dlist_t *list);
|
||||
|
||||
__static_inline dlist_node_t *dlist_take_head (dlist_t *list);
|
||||
__static_inline dlist_node_t *dlist_take_tail (dlist_t *list);
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_head (dlist_t *list);
|
||||
__static_inline dlist_node_t *dlist_peek_tail (dlist_t *list);
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_next (dlist_t *list, dlist_node_t *node);
|
||||
__static_inline dlist_node_t *dlist_peek_prev (dlist_t *list, dlist_node_t *node);
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_next_loop (dlist_t *list, dlist_node_t *node);
|
||||
__static_inline dlist_node_t *dlist_peek_prev_loop (dlist_t *list, dlist_node_t *node);
|
||||
|
||||
__static_inline int dlist_is_pending (dlist_node_t *node);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if LIST_NODE_TYPE == 1
|
||||
#define DLIST_SET(Value1, Value2) (Value1 = Value2 == 0 ? 0 : ((int)Value2 - (int)&Value1) | 1)
|
||||
#define DLIST_GET(Value) ((dlist_node_t*)(Value == 0 ? 0 : ((int)&Value + Value) & ~1))
|
||||
#else
|
||||
#define DLIST_SET(Value1, Value2) (Value1 = (list_node_t)Value2)
|
||||
#define DLIST_GET(Value) ((dlist_node_t*)(Value))
|
||||
#endif
|
||||
|
||||
__static_inline void dlist_init_list(dlist_t *list)
|
||||
{
|
||||
DLIST_SET(list->head, 0);
|
||||
}
|
||||
|
||||
__static_inline void dlist_init_node(dlist_node_t *node)
|
||||
{
|
||||
DLIST_SET(node->next, 0);
|
||||
DLIST_SET(node->prev, 0);
|
||||
}
|
||||
|
||||
__static_inline int dlist_insert_font(dlist_t *list, dlist_node_t *node)
|
||||
{
|
||||
if (dlist_insert_tail(list, node) == 0)
|
||||
{
|
||||
DLIST_SET(list->head, node);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline int dlist_insert_tail(dlist_t *list, dlist_node_t *node)
|
||||
{
|
||||
if (DLIST_GET(node->next) != NULL || DLIST_GET(node->prev) != NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
dlist_node_t *first_node = DLIST_GET(list->head);
|
||||
if (first_node == NULL)
|
||||
{
|
||||
/* 直接设置链头 */
|
||||
DLIST_SET(node->next, node);
|
||||
DLIST_SET(node->prev, node);
|
||||
DLIST_SET(list->head, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
dlist_node_t *first_node_prev = DLIST_GET(first_node->prev);
|
||||
|
||||
DLIST_SET(node->next, first_node);
|
||||
DLIST_SET(node->prev, first_node_prev);
|
||||
DLIST_SET(first_node_prev->next, node);
|
||||
DLIST_SET(first_node->prev, node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline int dlist_remove(dlist_t *list, dlist_node_t *node)
|
||||
{
|
||||
if (node == NULL || list == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
dlist_node_t *first_node = DLIST_GET(list->head);
|
||||
dlist_node_t *node_next = DLIST_GET(node->next);
|
||||
if (node_next == NULL || first_node == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (node_next == node) // 是最后一节点
|
||||
{
|
||||
DLIST_SET(list->head, 0);
|
||||
}
|
||||
else // 不是最后一节点
|
||||
{
|
||||
dlist_node_t *node_prev = DLIST_GET(node->prev);
|
||||
if (first_node == node)
|
||||
{
|
||||
DLIST_SET(list->head, node_next); // 链头指向下一节点
|
||||
}
|
||||
DLIST_SET(node_prev->next, node_next);
|
||||
DLIST_SET(node_next->prev, node_prev);
|
||||
}
|
||||
|
||||
DLIST_SET(node->next, 0);
|
||||
DLIST_SET(node->prev, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline int dlist_insert_next(dlist_t *list, dlist_node_t *tar_node, dlist_node_t *new_node)
|
||||
{
|
||||
dlist_node_t *tar_node_next = DLIST_GET(tar_node->next);
|
||||
if (DLIST_GET(list->head) == NULL || tar_node_next == NULL || DLIST_GET(new_node->next) != NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
DLIST_SET(new_node->next, tar_node_next);
|
||||
DLIST_SET(new_node->prev, tar_node);
|
||||
DLIST_SET(tar_node_next->prev, new_node);
|
||||
DLIST_SET(tar_node->next, new_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline int dlist_insert_prev(dlist_t *list, dlist_node_t *tar_node, dlist_node_t *new_node)
|
||||
{
|
||||
dlist_node_t *list_head = DLIST_GET(list->head);
|
||||
if (list_head == NULL || DLIST_GET(tar_node->next) == NULL || DLIST_GET(new_node->next) != NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
DLIST_SET(new_node->next, tar_node);
|
||||
DLIST_SET(new_node->prev, DLIST_GET(tar_node->prev));
|
||||
DLIST_SET(DLIST_GET(tar_node->prev)->next, new_node);
|
||||
DLIST_SET(tar_node->prev, new_node);
|
||||
if (tar_node == list_head) // tar_node 是首个节点
|
||||
{
|
||||
DLIST_SET(list->head, new_node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline void dlist_set_next(dlist_t *list)
|
||||
{
|
||||
if (list != NULL)
|
||||
{
|
||||
dlist_node_t *node = DLIST_GET(list->head);
|
||||
if (node != NULL)
|
||||
{
|
||||
DLIST_SET(list->head, DLIST_GET(node->next)); // 链头指向下一节点
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline dlist_node_t *dlist_take_head(dlist_t *list)
|
||||
{
|
||||
dlist_node_t *ret = DLIST_GET(list->head);
|
||||
dlist_remove(list, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
__static_inline dlist_node_t *dlist_take_tail(dlist_t *list)
|
||||
{
|
||||
dlist_node_t *ret = dlist_peek_tail(list);
|
||||
dlist_remove(list, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_head(dlist_t *list)
|
||||
{
|
||||
return DLIST_GET(list->head);
|
||||
}
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_tail(dlist_t *list)
|
||||
{
|
||||
dlist_node_t *list_head = DLIST_GET(list->head);
|
||||
if (list_head == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DLIST_GET(list_head->prev);
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_next(dlist_t *list, dlist_node_t *node)
|
||||
{
|
||||
dlist_node_t *ret = DLIST_GET(node->next);
|
||||
if (dlist_peek_head(list) == ret)
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_prev(dlist_t *list, dlist_node_t *node)
|
||||
{
|
||||
dlist_node_t *ret = DLIST_GET(node->prev);
|
||||
if (dlist_peek_tail(list) == ret)
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_next_loop(dlist_t *list, dlist_node_t *node)
|
||||
{
|
||||
(void)list;
|
||||
return DLIST_GET(node->next);
|
||||
}
|
||||
|
||||
__static_inline dlist_node_t *dlist_peek_prev_loop(dlist_t *list, dlist_node_t *node)
|
||||
{
|
||||
(void)list;
|
||||
return DLIST_GET(node->prev);
|
||||
}
|
||||
|
||||
__static_inline int dlist_is_pending(dlist_node_t *node)
|
||||
{
|
||||
return (DLIST_GET(node->next) != NULL);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
373
components/system/include/list/flist.h
Executable file
373
components/system/include/list/flist.h
Executable file
@@ -0,0 +1,373 @@
|
||||
/**
|
||||
* @file flist.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FULLLIST_H__
|
||||
#define __FULLLIST_H__
|
||||
|
||||
#include "sys_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef LIST_NODE_TYPE
|
||||
#define LIST_NODE_TYPE 0 /* 0 -- 使用指针连结(推荐);1 -- 使用偏移量连结,内存的地址允许被迁移并继续管理(推荐) */
|
||||
#endif
|
||||
|
||||
#if LIST_NODE_TYPE == 1
|
||||
typedef int list_node_t;
|
||||
#else
|
||||
typedef void * list_node_t;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
list_node_t next;
|
||||
list_node_t prev;
|
||||
list_node_t list;
|
||||
} flist_node_t;
|
||||
typedef struct
|
||||
{
|
||||
list_node_t head;
|
||||
} flist_t;
|
||||
|
||||
__static_inline void flist_init_list (flist_t *list);
|
||||
__static_inline void flist_init_node (flist_node_t *node);
|
||||
|
||||
__static_inline int flist_insert_font (flist_t *list, flist_node_t *node);
|
||||
__static_inline int flist_insert_tail (flist_t *list, flist_node_t *node);
|
||||
__static_inline int flist_remove (flist_t *list, flist_node_t *node);
|
||||
|
||||
__static_inline int flist_insert_next (flist_node_t *tar_node, flist_node_t *new_node);
|
||||
__static_inline int flist_insert_prev (flist_node_t *tar_node, flist_node_t *new_node);
|
||||
__static_inline int flist_node_free (flist_node_t *node);
|
||||
|
||||
__static_inline void flist_set_next (flist_t *list);
|
||||
|
||||
__static_inline flist_node_t *flist_take_head (flist_t *list);
|
||||
__static_inline flist_node_t *flist_take_tail (flist_t *list);
|
||||
|
||||
__static_inline flist_node_t *flist_peek_head (flist_t *list);
|
||||
__static_inline flist_node_t *flist_peek_tail (flist_t *list);
|
||||
|
||||
__static_inline flist_t *flist_peek_list (flist_node_t *node);
|
||||
__static_inline flist_node_t *flist_peek_first (flist_node_t *node);
|
||||
__static_inline flist_node_t *flist_peek_next (flist_node_t *node);
|
||||
__static_inline flist_node_t *flist_peek_prev (flist_node_t *node);
|
||||
|
||||
__static_inline flist_node_t *flist_peek_next_loop (flist_node_t *node);
|
||||
__static_inline flist_node_t *flist_peek_prev_loop (flist_node_t *node);
|
||||
|
||||
__static_inline int flist_is_pending (flist_node_t *node);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if LIST_NODE_TYPE == 1
|
||||
#define FLIST_SET(Value1, Value2) (Value1 = Value2 == 0 ? 0 : ((int)Value2 - (int)&Value1) | 1)
|
||||
#define FLIST_GET(Value) ((flist_node_t*)(Value == 0 ? 0 : ((int)&Value + Value) & ~1))
|
||||
#else
|
||||
#define FLIST_SET(Value1, Value2) (Value1 = (list_node_t)Value2)
|
||||
#define FLIST_GET(Value) ((flist_node_t*)(Value))
|
||||
#endif
|
||||
|
||||
__static_inline void flist_init_list(flist_t *list)
|
||||
{
|
||||
FLIST_SET(list->head, 0);
|
||||
}
|
||||
|
||||
__static_inline void flist_init_node(flist_node_t *node)
|
||||
{
|
||||
FLIST_SET(node->list, 0);
|
||||
FLIST_SET(node->next, 0);
|
||||
FLIST_SET(node->prev, 0);
|
||||
}
|
||||
|
||||
__static_inline int flist_insert_font(flist_t *list, flist_node_t *node)
|
||||
{
|
||||
flist_insert_tail(list, node);
|
||||
FLIST_SET(list->head, node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline int flist_insert_tail(flist_t *list, flist_node_t *node)
|
||||
{
|
||||
if (FLIST_GET(node->list) != NULL)
|
||||
{
|
||||
flist_node_free(node);
|
||||
}
|
||||
|
||||
FLIST_SET(node->list, list);
|
||||
|
||||
flist_node_t *first_node = FLIST_GET(list->head);
|
||||
if (first_node == NULL)
|
||||
{
|
||||
/* 直接设置链头 */
|
||||
FLIST_SET(node->next, node);
|
||||
FLIST_SET(node->prev, node);
|
||||
FLIST_SET(list->head, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
flist_node_t *first_node_prev = FLIST_GET(first_node->prev);
|
||||
FLIST_SET(node->next, first_node);
|
||||
FLIST_SET(node->prev, first_node_prev);
|
||||
FLIST_SET(first_node_prev->next, node);
|
||||
FLIST_SET(first_node->prev, node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline int flist_remove(flist_t *list, flist_node_t *node)
|
||||
{
|
||||
if (node == NULL || list == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
flist_node_t *first_node = FLIST_GET(list->head);
|
||||
flist_node_t *node_next = FLIST_GET(node->next);
|
||||
if (node_next == NULL || first_node == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (node_next == node) // 是最后一节点
|
||||
{
|
||||
FLIST_SET(list->head, 0);
|
||||
}
|
||||
else // 不是最后一节点
|
||||
{
|
||||
if (first_node == node)
|
||||
{
|
||||
FLIST_SET(list->head, node_next); // 链头指向下一节点
|
||||
}
|
||||
flist_node_t *node_prev = FLIST_GET(node->prev);
|
||||
FLIST_SET(node_prev->next, node_next);
|
||||
FLIST_SET(node_next->prev, node_prev);
|
||||
}
|
||||
|
||||
FLIST_SET(node->list, 0);
|
||||
FLIST_SET(node->next, 0);
|
||||
FLIST_SET(node->prev, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline int flist_insert_next(flist_node_t *tar_node, flist_node_t *new_node)
|
||||
{
|
||||
flist_node_t *tar_node_list = FLIST_GET(tar_node->list);
|
||||
if (tar_node_list == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tar_node == new_node)
|
||||
{
|
||||
flist_node_t *src_node_next = FLIST_GET(new_node->next);
|
||||
if (src_node_next != new_node) // 不是最后一节点
|
||||
{
|
||||
flist_t *list = (flist_t *)FLIST_GET(new_node->list);
|
||||
flist_node_t *first_node = FLIST_GET(list->head);
|
||||
if (first_node == new_node)
|
||||
{
|
||||
FLIST_SET(list->head, src_node_next); // 链头指向下一节点
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FLIST_GET(new_node->list) != NULL)
|
||||
{
|
||||
flist_node_free(new_node);
|
||||
}
|
||||
flist_node_t *tar_node_next = FLIST_GET(tar_node->next);
|
||||
FLIST_SET(new_node->list, tar_node_list);
|
||||
FLIST_SET(new_node->next, tar_node_next);
|
||||
FLIST_SET(new_node->prev, tar_node);
|
||||
FLIST_SET(tar_node_next->prev, new_node);
|
||||
FLIST_SET(tar_node->next, new_node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline int flist_insert_prev(flist_node_t *tar_node, flist_node_t *new_node)
|
||||
{
|
||||
flist_node_t *tar_node_list = FLIST_GET(tar_node->list);
|
||||
if (tar_node_list == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tar_node == new_node)
|
||||
{
|
||||
flist_node_t *src_node_next = FLIST_GET(new_node->next);
|
||||
if (src_node_next != new_node) // 不是最后一节点
|
||||
{
|
||||
flist_t *list = (flist_t *)FLIST_GET(new_node->list);
|
||||
flist_node_t *first_node = (flist_node_t *)FLIST_GET(list->head);
|
||||
if (first_node == new_node)
|
||||
{
|
||||
FLIST_SET(list->head, src_node_next); // 链头指向下一节点
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FLIST_GET(new_node->list) != NULL)
|
||||
{
|
||||
flist_node_free(new_node);
|
||||
}
|
||||
flist_node_t *tar_node_prev = FLIST_GET(tar_node->prev);
|
||||
FLIST_SET(new_node->list, tar_node_list);
|
||||
FLIST_SET(new_node->next, tar_node);
|
||||
FLIST_SET(new_node->prev, tar_node_prev);
|
||||
FLIST_SET(tar_node_prev->next, new_node);
|
||||
FLIST_SET(tar_node->prev, new_node);
|
||||
flist_t *list = (flist_t *)tar_node_list;
|
||||
if (tar_node == FLIST_GET(list->head)) // tar_node 是首个节点
|
||||
{
|
||||
FLIST_SET(list->head, new_node);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline int flist_node_free(flist_node_t *node)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return flist_remove((flist_t *)FLIST_GET(node->list), node);
|
||||
}
|
||||
|
||||
__static_inline void flist_set_next(flist_t *list)
|
||||
{
|
||||
if (list != NULL)
|
||||
{
|
||||
flist_node_t *node = FLIST_GET(list->head);
|
||||
if (node != NULL)
|
||||
{
|
||||
FLIST_SET(list->head, FLIST_GET(node->next)); // 链头指向下一节点
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_take_head(flist_t *list)
|
||||
{
|
||||
flist_node_t *ret = FLIST_GET(list->head);
|
||||
flist_remove(list, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_take_tail(flist_t *list)
|
||||
{
|
||||
flist_node_t *ret = flist_peek_tail(list);
|
||||
flist_remove(list, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_peek_head(flist_t *list)
|
||||
{
|
||||
return FLIST_GET(list->head);
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_peek_tail(flist_t *list)
|
||||
{
|
||||
flist_node_t *list_head = FLIST_GET(list->head);
|
||||
if (list_head == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FLIST_GET(list_head->prev);
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline flist_t *flist_peek_list(flist_node_t *node)
|
||||
{
|
||||
return (flist_t *)FLIST_GET(node->list);
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_peek_first(flist_node_t *node)
|
||||
{
|
||||
flist_node_t *node_list = FLIST_GET(node->list);
|
||||
if (node_list == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FLIST_GET(((flist_t *)node_list)->head);
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_peek_next(flist_node_t *node)
|
||||
{
|
||||
flist_t *pFlist = (flist_t *)FLIST_GET(node->list);
|
||||
if (pFlist == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
flist_node_t *ret = FLIST_GET(node->next);
|
||||
if (flist_peek_head(pFlist) == ret)
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_peek_prev(flist_node_t *node)
|
||||
{
|
||||
flist_t *pFlist = (flist_t *)FLIST_GET(node->list);
|
||||
if (pFlist == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
flist_node_t *ret = FLIST_GET(node->prev);
|
||||
if (flist_peek_tail(pFlist) == ret)
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_peek_next_loop(flist_node_t *node)
|
||||
{
|
||||
return FLIST_GET(node->next);
|
||||
}
|
||||
|
||||
__static_inline flist_node_t *flist_peek_prev_loop(flist_node_t *node)
|
||||
{
|
||||
return FLIST_GET(node->prev);
|
||||
}
|
||||
|
||||
__static_inline int flist_is_pending(flist_node_t *node)
|
||||
{
|
||||
return (FLIST_GET(node->next) != NULL);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
248
components/system/include/list/pslist.h
Executable file
248
components/system/include/list/pslist.h
Executable file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* @file pslist.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PSLIST_H__
|
||||
#define __PSLIST_H__
|
||||
|
||||
#include "sys_types.h"
|
||||
|
||||
typedef struct _psnode sys_psnode_t;
|
||||
|
||||
typedef struct _pslist sys_pslist_t;
|
||||
|
||||
struct _psnode
|
||||
{
|
||||
sys_psnode_t *const *next;
|
||||
};
|
||||
|
||||
struct _pslist
|
||||
{
|
||||
sys_psnode_t *const *head;
|
||||
sys_psnode_t *const *tail;
|
||||
};
|
||||
|
||||
#define _CONTAINER_OF(PTR, TYPE, MEMBER) ((TYPE *)&((uint8_t *)PTR)[-(int)&((TYPE *)0)->MEMBER])
|
||||
|
||||
#define SYS_PSLIST_FOR_EACH_NODE(__sl, __sn) \
|
||||
for (__sn = sys_pslist_peek_head(__sl); __sn; \
|
||||
__sn = sys_pslist_peek_next(__sn))
|
||||
|
||||
#define SYS_PSLIST_ITERATE_FROM_NODE(__sl, __sn) \
|
||||
for (__sn = __sn ? sys_pslist_peek_next_no_check(__sn) \
|
||||
: sys_pslist_peek_head(__sl); \
|
||||
__sn; \
|
||||
__sn = sys_pslist_peek_next(__sn))
|
||||
|
||||
#define SYS_PSLIST_FOR_EACH_NODE_SAFE(__sl, __sn, __sns) \
|
||||
for (__sn = sys_pslist_peek_head(__sl), \
|
||||
__sns = sys_pslist_peek_next(__sn); \
|
||||
__sn; \
|
||||
__sn = __sns, __sns = sys_pslist_peek_next(__sn))
|
||||
|
||||
#define SYS_PSLIST_CONTAINER(__ln, __cn, __n) \
|
||||
((__ln) ? _CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
|
||||
|
||||
#define SYS_PSLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n) \
|
||||
SYS_PSLIST_CONTAINER(sys_pslist_peek_head(__sl), __cn, __n)
|
||||
|
||||
#define SYS_PSLIST_PEEK_TAIL_CONTAINER(__sl, __cn, __n) \
|
||||
SYS_PSLIST_CONTAINER(sys_pslist_peek_tail(__sl), __cn, __n)
|
||||
|
||||
#define SYS_PSLIST_PEEK_NEXT_CONTAINER(__cn, __n) \
|
||||
((__cn) ? SYS_PSLIST_CONTAINER(sys_pslist_peek_next(&((__cn)->__n)), \
|
||||
__cn, __n) \
|
||||
: NULL)
|
||||
|
||||
#define SYS_PSLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \
|
||||
for (__cn = SYS_PSLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n); \
|
||||
__cn; \
|
||||
__cn = SYS_PSLIST_PEEK_NEXT_CONTAINER(__cn, __n))
|
||||
|
||||
#define SYS_PSLIST_FOR_EACH_CONTAINER_SAFE(__sl, __cn, __cns, __n) \
|
||||
for (__cn = SYS_PSLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n), \
|
||||
__cns = SYS_PSLIST_PEEK_NEXT_CONTAINER(__cn, __n); \
|
||||
__cn; \
|
||||
__cn = __cns, __cns = SYS_PSLIST_PEEK_NEXT_CONTAINER(__cn, __n))
|
||||
|
||||
__static_inline void sys_pslist_init(sys_pslist_t *list)
|
||||
{
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
}
|
||||
|
||||
#define SYS_PSLIST_STATIC_INIT(ptr_to_list) \
|
||||
{ \
|
||||
NULL, NULL \
|
||||
}
|
||||
|
||||
__static_inline bool sys_pslist_is_empty(sys_pslist_t *list)
|
||||
{
|
||||
return (!list->head);
|
||||
}
|
||||
|
||||
__static_inline sys_psnode_t *const *sys_pslist_peek_head(sys_pslist_t *list)
|
||||
{
|
||||
return list->head;
|
||||
}
|
||||
|
||||
__static_inline sys_psnode_t *const *sys_pslist_peek_tail(sys_pslist_t *list)
|
||||
{
|
||||
return list->tail;
|
||||
}
|
||||
|
||||
__static_inline sys_psnode_t *const *sys_pslist_peek_next_no_check(sys_psnode_t *const *node)
|
||||
{
|
||||
return (*node)->next;
|
||||
}
|
||||
|
||||
__static_inline sys_psnode_t *const *sys_pslist_peek_next(sys_psnode_t *const *node)
|
||||
{
|
||||
return node ? sys_pslist_peek_next_no_check(node) : NULL;
|
||||
}
|
||||
|
||||
__static_inline void sys_pslist_prepend(sys_pslist_t *list,
|
||||
sys_psnode_t *const *node)
|
||||
{
|
||||
(*node)->next = list->head;
|
||||
list->head = node;
|
||||
|
||||
if (!list->tail)
|
||||
{
|
||||
list->tail = list->head;
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline void sys_pslist_append(sys_pslist_t *list,
|
||||
sys_psnode_t *const *node)
|
||||
{
|
||||
(*node)->next = NULL;
|
||||
|
||||
if (!list->tail)
|
||||
{
|
||||
list->tail = node;
|
||||
list->head = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*(list->tail))->next = node;
|
||||
list->tail = node;
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline void sys_pslist_append_list(sys_pslist_t *list,
|
||||
sys_psnode_t *const *head, sys_psnode_t *const *tail)
|
||||
{
|
||||
if (!list->tail)
|
||||
{
|
||||
list->head = head;
|
||||
list->tail = tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*(list->tail))->next = head;
|
||||
list->tail = tail;
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline void sys_pslist_merge_pslist(sys_pslist_t *list,
|
||||
sys_pslist_t *list_to_append)
|
||||
{
|
||||
sys_pslist_append_list(list, list_to_append->head,
|
||||
list_to_append->tail);
|
||||
sys_pslist_init(list_to_append);
|
||||
}
|
||||
|
||||
__static_inline void sys_pslist_insert(sys_pslist_t *list,
|
||||
sys_psnode_t *const *prev,
|
||||
sys_psnode_t *const *node)
|
||||
{
|
||||
if (!prev)
|
||||
{
|
||||
sys_pslist_prepend(list, node);
|
||||
}
|
||||
else if (!(*prev)->next)
|
||||
{
|
||||
sys_pslist_append(list, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*node)->next = (*prev)->next;
|
||||
(*prev)->next = node;
|
||||
}
|
||||
}
|
||||
|
||||
__static_inline sys_psnode_t *const *sys_pslist_get_not_empty(sys_pslist_t *list)
|
||||
{
|
||||
sys_psnode_t *const *node = list->head;
|
||||
|
||||
list->head = (*node)->next;
|
||||
if (list->tail == node)
|
||||
{
|
||||
list->tail = list->head;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
__static_inline sys_psnode_t *const *sys_pslist_get(sys_pslist_t *list)
|
||||
{
|
||||
return sys_pslist_is_empty(list) ? NULL : sys_pslist_get_not_empty(list);
|
||||
}
|
||||
|
||||
__static_inline void sys_pslist_remove(sys_pslist_t *list,
|
||||
sys_psnode_t *const *prev_node,
|
||||
sys_psnode_t *const *node)
|
||||
{
|
||||
if (!prev_node)
|
||||
{
|
||||
list->head = (*node)->next;
|
||||
|
||||
/* Was node also the tail? */
|
||||
if (list->tail == node)
|
||||
{
|
||||
list->tail = list->head;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*prev_node)->next = (*node)->next;
|
||||
|
||||
/* Was node the tail? */
|
||||
if (list->tail == node)
|
||||
{
|
||||
list->tail = prev_node;
|
||||
}
|
||||
}
|
||||
|
||||
(*node)->next = NULL;
|
||||
}
|
||||
|
||||
__static_inline bool sys_pslist_find_and_remove(sys_pslist_t *list,
|
||||
sys_psnode_t *const *node)
|
||||
{
|
||||
sys_psnode_t *const *prev = NULL;
|
||||
sys_psnode_t *const *test;
|
||||
|
||||
SYS_PSLIST_FOR_EACH_NODE(list, test)
|
||||
{
|
||||
if (test == node)
|
||||
{
|
||||
sys_pslist_remove(list, prev, node);
|
||||
return true;
|
||||
}
|
||||
|
||||
prev = test;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
412
components/system/include/list/slist.h
Executable file
412
components/system/include/list/slist.h
Executable file
@@ -0,0 +1,412 @@
|
||||
/**
|
||||
* @file slist.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SINGLELIST_H__
|
||||
#define __SINGLELIST_H__
|
||||
|
||||
#include "sys_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef LIST_NODE_TYPE
|
||||
#define LIST_NODE_TYPE 0 /* 0 -- 使用指针连结(推荐);1 -- 使用偏移量连结,内存的地址允许被迁移并继续管理(推荐) */
|
||||
#endif
|
||||
|
||||
#if LIST_NODE_TYPE == 1
|
||||
typedef int list_node_t;
|
||||
#else
|
||||
typedef void * list_node_t;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
list_node_t next;
|
||||
} slist_node_t;
|
||||
typedef struct
|
||||
{
|
||||
list_node_t head;
|
||||
list_node_t tail;
|
||||
} slist_t;
|
||||
|
||||
__static_inline void slist_init_list (slist_t *list);
|
||||
__static_inline void slist_init_node (slist_node_t *node);
|
||||
|
||||
__static_inline int slist_insert_font (slist_t *list, slist_node_t *node);
|
||||
__static_inline int slist_insert_tail (slist_t *list, slist_node_t *node);
|
||||
__static_inline int slist_remove (slist_t *list, slist_node_t *node);
|
||||
__static_inline int slist_remove_next (slist_t *list, slist_node_t *prev_node, slist_node_t *remove_node);
|
||||
|
||||
__static_inline int slist_insert_next (slist_t *list, slist_node_t *tar_node, slist_node_t *new_node);
|
||||
__static_inline int slist_insert_prev (slist_t *list, slist_node_t *tar_node, slist_node_t *new_node);
|
||||
|
||||
__static_inline slist_node_t *slist_take_head (slist_t *list);
|
||||
__static_inline slist_node_t *slist_take_tail (slist_t *list);
|
||||
|
||||
__static_inline slist_node_t *slist_peek_head (slist_t *list);
|
||||
__static_inline slist_node_t *slist_peek_tail (slist_t *list);
|
||||
|
||||
__static_inline slist_node_t *slist_peek_next (slist_node_t *node);
|
||||
__static_inline slist_node_t *slist_peek_prev (slist_t *list, slist_node_t *node);
|
||||
|
||||
__static_inline slist_node_t *slist_peek_next_loop (slist_t *list, slist_node_t *node);
|
||||
__static_inline slist_node_t *slist_peek_prev_loop (slist_t *list, slist_node_t *node);
|
||||
|
||||
__static_inline int slist_is_pending (slist_node_t *node);
|
||||
|
||||
#define SLIST_CONTAINER_OF(PTR, TYPE, MEMBER) ((TYPE *)&((uint8_t *)PTR)[-(int)&((TYPE *)0)->MEMBER])
|
||||
|
||||
#define SLIST_FOR_EACH_NODE(__sl, __sn) \
|
||||
for (__sn = slist_peek_head(__sl); __sn; \
|
||||
__sn = slist_peek_next(__sn))
|
||||
|
||||
#define SLIST_ITERATE_FROM_NODE(__sl, __sn) \
|
||||
for (__sn = __sn ? slist_peek_next_no_check(__sn) \
|
||||
: slist_peek_head(__sl); \
|
||||
__sn; \
|
||||
__sn = slist_peek_next(__sn))
|
||||
|
||||
#define SLIST_FOR_EACH_NODE_SAFE(__sl, __sn, __sns) \
|
||||
for (__sn = slist_peek_head(__sl), \
|
||||
__sns = slist_peek_next(__sn); \
|
||||
__sn; \
|
||||
__sn = __sns, __sns = slist_peek_next(__sn))
|
||||
|
||||
#define SLIST_CONTAINER(__ln, __cn, __n) \
|
||||
((__ln) ? SLIST_CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
|
||||
|
||||
#define SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n) \
|
||||
SLIST_CONTAINER(slist_peek_head(__sl), __cn, __n)
|
||||
|
||||
#define SLIST_PEEK_TAIL_CONTAINER(__sl, __cn, __n) \
|
||||
SLIST_CONTAINER(slist_peek_tail(__sl), __cn, __n)
|
||||
|
||||
#define SLIST_PEEK_NEXT_CONTAINER(__cn, __n) \
|
||||
((__cn) ? SLIST_CONTAINER(slist_peek_next(&((__cn)->__n)), __cn, __n) : NULL)
|
||||
|
||||
#define SLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \
|
||||
for (__cn = SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n); \
|
||||
__cn; \
|
||||
__cn = SLIST_PEEK_NEXT_CONTAINER(__cn, __n))
|
||||
|
||||
#define SLIST_FOR_EACH_CONTAINER_SAFE(__sl, __cn, __cns, __n) \
|
||||
for (__cn = SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n), \
|
||||
__cns = SLIST_PEEK_NEXT_CONTAINER(__cn, __n); \
|
||||
__cn; \
|
||||
__cn = __cns, __cns = SLIST_PEEK_NEXT_CONTAINER(__cn, __n))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if LIST_NODE_TYPE == 1
|
||||
#define SLIST_SET(Value1, Value2) (Value1 = Value2 == 0 ? 0 : ((int)Value2 - (int)&Value1) | 1)
|
||||
#define SLIST_GET(Value) ((slist_node_t*)(Value == 0 ? 0 : ((int)&Value + Value) & ~1))
|
||||
#else
|
||||
#define SLIST_SET(Value1, Value2) (Value1 = (list_node_t)Value2)
|
||||
#define SLIST_GET(Value) ((slist_node_t*)(Value))
|
||||
#endif
|
||||
|
||||
__static_inline void slist_init_list(slist_t *list)
|
||||
{
|
||||
SLIST_SET(list->head, 0);
|
||||
SLIST_SET(list->tail, 0);
|
||||
}
|
||||
__static_inline void slist_init_node(slist_node_t *node)
|
||||
{
|
||||
SLIST_SET(node->next, 0);
|
||||
}
|
||||
__static_inline int slist_insert_font(slist_t *list, slist_node_t *node)
|
||||
{
|
||||
if (SLIST_GET(node->next) != NULL)
|
||||
{
|
||||
// SYS_LOG_WRN("Node is pending");
|
||||
return -1;
|
||||
}
|
||||
|
||||
slist_node_t *head_node = SLIST_GET(list->head);
|
||||
if (head_node)
|
||||
{
|
||||
SLIST_SET(node->next, head_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
SLIST_SET(node->next, node);
|
||||
SLIST_SET(list->tail, node);
|
||||
}
|
||||
SLIST_SET(list->head, node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
__static_inline int slist_insert_tail(slist_t *list, slist_node_t *node)
|
||||
{
|
||||
if (SLIST_GET(node->next) != NULL)
|
||||
{
|
||||
// SYS_LOG_WRN("Node is pending");
|
||||
return -1;
|
||||
}
|
||||
|
||||
SLIST_SET(node->next, node);
|
||||
if (SLIST_GET(list->head) == NULL)
|
||||
{
|
||||
SLIST_SET(list->head, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
slist_node_t *tail_node = (slist_node_t *)SLIST_GET(list->tail);
|
||||
|
||||
SLIST_SET(tail_node->next, node);
|
||||
}
|
||||
SLIST_SET(list->tail, node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
__static_inline int slist_remove(slist_t *list, slist_node_t *node)
|
||||
{
|
||||
if (node == NULL || list == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
slist_node_t *list_head = SLIST_GET(list->head);
|
||||
slist_node_t *node_next = SLIST_GET(node->next);
|
||||
if (node_next == NULL || list_head == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (node == list_head) // node 是首个节点
|
||||
{
|
||||
if (node == SLIST_GET(list->tail)) // node 是最后一个节点
|
||||
{
|
||||
SLIST_SET(list->head, 0);
|
||||
SLIST_SET(list->tail, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SLIST_SET(list->head, node_next);
|
||||
}
|
||||
}
|
||||
else // node 不是首个节点
|
||||
{
|
||||
slist_node_t *prev_node = slist_peek_prev(list, node);
|
||||
if (prev_node == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (node == SLIST_GET(list->tail)) // node 是最后一个节点
|
||||
{
|
||||
SLIST_SET(list->tail, prev_node);
|
||||
SLIST_SET(prev_node->next, prev_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
SLIST_SET(prev_node->next, node_next);
|
||||
}
|
||||
}
|
||||
|
||||
SLIST_SET(node->next, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
__static_inline int slist_remove_next(slist_t *list, slist_node_t *prev_node, slist_node_t *remove_node)
|
||||
{
|
||||
if (remove_node == NULL || list == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
slist_node_t *list_head = SLIST_GET(list->head);
|
||||
slist_node_t *node_next = SLIST_GET(remove_node->next);
|
||||
if (node_next == NULL || list_head == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (remove_node == list_head) // remove_node 是首个节点
|
||||
{
|
||||
if (remove_node == SLIST_GET(list->tail)) // remove_node 是最后一个节点
|
||||
{
|
||||
SLIST_SET(list->head, 0);
|
||||
SLIST_SET(list->tail, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SLIST_SET(list->head, node_next);
|
||||
}
|
||||
}
|
||||
else // remove_node 不是首个节点
|
||||
{
|
||||
if (prev_node == NULL)
|
||||
{
|
||||
prev_node = slist_peek_prev(list, remove_node);
|
||||
if (prev_node == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (remove_node == SLIST_GET(list->tail)) // remove_node 是最后一个节点
|
||||
{
|
||||
SLIST_SET(list->tail, prev_node);
|
||||
SLIST_SET(prev_node->next, prev_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
SLIST_SET(prev_node->next, node_next);
|
||||
}
|
||||
}
|
||||
|
||||
SLIST_SET(remove_node->next, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
__static_inline int slist_insert_next(slist_t *list, slist_node_t *tar_node, slist_node_t *new_node)
|
||||
{
|
||||
slist_node_t *tar_node_next = SLIST_GET(tar_node->next);
|
||||
if (SLIST_GET(list->head) == NULL || tar_node_next == NULL || SLIST_GET(new_node->next) != NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tar_node == SLIST_GET(list->tail)) // tar_node 是最后一个节点
|
||||
{
|
||||
SLIST_SET(new_node->next, new_node);
|
||||
SLIST_SET(tar_node->next, new_node);
|
||||
SLIST_SET(list->tail, new_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
SLIST_SET(new_node->next, tar_node_next);
|
||||
SLIST_SET(tar_node->next, new_node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
__static_inline int slist_insert_prev(slist_t *list, slist_node_t *tar_node, slist_node_t *new_node)
|
||||
{
|
||||
slist_node_t *list_head = SLIST_GET(list->head);
|
||||
if (list_head == NULL || SLIST_GET(tar_node->next) == NULL || SLIST_GET(new_node->next) != NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tar_node == list_head) // tar_node 是首个节点
|
||||
{
|
||||
SLIST_SET(new_node->next, list_head);
|
||||
SLIST_SET(list->head, new_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
slist_node_t *prev_node = slist_peek_prev(list, tar_node);
|
||||
if (prev_node == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
SLIST_SET(new_node->next, tar_node);
|
||||
SLIST_SET(prev_node->next, new_node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__static_inline slist_node_t *slist_take_head(slist_t *list)
|
||||
{
|
||||
slist_node_t *ret = SLIST_GET(list->head);
|
||||
slist_remove(list, ret);
|
||||
return ret;
|
||||
}
|
||||
__static_inline slist_node_t *slist_take_tail(slist_t *list)
|
||||
{
|
||||
slist_node_t *ret = SLIST_GET(list->tail);
|
||||
slist_remove(list, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
__static_inline slist_node_t *slist_peek_head(slist_t *list)
|
||||
{
|
||||
return SLIST_GET(list->head);
|
||||
}
|
||||
__static_inline slist_node_t *slist_peek_tail(slist_t *list)
|
||||
{
|
||||
return SLIST_GET(list->tail);
|
||||
}
|
||||
|
||||
__static_inline slist_node_t *slist_peek_next(slist_node_t *node)
|
||||
{
|
||||
slist_node_t *next_node = SLIST_GET(node->next);
|
||||
if (next_node == node)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return next_node;
|
||||
}
|
||||
}
|
||||
__static_inline slist_node_t *slist_peek_prev(slist_t *list, slist_node_t *node)
|
||||
{
|
||||
slist_node_t *prev_node = NULL;
|
||||
slist_node_t *test_node = SLIST_GET(list->head);
|
||||
while (test_node && test_node != node && prev_node != test_node)
|
||||
{
|
||||
prev_node = test_node;
|
||||
test_node = SLIST_GET(test_node->next);
|
||||
}
|
||||
if (test_node == node)
|
||||
{
|
||||
return prev_node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__static_inline slist_node_t *slist_peek_next_loop(slist_t *list, slist_node_t *node)
|
||||
{
|
||||
slist_node_t *next_node = SLIST_GET(node->next);
|
||||
if (next_node == node)
|
||||
{
|
||||
return SLIST_GET(list->head);
|
||||
}
|
||||
else
|
||||
{
|
||||
return next_node;
|
||||
}
|
||||
}
|
||||
__static_inline slist_node_t *slist_peek_prev_loop(slist_t *list, slist_node_t *node)
|
||||
{
|
||||
slist_node_t *prev_node = SLIST_GET(list->tail);
|
||||
slist_node_t *test_node = SLIST_GET(list->head);
|
||||
while (test_node && test_node != node && prev_node != test_node)
|
||||
{
|
||||
prev_node = test_node;
|
||||
test_node = SLIST_GET(test_node->next);
|
||||
}
|
||||
if (test_node == node)
|
||||
{
|
||||
return prev_node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__static_inline int slist_is_pending(slist_node_t *node)
|
||||
{
|
||||
return (SLIST_GET(node->next) != NULL);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
24
components/system/include/os/os.h
Executable file
24
components/system/include/os/os.h
Executable file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @file os.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_H__
|
||||
#define __OS_H__
|
||||
|
||||
#include "os/os_thread.h"
|
||||
#include "os/os_timer.h"
|
||||
#include "os/os_work.h"
|
||||
#include "os/os_ipc.h"
|
||||
#include "os/os_semaphore.h"
|
||||
#include "os/os_mutex.h"
|
||||
#include "os/os_service.h"
|
||||
#include "os/os_heap.h"
|
||||
|
||||
#endif /* __OS_H__ */
|
||||
68
components/system/include/os/os_common.h
Executable file
68
components/system/include/os/os_common.h
Executable file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file os_common.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_COMMON_H__
|
||||
#define __OS_COMMON_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
OS_PRIORITY_IDLE = 0,
|
||||
OS_PRIORITY_LOWEST = 1,
|
||||
OS_PRIORITY_LOWER = 2,
|
||||
OS_PRIORITY_LOW = 3,
|
||||
OS_PRIORITY_NORMAL = 4,
|
||||
OS_PRIORITY_HIGH = 5,
|
||||
OS_PRIORITY_HIGHER = 6,
|
||||
OS_PRIORITY_HIGHEST = 7
|
||||
} os_priority;
|
||||
|
||||
typedef enum {
|
||||
OS_OK = 0, /* success */
|
||||
OS_FAIL = -1, /* general failure */
|
||||
OS_E_NOMEM = -2, /* out of memory */
|
||||
OS_E_PARAM = -3, /* invalid parameter */
|
||||
OS_E_TIMEOUT = -4, /* operation timeout */
|
||||
OS_E_ISR = -5, /* not allowed in ISR context */
|
||||
} os_state;
|
||||
|
||||
typedef void * os_handle_t;
|
||||
|
||||
typedef size_t os_time_t;
|
||||
|
||||
#define OS_INVALID_HANDLE NULL /* OS invalid handle */
|
||||
#define OS_WAIT_FOREVER 0xffffffffU /* Wait forever timeout value */
|
||||
#define OS_SEMAPHORE_MAX_COUNT 0xffffffffU /* Maximum count value for semaphore */
|
||||
|
||||
#define OS_MSEC_PER_SEC 1000U /* milliseconds per second */
|
||||
#define OS_USEC_PER_MSEC 1000U /* microseconds per millisecond */
|
||||
#define OS_USEC_PER_SEC 1000000U /* microseconds per second */
|
||||
|
||||
#define OS_TICK (OS_USEC_PER_SEC / OS_TICK_RATE) /* microseconds per tick */
|
||||
|
||||
#define OS_SecsToTicks(sec) ((os_time_t)(sec) * OS_TICK_RATE)
|
||||
#define OS_MSecsToTicks(msec) ((os_time_t)(OS_TICK_RATE < OS_MSEC_PER_SEC ? (msec) / (OS_TICK / OS_USEC_PER_MSEC) : (msec) * (OS_USEC_PER_MSEC / OS_TICK)))
|
||||
#define OS_TicksToMSecs(t) ((os_time_t)(OS_TICK_RATE < OS_MSEC_PER_SEC ? (t) * (OS_TICK / OS_USEC_PER_MSEC) : (t) / (OS_USEC_PER_MSEC / OS_TICK)))
|
||||
#define OS_TicksToSecs(t) ((os_time_t)(t) / (OS_USEC_PER_SEC / OS_TICK))
|
||||
|
||||
#define OS_CONTAINER_OF(PTR, TYPE, MEMBER) ((TYPE *)&((uint8_t *)PTR)[-(int)&((TYPE *)0)->MEMBER])
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OS_COMMON_H__ */
|
||||
33
components/system/include/os/os_heap.h
Executable file
33
components/system/include/os/os_heap.h
Executable file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @file os_heap.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_HEAP_H__
|
||||
#define __OS_HEAP_H__
|
||||
|
||||
#include "os/os_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void *os_malloc(size_t size);
|
||||
void *os_calloc(size_t size);
|
||||
void *os_realloc(void *p, size_t size);
|
||||
void os_free(void *p);
|
||||
|
||||
void os_heap_info(size_t *used_size, size_t *free_size, size_t *max_block_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OS_HEAP_H__ */
|
||||
103
components/system/include/os/os_ipc.h
Executable file
103
components/system/include/os/os_ipc.h
Executable file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @file os_ipc.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_IPC_H__
|
||||
#define __OS_IPC_H__
|
||||
|
||||
#include "os/os_work.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
typedef os_handle_t os_fifo_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_fifo_handle_t handle;
|
||||
} os_fifo_t;
|
||||
|
||||
os_state os_fifo_q_create(os_fifo_t *fifo_handle);
|
||||
os_state os_fifo_q_delete(os_fifo_t *fifo_handle);
|
||||
os_state os_fifo_q_clr(os_fifo_t *fifo_handle);
|
||||
|
||||
void os_fifo_q_regist(os_fifo_t *fifo_handle, os_work_t *work_handle, int delay_ticks);
|
||||
void os_fifo_q_unregist(os_fifo_t *fifo_handle);
|
||||
|
||||
void *os_fifo_alloc(size_t size);
|
||||
os_state os_fifo_put(os_fifo_t *fifo_handle, void *fifo_data);
|
||||
|
||||
void *os_fifo_take(os_fifo_t *fifo_handle, os_time_t wait_ms);
|
||||
os_state os_fifo_free(void *fifo_data);
|
||||
|
||||
void *os_fifo_peek_head(os_fifo_t *fifo_handle);
|
||||
void *os_fifo_peek_tail(os_fifo_t *fifo_handle);
|
||||
|
||||
bool os_fifo_q_is_valid(os_fifo_t *fifo_handle);
|
||||
|
||||
typedef os_handle_t os_queue_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_queue_handle_t handle;
|
||||
} os_queue_t;
|
||||
|
||||
os_state os_queue_create(os_queue_t *queue_handle, size_t queueLen, size_t itemSize);
|
||||
os_state os_queue_delete(os_queue_t *queue_handle);
|
||||
os_state os_queue_clr(os_queue_t *queue_handle);
|
||||
|
||||
void os_queue_regist(os_queue_t *queue_handle, os_work_t *work_handle, int delay_ticks);
|
||||
void os_queue_unregist(os_queue_t *queue_handle);
|
||||
|
||||
os_state os_queue_send(os_queue_t *queue_handle, const void *item, os_time_t wait_ms);
|
||||
os_state os_queue_recv(os_queue_t *queue_handle, void *item, os_time_t wait_ms);
|
||||
|
||||
void *os_queue_peek_head(os_queue_t *queue_handle);
|
||||
void *os_queue_peek_tail(os_queue_t *queue_handle);
|
||||
|
||||
size_t os_queue_get_item_size(os_queue_t *queue_handle);
|
||||
|
||||
bool os_queue_is_valid(os_queue_t *queue_handle);
|
||||
|
||||
typedef os_handle_t os_pipe_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_pipe_handle_t handle;
|
||||
} os_pipe_t;
|
||||
|
||||
os_state os_pipe_create(os_pipe_t *pipe_handle, size_t pipe_size);
|
||||
os_state os_pipe_delete(os_pipe_t *pipe_handle);
|
||||
os_state os_pipe_clr(os_pipe_t *pipe_handle);
|
||||
|
||||
void os_pipe_regist(os_pipe_t *pipe_handle, os_work_t *work_handle, int delay_ticks);
|
||||
void os_pipe_unregist(os_pipe_t *pipe_handle);
|
||||
|
||||
size_t os_pipe_poll_write(os_pipe_t *pipe_handle, uint8_t data);
|
||||
size_t os_pipe_fifo_fill(os_pipe_t *pipe_handle, const void *data, size_t size);
|
||||
size_t os_pipe_poll_read(os_pipe_t *pipe_handle, uint8_t *data);
|
||||
size_t os_pipe_fifo_read(os_pipe_t *pipe_handle, void *data, size_t size);
|
||||
|
||||
bool os_pipe_is_ne(os_pipe_t *pipe_handle);
|
||||
size_t os_pipe_get_valid_size(os_pipe_t *pipe_handle);
|
||||
size_t os_pipe_get_empty_size(os_pipe_t *pipe_handle);
|
||||
|
||||
void os_pipe_peek_valid(os_pipe_t *pipe_handle, void **dst_base, size_t *dst_size);
|
||||
void os_pipe_peek_empty(os_pipe_t *pipe_handle, void **dst_base, size_t *dst_size);
|
||||
|
||||
bool os_pipe_is_valid(os_pipe_t *pipe_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif /* __OS_IPC_H__ */
|
||||
44
components/system/include/os/os_mutex.h
Executable file
44
components/system/include/os/os_mutex.h
Executable file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file os_mutex.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_MUTEX_H__
|
||||
#define __OS_MUTEX_H__
|
||||
|
||||
#include "os/os_common.h"
|
||||
#include "os/os_thread.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef os_handle_t os_mutex_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_mutex_handle_t handle;
|
||||
} os_mutex_t;
|
||||
|
||||
os_state os_mutex_create(os_mutex_t *mutex);
|
||||
os_state os_mutex_delete(os_mutex_t *mutex);
|
||||
|
||||
os_state os_mutex_lock(os_mutex_t *mutex, os_time_t wait_ms);
|
||||
os_state os_mutex_unlock(os_mutex_t *mutex);
|
||||
|
||||
os_thread_handle_t os_mutex_get_holder(os_mutex_t *mutex);
|
||||
|
||||
bool os_mutex_is_valid(os_mutex_t *mutex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OS_MUTEX_H__ */
|
||||
41
components/system/include/os/os_semaphore.h
Executable file
41
components/system/include/os/os_semaphore.h
Executable file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @file os_semaphore.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_SEMAPHORE_H__
|
||||
#define __OS_SEMAPHORE_H__
|
||||
|
||||
#include "os/os_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef os_handle_t os_sem_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_sem_handle_t handle;
|
||||
} os_sem_t;
|
||||
|
||||
os_state os_sem_create(os_sem_t *sem, size_t init_value, size_t max_value);
|
||||
os_state os_sem_delete(os_sem_t *sem);
|
||||
|
||||
os_state os_sem_take(os_sem_t *sem, os_time_t wait_ms);
|
||||
os_state os_sem_release(os_sem_t *sem);
|
||||
|
||||
bool os_sem_is_valid(os_sem_t *sem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OS_SEMAPHORE_H__ */
|
||||
56
components/system/include/os/os_service.h
Executable file
56
components/system/include/os/os_service.h
Executable file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file os_service.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_SERVER_H__
|
||||
#define __OS_SERVER_H__
|
||||
|
||||
#include "os/os_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int os_start(void *heap_mem, size_t heap_size);
|
||||
|
||||
void os_int_entry(void);
|
||||
void os_int_exit(void);
|
||||
|
||||
bool os_is_isr_context(void);
|
||||
|
||||
void os_interrupt_disable(void);
|
||||
void os_interrupt_enable(void);
|
||||
|
||||
void os_scheduler_suspend(void);
|
||||
void os_scheduler_resume(void);
|
||||
|
||||
bool os_scheduler_is_running(void);
|
||||
|
||||
void os_sys_print_info(void);
|
||||
|
||||
os_time_t os_get_sys_time(void);
|
||||
|
||||
size_t os_get_sys_ticks(void);
|
||||
|
||||
os_time_t os_calc_ticks_to_msec(size_t ticks);
|
||||
size_t os_calc_msec_to_ticks(os_time_t msec);
|
||||
|
||||
size_t os_cpu_usage(void);
|
||||
|
||||
int os_get_err(void);
|
||||
|
||||
void os_set_err(int err);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OS_SERVER_H__ */
|
||||
68
components/system/include/os/os_thread.h
Executable file
68
components/system/include/os/os_thread.h
Executable file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file os_thread.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_THREAD_H__
|
||||
#define __OS_THREAD_H__
|
||||
|
||||
#include "os/os_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef os_handle_t os_thread_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_thread_handle_t handle;
|
||||
} os_thread_t;
|
||||
|
||||
typedef void (*os_thread_entry_t)(void *);
|
||||
|
||||
os_state os_thread_init(os_thread_t *thread,
|
||||
const char *name,
|
||||
os_thread_entry_t entry,
|
||||
void *arg,
|
||||
void *stack_base,
|
||||
size_t stack_size,
|
||||
os_priority priority);
|
||||
|
||||
os_state os_thread_create(os_thread_t *thread,
|
||||
const char *name,
|
||||
os_thread_entry_t entry,
|
||||
void *arg,
|
||||
size_t stack_size,
|
||||
os_priority priority);
|
||||
|
||||
os_state os_thread_delete(os_thread_t *thread);
|
||||
|
||||
void os_thread_sleep(os_time_t msec);
|
||||
|
||||
void os_thread_yield(void);
|
||||
|
||||
void os_thread_suspend(os_thread_t *thread);
|
||||
|
||||
void os_thread_resume(os_thread_t *thread);
|
||||
|
||||
os_thread_handle_t os_thread_get_self(void);
|
||||
|
||||
const char *os_thread_get_name(os_thread_t *thread);
|
||||
|
||||
size_t os_thread_stack_min(os_thread_t *thread);
|
||||
|
||||
bool os_thread_is_valid(os_thread_t *thread);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OS_THREAD_H__ */
|
||||
55
components/system/include/os/os_timer.h
Executable file
55
components/system/include/os/os_timer.h
Executable file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file os_timer.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_TIMER_H__
|
||||
#define __OS_TIMER_H__
|
||||
|
||||
#include "os/os_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef os_handle_t os_timer_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_timer_handle_t handle;
|
||||
} os_timer_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OS_TIMER_ONCE = 0, /* one shot timer */
|
||||
OS_TIMER_PERIODIC = 1 /* periodic timer */
|
||||
} os_timer_type_t;
|
||||
|
||||
typedef void (*os_timer_cb_fn)(void *arg);
|
||||
|
||||
os_state os_timer_create(os_timer_t *timer, os_timer_cb_fn cb, void *arg);
|
||||
|
||||
os_state os_timer_delete(os_timer_t *timer);
|
||||
|
||||
os_state os_timer_set_period(os_timer_t *timer, os_timer_type_t type, os_time_t period_ms);
|
||||
|
||||
os_state os_timer_start(os_timer_t *timer);
|
||||
|
||||
os_state os_timer_stop(os_timer_t *timer);
|
||||
|
||||
bool os_timer_is_pending(os_timer_t *timer);
|
||||
|
||||
bool os_timer_is_valid(os_timer_t *timer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OS_TIMER_H__ */
|
||||
71
components/system/include/os/os_work.h
Executable file
71
components/system/include/os/os_work.h
Executable file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file os_work.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_WORK_H__
|
||||
#define __OS_WORK_H__
|
||||
|
||||
#include "os/os_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
typedef os_handle_t os_work_q_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_work_q_handle_t handle;
|
||||
} os_work_q_t;
|
||||
|
||||
extern os_work_q_t *default_os_work_q_hdl;
|
||||
|
||||
os_state os_work_q_create(os_work_q_t *work_q_handle,
|
||||
const char *name,
|
||||
size_t stack_size,
|
||||
os_priority priority);
|
||||
|
||||
os_state os_work_q_delete(os_work_q_t *work_q_handle);
|
||||
|
||||
bool os_work_q_is_valid(os_work_q_t *work_q_handle);
|
||||
bool os_work_q_delayed_state(os_work_q_t *work_q_handle);
|
||||
bool os_work_q_ready_state(os_work_q_t *work_q_handle);
|
||||
|
||||
typedef os_handle_t os_work_handle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
os_work_handle_t handle;
|
||||
} os_work_t;
|
||||
|
||||
typedef void (*os_work_fn)(void *arg);
|
||||
|
||||
os_state os_work_create(os_work_t *work_handle, const char *name, os_work_fn work_route, void *arg, uint8_t sub_prior);
|
||||
void os_work_delete(os_work_t *work_handle);
|
||||
|
||||
bool os_work_is_valid(os_work_t *work_handle);
|
||||
bool os_work_is_pending(os_work_t *work_handle);
|
||||
os_time_t os_work_time_remain(os_work_t *work_handle);
|
||||
|
||||
void os_work_submit(os_work_q_t *work_q_handle, os_work_t *work_handle, os_time_t delay_ms);
|
||||
void os_work_resume(os_work_t *work_handle, os_time_t delay_ms);
|
||||
void os_work_suspend(os_work_t *work_handle);
|
||||
|
||||
void os_work_yield(os_time_t ms);
|
||||
void os_work_sleep(os_time_t ms);
|
||||
void os_work_later(os_time_t ms);
|
||||
void os_work_later_until(os_time_t ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif
|
||||
75
components/system/include/sys/features.h
Executable file
75
components/system/include/sys/features.h
Executable file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file features.h
|
||||
* @author
|
||||
* @brief
|
||||
* In order to redefine int32_t to int when compiles using GCC, this file is
|
||||
* added to override <sys/features.h> of GCC.
|
||||
* @version 0.1
|
||||
* @date 2021-12-09
|
||||
*
|
||||
* @copyright Copyright (c) 2021
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LIBC_SYS_FEATURES_H_
|
||||
#define _LIBC_SYS_FEATURES_H_
|
||||
|
||||
/*
|
||||
* Redefine some macros defined by GCC
|
||||
*/
|
||||
#ifdef __INT32_MAX__
|
||||
#undef __INT32_MAX__
|
||||
#endif
|
||||
#define __INT32_MAX__ 2147483647
|
||||
|
||||
#ifdef __UINT32_MAX__
|
||||
#undef __UINT32_MAX__
|
||||
#endif
|
||||
#define __UINT32_MAX__ 4294967295U
|
||||
|
||||
#ifdef __INT_LEAST32_MAX__
|
||||
#undef __INT_LEAST32_MAX__
|
||||
#endif
|
||||
#define __INT_LEAST32_MAX__ 2147483647
|
||||
|
||||
#ifdef __UINT_LEAST32_MAX__
|
||||
#undef __UINT_LEAST32_MAX__
|
||||
#endif
|
||||
#define __UINT_LEAST32_MAX__ 4294967295U
|
||||
|
||||
#ifdef __INT_LEAST32_TYPE__
|
||||
#undef __INT_LEAST32_TYPE__
|
||||
#endif
|
||||
#define __INT_LEAST32_TYPE__ int
|
||||
|
||||
#ifdef __UINT_LEAST32_TYPE__
|
||||
#undef __UINT_LEAST32_TYPE__
|
||||
#endif
|
||||
#define __UINT_LEAST32_TYPE__ unsigned int
|
||||
|
||||
#ifdef __INT32_C
|
||||
#undef __INT32_C
|
||||
#endif
|
||||
#define __INT32_C(c) c
|
||||
|
||||
#ifdef __UINT32_C
|
||||
#undef __UINT32_C
|
||||
#endif
|
||||
#define __UINT32_C(c) c ## U
|
||||
|
||||
#ifdef __INT32_TYPE__
|
||||
#undef __INT32_TYPE__
|
||||
#endif
|
||||
#define __INT32_TYPE__ int
|
||||
|
||||
#ifdef __UINT32_TYPE__
|
||||
#undef __UINT32_TYPE__
|
||||
#endif
|
||||
#define __UINT32_TYPE__ unsigned int
|
||||
|
||||
/*
|
||||
* Include <sys/features.h> of compiler
|
||||
*/
|
||||
#include_next <sys/features.h>
|
||||
|
||||
#endif /* _LIBC_SYS_FEATURES_H_ */
|
||||
2
components/system/include/sys/reent.h
Normal file
2
components/system/include/sys/reent.h
Normal file
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
#include_next <sys/reent.h>
|
||||
400
components/system/include/sys_init.h
Executable file
400
components/system/include/sys_init.h
Executable file
@@ -0,0 +1,400 @@
|
||||
/**
|
||||
* @file sys_init.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-06-01
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SYS_INIT_H__
|
||||
#define __SYS_INIT_H__
|
||||
|
||||
#include "sys_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
/* initialize function -------------------------------------------------------- */
|
||||
|
||||
#define INIT_EXPORT_BOARD(FN) _INIT_EXPORT(FN, 0, 1) // 定义自动初始化函数:非常早期的初始化,此时调度器还未启动
|
||||
#define INIT_EXPORT_PREV(FN) _INIT_EXPORT(FN, 1, 1) // 定义自动初始化函数:主要是用于纯软件的初始化、没有太多依赖的函数
|
||||
#define INIT_EXPORT_DEVICE(FN) _INIT_EXPORT(FN, 2, 1) // 定义自动初始化函数:外设驱动初始化相关,比如网卡设备
|
||||
#define INIT_EXPORT_COMPONENT(FN) _INIT_EXPORT(FN, 3, 1) // 定义自动初始化函数:组件初始化,比如文件系统或者 LWIP
|
||||
#define INIT_EXPORT_ENV(FN) _INIT_EXPORT(FN, 4, 1) // 定义自动初始化函数:系统环境初始化,比如挂载文件系统
|
||||
#define INIT_EXPORT_APP(FN, PRIOR) _INIT_EXPORT(FN, 5, PRIOR) // 定义自动初始化函数:应用初始化,比如 GUI 应用(PRIOR 建议取值为 0 或 10..99)
|
||||
|
||||
/* module define -------------------------------------------------------------- */
|
||||
|
||||
#define OBJ_EXPORT_DEVICE(OBJECT, NAME) _MODULE_EXPORT(OBJECT, NAME, MODULE_TYPE_DEVICE)
|
||||
#define OBJ_EXPORT_COMPONENT(OBJECT, NAME) _MODULE_EXPORT(OBJECT, NAME, MODULE_TYPE_COMPONENT)
|
||||
|
||||
/* module api------------------------------------------------------------------ */
|
||||
|
||||
__static_inline const void *device_binding(const char *name);
|
||||
__static_inline const char *device_name(const void *object);
|
||||
__static_inline const char *device_search(const char *prefix_name, unsigned int num);
|
||||
|
||||
__static_inline const void *component_binding(const char *name);
|
||||
__static_inline const char *component_name(const void *object);
|
||||
__static_inline const char *component_search(const char *prefix_name, unsigned int num);
|
||||
|
||||
/* code ----------------------------------------------------------------------- */
|
||||
|
||||
/** @defgroup initialize function
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int (*fn)(void); // 初始化函数地址
|
||||
const char *fn_name; // debug: 函数关联名
|
||||
const char *file; // debug: 所在文件名
|
||||
uint16_t line; // debug: 所在文件行
|
||||
uint8_t level; // debug: 初始化等级
|
||||
uint8_t prior; // debug: 初始化优先级
|
||||
} sys_init_t;
|
||||
|
||||
/**
|
||||
* @def _INIT_EXPORT
|
||||
*
|
||||
* @brief 用于如下宏:
|
||||
* INIT_EXPORT_BOARD
|
||||
* INIT_EXPORT_PREV
|
||||
* INIT_EXPORT_DEVICE
|
||||
* INIT_EXPORT_COMPONENT
|
||||
* INIT_EXPORT_ENV
|
||||
* INIT_EXPORT_APP
|
||||
* 输出一个 sys_init_t 类型的数据。
|
||||
* 这些数据将被归为 "(.s_sys_init_t.*)" 段中,编译阶段被排序并链接。
|
||||
* 需要将文件 "sys_init.ld" 添加到链接脚本。
|
||||
* 用于自动初始化。
|
||||
*
|
||||
* @param FN 待函数
|
||||
*
|
||||
* @param LEVEL 按功能划分的优先级
|
||||
*
|
||||
* @param PRIOR 同一功能等级中的优先级,0..99,数值越小越优早执行
|
||||
*
|
||||
* 举例:
|
||||
* @verbatim
|
||||
* static int _init_env_template(void)
|
||||
* {
|
||||
* SYS_LOG_INF("done.\r\n");
|
||||
* return 0;
|
||||
* }
|
||||
* INIT_EXPORT_ENV(_init_env_template);
|
||||
*
|
||||
* static int _init_app_template1(void)
|
||||
* {
|
||||
* SYS_LOG_INF("done.\r\n");
|
||||
* return 0;
|
||||
* }
|
||||
* static int _init_app_template2(void)
|
||||
* {
|
||||
* SYS_LOG_INF("done.\r\n");
|
||||
* return 0;
|
||||
* }
|
||||
* INIT_EXPORT_APP(_init_app_template1, 0);
|
||||
* INIT_EXPORT_APP(_init_app_template2, 1);
|
||||
* @endverbatim
|
||||
*/
|
||||
#define _INIT_EXPORT(FN, LEVEL, PRIOR) \
|
||||
__used __section(".s_sys_init_t." #LEVEL "." #PRIOR) static sys_init_t const \
|
||||
__sys_init_##FN = { \
|
||||
.fn = FN, \
|
||||
.fn_name = #FN, \
|
||||
.line = __LINE__, \
|
||||
.file = __FILE__, \
|
||||
.level = LEVEL, \
|
||||
.prior = PRIOR, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup initialize module
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum __packed // 定义模块的类型
|
||||
{
|
||||
MODULE_TYPE_DEVICE, // 模块类型为驱动
|
||||
MODULE_TYPE_COMPONENT, // 模块类型为组件
|
||||
// ...
|
||||
} module_type_t;
|
||||
|
||||
typedef struct // 模块数据结构
|
||||
{
|
||||
const char *name; // 模块数据关联名
|
||||
const void *obj; // 模块数据地址
|
||||
module_type_t type; // 模块数据类型
|
||||
uint16_t line; // debug: 所在文件行
|
||||
const char *file; // debug: 所在文件名
|
||||
} module_t;
|
||||
|
||||
/**
|
||||
* @def _MODULE_EXPORT
|
||||
*
|
||||
* @brief 输出一个指定模块数据结构。用于如下宏:
|
||||
* OBJ_EXPORT_DEVICE
|
||||
* OBJ_EXPORT_COMPONENT
|
||||
* 这些数据结构将被归为 ".sys_module_data" 段中,编译阶段被链接。
|
||||
* 需要将文件 "sys_init.ld" 添加到链接脚本。
|
||||
* 使用 sys_module_binding() 可找到模块数据结构。
|
||||
*
|
||||
* @param OBJECT 子对象(符号)
|
||||
*
|
||||
* @param OBJ_NAME 子对象关联名称(字符串)。使用 sys_module_search() 可遍历已有对象关联名称
|
||||
*
|
||||
* @param MODULE_TYPE 模块类型 @ref module_type_t
|
||||
*
|
||||
* 举例:
|
||||
* @verbatim
|
||||
* #include "device_template.h"
|
||||
*
|
||||
* static void _set_data(device_template_t dev, int data);
|
||||
* static int _get_data(device_template_t dev);
|
||||
*
|
||||
* static device_template_config_t config;
|
||||
*
|
||||
* static struct device_template const device = {
|
||||
* .api = {
|
||||
* .set_data = _set_data,
|
||||
* .get_data = _get_data,
|
||||
* },
|
||||
* .config = &config,
|
||||
* };
|
||||
* OBJ_EXPORT_DEVICE(device, "DRV1");
|
||||
*
|
||||
* static void _set_data(device_template_t dev, int data)
|
||||
* {
|
||||
* dev->config->data = data;
|
||||
* }
|
||||
*
|
||||
* static int _get_data(device_template_t dev)
|
||||
* {
|
||||
* return dev->config->data;
|
||||
* }
|
||||
* @endverbatim
|
||||
*
|
||||
*/
|
||||
#define _MODULE_EXPORT(OBJECT, OBJ_NAME, MODULE_TYPE) \
|
||||
__used __section(".sys_module_data.1") static module_t const \
|
||||
__sys_module_##OBJECT = { \
|
||||
.name = OBJ_NAME, \
|
||||
.obj = &OBJECT, \
|
||||
.type = MODULE_TYPE, \
|
||||
.line = __LINE__, \
|
||||
.file = __FILE__, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 结合类型和名称,精确匹配查找个由 _MODULE_EXPORT 输出的模块对象。
|
||||
*
|
||||
* @param type 由 _MODULE_EXPORT 输出的模块类型
|
||||
* @param name 由 _MODULE_EXPORT 输出的模块名
|
||||
* @return module_t * 由 _MODULE_EXPORT 输出的模块对象
|
||||
*/
|
||||
__static_inline const module_t *sys_module_binding(module_type_t type, const char *name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
extern const module_t __sys_module_leader_0;
|
||||
extern const module_t __sys_module_leader_9;
|
||||
const module_t *module = &__sys_module_leader_0;
|
||||
const module_t *end = &__sys_module_leader_9;
|
||||
while (module < end)
|
||||
{
|
||||
if (module->type == type)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; 1; i++)
|
||||
{
|
||||
if (name[i] != module->name[i])
|
||||
break;
|
||||
if (name[i] == '\0')
|
||||
return module;
|
||||
}
|
||||
}
|
||||
module = &module[1];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 结合类型和名称,查找个由 _MODULE_EXPORT 输出的模块对象名。
|
||||
*
|
||||
* @param type 由 _MODULE_EXPORT 输出的模块类型
|
||||
* @param prefix_name 由 _MODULE_EXPORT 输出的模块名的前缀。例如: prefix_name 为 "UART" ,可能查找到 "UART1", "UART2"...
|
||||
* @param num 匹配到 prefix_name 的第几次时返回,范围 0..n
|
||||
* @return const char * 匹配到的第 num 个名称为 prefix_name.* 的完整对象名,这个对象名可用于 sys_module_binding() 的参数。
|
||||
* @return NULL 表示没对象
|
||||
*/
|
||||
__static_inline const char *sys_module_search(module_type_t type, const char *prefix_name, unsigned int num)
|
||||
{
|
||||
if (prefix_name)
|
||||
{
|
||||
extern const module_t __sys_module_leader_0;
|
||||
extern const module_t __sys_module_leader_9;
|
||||
const module_t *module = &__sys_module_leader_0;
|
||||
const module_t *end = &__sys_module_leader_9;
|
||||
unsigned int match = 0;
|
||||
while (module < end)
|
||||
{
|
||||
if (module->type == type)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; 1; i++)
|
||||
{
|
||||
if (prefix_name[i] == '\0')
|
||||
{
|
||||
if (match < num)
|
||||
{
|
||||
match++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return module->name;
|
||||
}
|
||||
}
|
||||
if (prefix_name[i] != module->name[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
module = &module[1];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取已绑定的对象的关联名
|
||||
*
|
||||
* @param object 由 sys_module_binding() 取得的对象
|
||||
* @return const char * 对象的关联名
|
||||
*/
|
||||
__static_inline const char *sys_module_name(const void *object)
|
||||
{
|
||||
if (object)
|
||||
{
|
||||
extern const module_t __sys_module_leader_0;
|
||||
extern const module_t __sys_module_leader_9;
|
||||
const module_t *module = &__sys_module_leader_0;
|
||||
const module_t *end = &__sys_module_leader_9;
|
||||
while (module < end)
|
||||
{
|
||||
if (module->obj == object)
|
||||
{
|
||||
return module->name;
|
||||
}
|
||||
module = &module[1];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief 绑定一个由 OBJ_EXPORT_DEVICE 输出的设备对象
|
||||
*
|
||||
* @param name 由 OBJ_EXPORT_DEVICE 输出的设备名
|
||||
* @return const void * 由 OBJ_EXPORT_DEVICE 输出的设备对象
|
||||
*/
|
||||
__static_inline const void *device_binding(const char *name)
|
||||
{
|
||||
const module_t *module = sys_module_binding(MODULE_TYPE_DEVICE, name);
|
||||
if (module)
|
||||
return module->obj;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取已绑定的对象的关联名
|
||||
*
|
||||
* @param object 由 device_binding() 取得的对象
|
||||
* @return const char * 对象的关联名
|
||||
*/
|
||||
__static_inline const char *device_name(const void *object)
|
||||
{
|
||||
return sys_module_name(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 查找 device_binding() 可用的模块对象名。
|
||||
*
|
||||
* @param prefix_name 由 _MODULE_EXPORT 输出的模块名的前缀。例如: prefix_name 为 "UART" ,可能查找到 "UART1", "UART2"...
|
||||
* @param num 匹配到 prefix_name 的第几次时返回,范围 0..n
|
||||
* @return const char * 匹配到的第 num 个名称为 prefix_name.* 的完整对象名
|
||||
* @return NULL 表示没对象
|
||||
*/
|
||||
__static_inline const char *device_search(const char *prefix_name, unsigned int num)
|
||||
{
|
||||
return sys_module_search(MODULE_TYPE_DEVICE, prefix_name, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绑定一个由 OBJ_EXPORT_COMPONENT 输出的设备对象
|
||||
*
|
||||
* @param name 由 OBJ_EXPORT_COMPONENT 输出的设备名
|
||||
* @return const void * 由 OBJ_EXPORT_COMPONENT 输出的设备对象
|
||||
*/
|
||||
__static_inline const void *component_binding(const char *name)
|
||||
{
|
||||
const module_t *module = sys_module_binding(MODULE_TYPE_COMPONENT, name);
|
||||
if (module)
|
||||
return module->obj;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 获取已绑定的对象的关联名
|
||||
*
|
||||
* @param object 由 component_binding() 取得的对象
|
||||
* @return const char * 对象的关联名
|
||||
*/
|
||||
__static_inline const char *component_name(const void *object)
|
||||
{
|
||||
return sys_module_name(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 查找 component_binding() 可用的模块对象名。
|
||||
*
|
||||
* @param prefix_name 由 _MODULE_EXPORT 输出的模块名的前缀。例如: prefix_name 为 "UART" ,可能查找到 "UART1", "UART2"...
|
||||
* @param num 匹配到 prefix_name 的第几次时返回,范围 0..n
|
||||
* @return const char * 匹配到的第 num 个名称为 prefix_name.* 的完整对象名
|
||||
* @return NULL 表示没对象
|
||||
*/
|
||||
__static_inline const char *component_search(const char *prefix_name, unsigned int num)
|
||||
{
|
||||
return sys_module_search(MODULE_TYPE_COMPONENT, prefix_name, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif
|
||||
436
components/system/include/sys_log.h
Executable file
436
components/system/include/sys_log.h
Executable file
@@ -0,0 +1,436 @@
|
||||
/**
|
||||
* @file sys_log.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SYS_LOG_H__
|
||||
#define __SYS_LOG_H__
|
||||
|
||||
#include "sys_types.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef SYS_LOG_DOMAIN
|
||||
#define SYS_LOG_DOMAIN "general"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_LEVEL
|
||||
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_INF /* 配置日志打印的等级 */
|
||||
#endif
|
||||
|
||||
#define SYS_LOG_LEVEL_OFF 0
|
||||
#define SYS_LOG_LEVEL_ERR 1
|
||||
#define SYS_LOG_LEVEL_WRN 2
|
||||
#define SYS_LOG_LEVEL_INF 3
|
||||
#define SYS_LOG_LEVEL_DBG 4
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_COLOR_ON
|
||||
#define CONFIG_SYS_LOG_COLOR_ON 1 /* 使能打印颜色 */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_LOCAL_ON
|
||||
#define CONFIG_SYS_LOG_LOCAL_ON 1 /* 强制使能打印所在文件位置 */
|
||||
#endif
|
||||
|
||||
#define SYS_PRINT printf
|
||||
#define SYS_VPRINT vprintf
|
||||
#define SYS_SPRINT sprintf
|
||||
#define SYS_SNPRINT snprintf
|
||||
#define SYS_VSNPRINT vsnprintf
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_CONS_ON
|
||||
#define CONFIG_SYS_LOG_CONS_ON (CONFIG_SYS_LOG_LEVEL > SYS_LOG_LEVEL_OFF) /* 打印控制总开关 */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_DUMP_ON
|
||||
#define CONFIG_SYS_LOG_DUMP_ON CONFIG_SYS_LOG_DBG_ON /* 使能打印二进制和十六进制类型 */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_DBG_ON
|
||||
#define CONFIG_SYS_LOG_DBG_ON (CONFIG_SYS_LOG_LEVEL >= SYS_LOG_LEVEL_DBG) /* 使能打印调试类型*/
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_INF_ON
|
||||
#define CONFIG_SYS_LOG_INF_ON (CONFIG_SYS_LOG_LEVEL >= SYS_LOG_LEVEL_INF) /* 使能打印信息类型 */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_WRN_ON
|
||||
#define CONFIG_SYS_LOG_WRN_ON (CONFIG_SYS_LOG_LEVEL >= SYS_LOG_LEVEL_WRN) /* 使能打印警告类型 */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_ERR_ON
|
||||
#define CONFIG_SYS_LOG_ERR_ON (CONFIG_SYS_LOG_LEVEL >= SYS_LOG_LEVEL_ERR) /* 使能打印错误类型 */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_LOG_ASS_ON
|
||||
#define CONFIG_SYS_LOG_ASS_ON (CONFIG_SYS_LOG_LEVEL >= SYS_LOG_LEVEL_INF) /* 使能有效性检测 */
|
||||
#endif
|
||||
|
||||
#define CONS_PRINT(FMT, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (CONFIG_SYS_LOG_CONS_ON) \
|
||||
{ \
|
||||
SYS_PRINT(FMT, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifndef CONS_ABORT
|
||||
#define CONS_ABORT() \
|
||||
do \
|
||||
{ \
|
||||
volatile int FLAG = 0; \
|
||||
do \
|
||||
{ \
|
||||
} while (FLAG == 0); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if (CONFIG_SYS_LOG_COLOR_ON == 1)
|
||||
#define _COLOR_R "\033[31m" /* 红 RED */
|
||||
#define _COLOR_G "\033[32m" /* 绿 GREEN */
|
||||
#define _COLOR_Y "\033[33m" /* 黄 YELLOW */
|
||||
#define _COLOR_B "\033[34m" /* 蓝 BLUE */
|
||||
#define _COLOR_P "\033[35m" /* 紫 PURPLE */
|
||||
#define _COLOR_C "\033[36m" /* 青 CYAN */
|
||||
#define _COLOR_RY "\033[41;33m" /* 红底黄字 */
|
||||
#define _COLOR_END "\033[0m" /* 结束 */
|
||||
#else
|
||||
#define _COLOR_R "" /* 红 */
|
||||
#define _COLOR_G "" /* 绿 */
|
||||
#define _COLOR_Y "" /* 黄 */
|
||||
#define _COLOR_B "" /* 蓝 */
|
||||
#define _COLOR_P "" /* 紫 */
|
||||
#define _COLOR_C "" /* 青 */
|
||||
#define _COLOR_RY "" /* 红底黄字 */
|
||||
#define _COLOR_END "" /* 结束 */
|
||||
#endif
|
||||
|
||||
#define _DO_SYS_LOG(FLAG, FMT, ARG...) \
|
||||
do \
|
||||
{ \
|
||||
if (FLAG) \
|
||||
{ \
|
||||
CONS_PRINT(FMT, ##ARG); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _FILENAME(FILE) (strrchr(FILE, '/') ? (strrchr(FILE, '/') + 1) : (strrchr(FILE, '\\') ? (strrchr(FILE, '\\') + 1) : FILE))
|
||||
|
||||
#define _GEN_DOMAIN "[" SYS_LOG_DOMAIN "] "
|
||||
|
||||
#define _SYS_LOG(FLAG, INFO, FMT, ...) _DO_SYS_LOG(FLAG, INFO "%s:%u \t%s =>\t" FMT "\r\n", \
|
||||
_FILENAME(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
|
||||
#if (CONFIG_SYS_LOG_LOCAL_ON == 1 || CONFIG_SYS_LOG_DBG_ON == 1)
|
||||
#define _SYS_LOG_COLOR(FLAG, INFO, COLOR, FMT, ...) _DO_SYS_LOG(FLAG, INFO "%s:%u \t%s =>\t" COLOR FMT _COLOR_END "\r\n", \
|
||||
_FILENAME(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define _SYS_LOG_COLOR(FLAG, INFO, COLOR, FMT, ...) _DO_SYS_LOG(FLAG, INFO "%s =>\t" COLOR FMT _COLOR_END "\r\n", \
|
||||
__FUNCTION__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define SYS_LOG_DBG(FMT, ...) _SYS_LOG(CONFIG_SYS_LOG_DBG_ON, "[DBG] " _GEN_DOMAIN, FMT, ##__VA_ARGS__)
|
||||
#define SYS_LOG_INF(FMT, ...) _SYS_LOG_COLOR(CONFIG_SYS_LOG_INF_ON, "[INF] | " _GEN_DOMAIN, _COLOR_G, FMT, ##__VA_ARGS__)
|
||||
#define SYS_LOG_WRN(FMT, ...) _SYS_LOG_COLOR(CONFIG_SYS_LOG_WRN_ON, "[WRN] * " _GEN_DOMAIN, _COLOR_Y, FMT, ##__VA_ARGS__)
|
||||
#define SYS_LOG_ERR(FMT, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (CONFIG_SYS_LOG_ERR_ON) \
|
||||
{ \
|
||||
_SYS_LOG_COLOR(1, "[ERR] - " _GEN_DOMAIN, _COLOR_R, FMT, ##__VA_ARGS__); \
|
||||
CONS_ABORT(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SYS_LOG(FMT, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (CONFIG_SYS_LOG_CONS_ON) \
|
||||
{ \
|
||||
CONS_PRINT(_GEN_DOMAIN "- %s:%u, %s =>\t" _COLOR_B FMT _COLOR_END "\r\n", \
|
||||
_FILENAME(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SYS_ASSERT_FALSE(EXP, FMT, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (CONFIG_SYS_LOG_ASS_ON && (EXP)) \
|
||||
{ \
|
||||
CONS_PRINT("[ASS] # " _GEN_DOMAIN "%s:%u \t%s =>\t" _COLOR_RY "%s" _COLOR_END "; ## " FMT "\r\n", \
|
||||
_FILENAME(__FILE__), __LINE__, __FUNCTION__, #EXP, ##__VA_ARGS__); \
|
||||
CONS_ABORT(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SYS_ASSERT(EXP, FMT, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (CONFIG_SYS_LOG_ASS_ON && !(EXP)) \
|
||||
{ \
|
||||
CONS_PRINT("[ASS] # " _GEN_DOMAIN "%s:%u \t%s =>\t" _COLOR_RY "!(%s)" _COLOR_END "; ## " FMT "\r\n", \
|
||||
_FILENAME(__FILE__), __LINE__, __FUNCTION__, #EXP, ##__VA_ARGS__); \
|
||||
CONS_ABORT(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief Print data in hexadecima
|
||||
*
|
||||
* @param P point to data base
|
||||
* @param SIZE data size (bytes)
|
||||
* @param ALIGN word length, 1, 2, 4, 8
|
||||
* @param ENDIAN 0 -- little-endian, 1 -- big-endian
|
||||
*/
|
||||
#define SYS_LOG_DUMP(P, SIZE, ALIGN, ENDIAN) \
|
||||
do \
|
||||
{ \
|
||||
if (CONFIG_SYS_LOG_CONS_ON && CONFIG_SYS_LOG_DUMP_ON) \
|
||||
{ \
|
||||
_SYS_LOG_COLOR(1, "[HEX]: " _GEN_DOMAIN, _COLOR_C, #P ": %d bytes%s", \
|
||||
SIZE, \
|
||||
ALIGN <= 1 ? "" : ENDIAN ? ", big-endian" \
|
||||
: ", little-endian"); \
|
||||
_sys_log_dump((unsigned)P, P, SIZE, ALIGN, ENDIAN); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief Print data in binary
|
||||
*
|
||||
* @param P point to data base
|
||||
* @param SIZE data size (bytes)
|
||||
* @param ALIGN word length, 1, 2, 4, 8
|
||||
* @param ENDIAN 0 -- little-endian, 1 -- big-endian
|
||||
*/
|
||||
#define SYS_LOG_BIN(P, SIZE, ALIGN, ENDIAN) \
|
||||
do \
|
||||
{ \
|
||||
if (CONFIG_SYS_LOG_CONS_ON && CONFIG_SYS_LOG_DUMP_ON) \
|
||||
{ \
|
||||
_SYS_LOG_COLOR(1, "[BIN]: " _GEN_DOMAIN, _COLOR_C, #P ": %d bytes%s", \
|
||||
SIZE, \
|
||||
ALIGN <= 1 ? "" : ENDIAN ? ", big-endian" \
|
||||
: ", little-endian"); \
|
||||
_sys_log_bin((unsigned)P, P, SIZE, ALIGN, ENDIAN); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
__static_inline void _sys_log_dump(unsigned addr,
|
||||
const void *p,
|
||||
int size,
|
||||
int width,
|
||||
int endian)
|
||||
{
|
||||
#define BYTES_PRE_LINE 16
|
||||
if (size)
|
||||
{
|
||||
int i, ii, j;
|
||||
char buf[4 + 4 * BYTES_PRE_LINE];
|
||||
char *ascii;
|
||||
int len1;
|
||||
int len2;
|
||||
int lenmax;
|
||||
width = (width <= 1 ? 1 : (width <= 2 ? 2 : (width <= 4 ? 4 : 8)));
|
||||
size = (size + width - 1) / width;
|
||||
len1 = (1 + width * 2) * ((BYTES_PRE_LINE + width - 1) / width) - 1;
|
||||
len2 = 3 + (BYTES_PRE_LINE + width - 1) / width * width;
|
||||
lenmax = len1 + len2;
|
||||
ascii = &buf[len1 + 2];
|
||||
for (i = 0; i < 6 + sizeof(void *) * 2; i++)
|
||||
{
|
||||
SYS_PRINT("-");
|
||||
}
|
||||
for (i = 0; i < lenmax; i++)
|
||||
{
|
||||
buf[i] = '-';
|
||||
}
|
||||
buf[i] = '\0';
|
||||
SYS_PRINT("%s\r\n", buf);
|
||||
ii = (BYTES_PRE_LINE + width - 1) / width;
|
||||
while (size)
|
||||
{
|
||||
int index1 = 0;
|
||||
int index2 = 0;
|
||||
SYS_PRINT(_COLOR_Y "[" _COLOR_END "0x%08X" _COLOR_Y "]" _COLOR_END ": ", (unsigned)addr);
|
||||
for (i = 0; i < ii;)
|
||||
{
|
||||
for (j = 0; j < width; j++)
|
||||
{
|
||||
if (endian)
|
||||
{
|
||||
index1 += SYS_SPRINT(&buf[index1], "%02x", ((uint8_t *)p)[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
index1 += SYS_SPRINT(&buf[index1], "%02x", ((uint8_t *)p)[width - j - 1]);
|
||||
}
|
||||
if (((uint8_t *)p)[j] >= ' ' && ((uint8_t *)p)[j] < 0x7f)
|
||||
{
|
||||
index2 += SYS_SPRINT(&ascii[index2], "%c", ((uint8_t *)p)[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
index2 += SYS_SPRINT(&ascii[index2], ".");
|
||||
}
|
||||
}
|
||||
addr += width;
|
||||
p = &((uint8_t *)p)[width];
|
||||
if (--size > 0 && ++i < ii)
|
||||
{
|
||||
index1 += SYS_SPRINT(&buf[index1], " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
while (index1 < len1)
|
||||
{
|
||||
buf[index1++] = ' ';
|
||||
}
|
||||
buf[index1++] = ' ';
|
||||
buf[index1++] = '|';
|
||||
index1 += index2;
|
||||
while (index1 < lenmax - 1)
|
||||
{
|
||||
buf[index1++] = ' ';
|
||||
}
|
||||
buf[index1++] = '\0';
|
||||
SYS_PRINT("%s|\r\n", buf);
|
||||
}
|
||||
if (size == 0)
|
||||
{
|
||||
for (i = 0; i < 6 + sizeof(void *) * 2; i++)
|
||||
{
|
||||
SYS_PRINT("=");
|
||||
}
|
||||
for (i = 0; i < lenmax; i++)
|
||||
{
|
||||
buf[i] = '=';
|
||||
}
|
||||
buf[i] = '\0';
|
||||
SYS_PRINT("%s\r\n", buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef BYTES_PRE_LINE
|
||||
}
|
||||
|
||||
__static_inline void _sys_log_bin(unsigned addr,
|
||||
const void *p,
|
||||
int size,
|
||||
int width,
|
||||
int endian)
|
||||
{
|
||||
#define BITS_PRE_LINE 64
|
||||
if (size)
|
||||
{
|
||||
uint8_t value[8];
|
||||
int i, j;
|
||||
int lenmax;
|
||||
width = (width <= 1 ? 1 : (width <= 2 ? 2 : (width <= 4 ? 4 : 8)));
|
||||
width = width < BITS_PRE_LINE ? width : BITS_PRE_LINE;
|
||||
size = (size + width - 1) / width * width;
|
||||
lenmax = (1 + 3 * 8) * width;
|
||||
for (i = 0; i < 9 + sizeof(void *) * 2 + width * 2 + width * 8 / 4 + lenmax; i++)
|
||||
{
|
||||
SYS_PRINT("-");
|
||||
}
|
||||
SYS_PRINT("\r\n");
|
||||
for (i = 0; i < 8 + sizeof(void *) * 2 + width * 2; i++)
|
||||
{
|
||||
SYS_PRINT(" ");
|
||||
}
|
||||
for (i = 0; i < 8 * width; i++)
|
||||
{
|
||||
if (i % 4 == 0)
|
||||
{
|
||||
if (i % 8 == 0)
|
||||
{
|
||||
SYS_PRINT(" ");
|
||||
}
|
||||
SYS_PRINT(" ");
|
||||
}
|
||||
SYS_PRINT("%3d", 8 * width - 1 - i);
|
||||
}
|
||||
SYS_PRINT("\r\n");
|
||||
for (i = 0; i < 9 + sizeof(void *) * 2 + width * 2 + width * 8 / 4 + lenmax; i++)
|
||||
{
|
||||
SYS_PRINT("~");
|
||||
}
|
||||
SYS_PRINT("\r\n");
|
||||
while (size)
|
||||
{
|
||||
SYS_PRINT(_COLOR_Y "[" _COLOR_END "0x%08X" _COLOR_Y "]" _COLOR_END ": 0x", (unsigned)addr);
|
||||
if (endian)
|
||||
{
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
value[i] = ((uint8_t *)p)[i];
|
||||
SYS_PRINT("%02X", value[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
value[i] = ((uint8_t *)p)[width - 1 - i];
|
||||
SYS_PRINT("%02X", value[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (j % 4 == 0)
|
||||
{
|
||||
SYS_PRINT(" ");
|
||||
if (j % 8 == 0)
|
||||
{
|
||||
SYS_PRINT(" ");
|
||||
}
|
||||
}
|
||||
if (value[i] >> (7 - j) & 1)
|
||||
{
|
||||
SYS_PRINT(" 1");
|
||||
}
|
||||
else
|
||||
{
|
||||
SYS_PRINT(" 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
SYS_PRINT("\n");
|
||||
addr += width;
|
||||
p = &((uint8_t *)p)[width];
|
||||
size -= width;
|
||||
if (size == 0)
|
||||
{
|
||||
for (i = 0; i < 9 + sizeof(void *) * 2 + width * 2 + width * 8 / 4 + lenmax; i++)
|
||||
{
|
||||
SYS_PRINT("=");
|
||||
}
|
||||
SYS_PRINT("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef BITS_PRE_LINE
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
301
components/system/include/sys_types.h
Executable file
301
components/system/include/sys_types.h
Executable file
@@ -0,0 +1,301 @@
|
||||
/**
|
||||
* @file sys_types.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-05-01
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SYS_TYPES_H__
|
||||
#define __SYS_TYPES_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
#ifndef __static_inline
|
||||
#define __static_inline static __inline
|
||||
#endif
|
||||
|
||||
#ifndef __section
|
||||
#define __section(X) __attribute__((section(X)))
|
||||
#endif
|
||||
|
||||
#ifndef __used
|
||||
#define __used __attribute__((used))
|
||||
#endif
|
||||
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif
|
||||
|
||||
#ifndef __naked
|
||||
#define __naked __attribute__((naked))
|
||||
#endif
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#ifndef __aligned
|
||||
#define __aligned(X) __attribute__((aligned(X)))
|
||||
#endif
|
||||
|
||||
#ifndef __likely
|
||||
#define __likely(X) __builtin_expect(!!(X), 1)
|
||||
#endif
|
||||
|
||||
#ifndef __unlikely
|
||||
#define __unlikely(X) __builtin_expect(!!(X), 0)
|
||||
#endif
|
||||
|
||||
#ifndef FALLTHROUGH
|
||||
#define FALLTHROUGH
|
||||
#endif
|
||||
|
||||
#ifndef __nop
|
||||
#define __nop() do { __asm { nop; } } while (0)
|
||||
#endif
|
||||
|
||||
#ifndef __no_optimize
|
||||
#define __no_optimize
|
||||
#endif
|
||||
|
||||
#ifndef __clz
|
||||
#define __clz(VAL) __builtin_clz(VAL);
|
||||
#endif
|
||||
|
||||
#ifndef __typeof
|
||||
#define __typeof(VAR) __typeof__((VAR))
|
||||
#endif
|
||||
|
||||
#ifndef __optimize
|
||||
#define __optimize(X) __attribute__((optimize("O"#X)))
|
||||
#endif
|
||||
|
||||
#elif defined(__GNUC__) /* #if defined(__CC_ARM) */
|
||||
|
||||
#ifndef __static_inline
|
||||
#define __static_inline static inline
|
||||
#endif
|
||||
|
||||
#ifndef __section
|
||||
#define __section(X) __attribute__((section(X)))
|
||||
#endif
|
||||
|
||||
#ifndef __used
|
||||
#define __used __attribute__((used))
|
||||
#endif
|
||||
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif
|
||||
|
||||
#ifndef __naked
|
||||
#define __naked __attribute__((naked))
|
||||
#endif
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#ifndef __aligned
|
||||
#define __aligned(X) __attribute__((__aligned__(X)))
|
||||
#endif
|
||||
|
||||
#ifndef __likely
|
||||
#define __likely(X) __builtin_expect(!!(X), 1)
|
||||
#endif
|
||||
|
||||
#ifndef __unlikely
|
||||
#define __unlikely(X) __builtin_expect(!!(X), 0)
|
||||
#endif
|
||||
|
||||
#ifndef FALLTHROUGH
|
||||
#define FALLTHROUGH __attribute__((fallthrough))
|
||||
#endif
|
||||
|
||||
#ifndef __nop
|
||||
#define __nop() __asm volatile("nop")
|
||||
#endif
|
||||
|
||||
#ifndef __no_optimize
|
||||
#define __no_optimize __attribute__((optimize("O0")))
|
||||
#endif
|
||||
|
||||
#ifndef __clz
|
||||
#define __clz(VAL) ((VAL) == 0 ? 32 : __builtin_clz(VAL))
|
||||
#endif
|
||||
|
||||
#ifndef __typeof
|
||||
#define __typeof(VAR) __typeof__((VAR))
|
||||
#endif
|
||||
|
||||
#ifndef __optimize
|
||||
#define __optimize(X) __attribute__((optimize("O"#X)))
|
||||
#endif
|
||||
|
||||
#else /* #elif defined(__GNUC__) */
|
||||
|
||||
#define __static_inline static inline
|
||||
|
||||
#define __no_init
|
||||
|
||||
#define __nop() __nop
|
||||
|
||||
#define __no_optimize
|
||||
|
||||
#define __clz(VAL) __builtin_clz(VAL);
|
||||
|
||||
#endif /* #elif defined(__GNUC__) */
|
||||
|
||||
#ifndef __ARRAY_SIZE
|
||||
#define __ARRAY_SIZE(ARRAY) (sizeof(ARRAY) / sizeof((ARRAY)[0]))
|
||||
#endif
|
||||
|
||||
#ifndef __no_init
|
||||
#define __no_init __section(".noinitialized")
|
||||
#endif
|
||||
|
||||
#ifndef __ram_text
|
||||
#define __ram_text __section(".ram_text")
|
||||
#endif
|
||||
|
||||
#ifndef __IM
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#endif
|
||||
#ifndef __OM
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#endif
|
||||
#ifndef __IOM
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
#endif
|
||||
|
||||
#ifndef sys_le16_to_cpu
|
||||
#define _b_swap_16(X) ((u16_t)((((X) >> 8) & 0xff) | (((X)&0xff) << 8)))
|
||||
|
||||
#define _b_swap_32(X) ((u32_t)((((X) >> 24) & 0xff) | \
|
||||
(((X) >> 8) & 0xff00) | \
|
||||
(((X)&0xff00) << 8) | \
|
||||
(((X)&0xff) << 24)))
|
||||
|
||||
#define _b_swap_64(X) ((u64_t)((((X) >> 56) & 0xff) | \
|
||||
(((X) >> 40) & 0xff00) | \
|
||||
(((X) >> 24) & 0xff0000) | \
|
||||
(((X) >> 8) & 0xff000000) | \
|
||||
(((X)&0xff000000) << 8) | \
|
||||
(((X)&0xff0000) << 24) | \
|
||||
(((X)&0xff00) << 40) | \
|
||||
(((X)&0xff) << 56)))
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define sys_le16_to_cpu(VAL) (VAL)
|
||||
#define sys_le32_to_cpu(VAL) (VAL)
|
||||
#define sys_le64_to_cpu(VAL) (VAL)
|
||||
#define sys_cpu_to_le16(VAL) (VAL)
|
||||
#define sys_cpu_to_le32(VAL) (VAL)
|
||||
#define sys_cpu_to_le64(VAL) (VAL)
|
||||
#define sys_be16_to_cpu(VAL) _b_swap_16(VAL)
|
||||
#define sys_be32_to_cpu(VAL) _b_swap_32(VAL)
|
||||
#define sys_be64_to_cpu(VAL) _b_swap_64(VAL)
|
||||
#define sys_cpu_to_be16(VAL) _b_swap_16(VAL)
|
||||
#define sys_cpu_to_be32(VAL) _b_swap_32(VAL)
|
||||
#define sys_cpu_to_be64(VAL) _b_swap_64(VAL)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define sys_le16_to_cpu(VAL) _b_swap_16(VAL)
|
||||
#define sys_le32_to_cpu(VAL) _b_swap_32(VAL)
|
||||
#define sys_le64_to_cpu(VAL) _b_swap_64(VAL)
|
||||
#define sys_cpu_to_le16(VAL) _b_swap_16(VAL)
|
||||
#define sys_cpu_to_le32(VAL) _b_swap_32(VAL)
|
||||
#define sys_cpu_to_le64(VAL) _b_swap_64(VAL)
|
||||
#define sys_be16_to_cpu(VAL) (VAL)
|
||||
#define sys_be32_to_cpu(VAL) (VAL)
|
||||
#define sys_be64_to_cpu(VAL) (VAL)
|
||||
#define sys_cpu_to_be16(VAL) (VAL)
|
||||
#define sys_cpu_to_be32(VAL) (VAL)
|
||||
#define sys_cpu_to_be64(VAL) (VAL)
|
||||
#else
|
||||
#error "Unknown byte order"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef uint8_t u8_t ;
|
||||
typedef uint16_t u16_t ;
|
||||
typedef uint32_t u32_t ;
|
||||
typedef int8_t s8_t ;
|
||||
typedef int16_t s16_t ;
|
||||
typedef int32_t s32_t ;
|
||||
typedef int64_t s64_t ;
|
||||
typedef volatile uint8_t vu8_t ;
|
||||
typedef volatile uint16_t vu16_t ;
|
||||
typedef volatile uint32_t vu32_t ;
|
||||
typedef volatile uint64_t vu64_t ;
|
||||
typedef volatile int8_t vs8_t ;
|
||||
typedef volatile int16_t vs16_t ;
|
||||
typedef volatile int32_t vs32_t ;
|
||||
typedef volatile int64_t vs64_t ;
|
||||
typedef volatile signed vint ;
|
||||
typedef unsigned uint ;
|
||||
typedef volatile unsigned vuint ;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPES_NO_ERR = 0,
|
||||
TYPES_TIMEOUT,
|
||||
TYPES_NO_MEM,
|
||||
TYPES_HAL_ERR,
|
||||
TYPES_ERROR = -1,
|
||||
} types_err_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPES_RESET = 0,
|
||||
TYPES_SET = 1,
|
||||
} types_flag_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPES_DISABLE = 0,
|
||||
TYPES_ENABLE = 1,
|
||||
} types_ctrl_t;
|
||||
|
||||
#ifndef __WRITEBITS
|
||||
#define __WRITEBITS(P, INDEX, WIDE, VALUE) (*(vuint *)(P) = (*(vuint *)(P) & ~(~(-1u << (WIDE)) << (INDEX))) ^ (((VALUE) & ~(-1u << (WIDE))) << (INDEX)))
|
||||
#endif
|
||||
|
||||
#ifndef __READBITS
|
||||
#define __READBITS(VAR, INDEX, WIDE) (((VAR) >> (INDEX)) & ~(-1u << (WIDE)))
|
||||
#endif
|
||||
|
||||
__static_inline void writebits(volatile void *dest, u8_t index, u8_t bitwide, uint value)
|
||||
{
|
||||
while(index + bitwide > sizeof(vuint) * 8);
|
||||
while(value >= 1 << bitwide);
|
||||
__WRITEBITS(dest, index, bitwide, value);
|
||||
}
|
||||
|
||||
__static_inline uint readbits(uint var, u8_t index, u8_t bitwide)
|
||||
{
|
||||
return __READBITS(var, index, bitwide);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user