1、概述

弯弯绕绕的宏定义一一把它理清楚。

2、通用设备宏定义

2.1 UART0设备定义:

UART_ACTS_DEVICE_INIT(0)

#define UART_ACTS_DEVICE_INIT(idx)                      {

    PINCTRL_DT_DEFINE(UARTNODE(idx)); //UART设备引脚管理                      

    UART_ACTS_DEFINE_CONFIG(idx);//UART设备软件配置

    static struct acts_uart_data uart_acts_dev_data_##idx ;//UART设备数据结构

    DEVICE_DT_DEFINE(UARTNODE(idx),        //通用设备结构定义

              &uart_acts_init,//初始入口

              NULL,                

              &uart_acts_dev_data_##idx,                       

              &uart_acts_config_##idx,                     

              PRE_KERNEL_1,                        

              CONFIG_SERIAL_INIT_PRIORITY,                 

              &uart_acts_driver_api);

2.2 重点追踪

...\outdir\ats3239_dvb_ext_nor\zephyr\include\generated\zephyr\devicetree_generated.h —— 由python生成。目的是将设备字符串替换为序号。
#define DT_N_NODELABEL_uart0            DT_N_S_soc_S_uart_40038000
#define DT_N_S_soc_S_uart_40038000_ORD 129

node_id = UARTNODE(0) = DT_N_NODELABEL_uart0;

dev_id = Z_DEVICE_DT_DEV_ID(node_id) = (dts_ord_ + (DT_N_NODELABEL_uart0 + _ORD)) = dts_ord_129;

node_id,dev_id竟然都是一个字符串。

varname = DEVICE_NAME_GET(dev_id) = __device_dts_ord_129

__in_section(_##secname, static, _CONCAT(section_postfix, _)) = ._device.static.1_3_

secname = COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)) = device;

        #define CONFIG_SERIAL_INIT_PRIORITY 3

        #define Z_INIT_ORD_PRE_KERNEL_1 1

        prio = CONFIG_SERIAL_INIT_PRIORITY = 3

        level = PRE_KERNEL_1

section_postfix = Z_DEVICE_SECTION_NAME(level, prio) = _CONCAT(INIT_LEVEL_ORD(level), _##prio) = Z_INIT_ORD_PRE_KERNEL_1 + _ + CONFIG_SERIAL_INIT_PRIORITY = 1_3

定义输出函数:

.text.uart0_acts_irq_config:static void uart0_acts_irq_config(const struct device *port)

定义输出变量:

.rodata.uart_acts_config_0:static const struct acts_uart_config uart_acts_config_0;

.rodata.__pinctrl_dev_config__device_dts_ord_129:

.rodata.__pinctrl_states__device_dts_ord_129:

._device.static.1_3_:struct  device __device_dts_ord_129;

#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, ...)
 
	/*step1:struct device_state 类型变量定义。*/
	Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id));                    \

	/*step2:核心定义*/
	Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id),                  \
			DEVICE_DT_NAME(node_id), init_fn, pm, data, config,    \
			level, prio, api,                                      \
			&Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)),     \
			__VA_ARGS__)

//追踪
#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
#define DT_DEP_ORD(node_id) DT_CAT(node_id, _ORD)
#define DT_CAT(a1, a2) a1 ## a2

#define DEVICE_DT_NAME(node_id)  DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
#define DT_PROP_OR(node_id, prop, default_value) \
	COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
		    (DT_PROP(node_id, prop)), (default_value))
#define DT_NODE_FULL_NAME(node_id) DT_CAT(node_id, _FULL_NAME)

#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
#define _CONCAT(x, y) _DO_CONCAT(x, y)
#define _DO_CONCAT(x, y) x ## y
//step1.:struct device_state 类型变量定义。
#define Z_DEVICE_STATE_DEFINE(dev_id)                                          \

	/*step1.1:定义对齐方式,struct device_state类型变量名定义但没有赋值*/
	static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id)   \

	/*step1.2:指定变量的段*/
		__attribute__((__section__(".z_devstate")))


//step1.:追踪
#define Z_DECL_ALIGN(type) __aligned(__alignof(type)) type

#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
#define _CONCAT(x, y) _DO_CONCAT(x, y)
#define _DO_CONCAT(x, y) x ## y
//step2.:
#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, level, prio, api, state, ...)                           \

	/*step2.1:编译时检查设备名称长度是否合法*/
    Z_DEVICE_NAME_CHECK(name);                                              \
                                                                                \
	/*step2.2:*/
	IF_ENABLED(CONFIG_DEVICE_DEPS,                                          \
		   (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);))       \
                                                                                \
	/*step2.3:*/
	IF_ENABLED(CONFIG_DEVICE_DT_METADATA,                                   \
		   (IF_ENABLED(DT_NODE_EXISTS(node_id),                         \
			      (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\
                                                                                \
	/*step2.4:struct device 类型变量定义*/
	Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level,    \
		prio, api, state, Z_DEVICE_DEPS_NAME(dev_id));                   \

	/*step2.5:struct init_entry 类型变量定义,初始入口*/
	COND_CODE_1(DEVICE_DT_DEFER(node_id),                                   \
		    (Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id,          \
						      init_fn)),                \
		    (Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn,       \
						level, prio)));
//step2.1.:编译时检查设备名称长度
#define Z_DEVICE_NAME_CHECK(name)                                              \
	BUILD_ASSERT(sizeof(Z_STRINGIFY(name)) <= Z_DEVICE_MAX_NAME_LEN,       \
			    Z_STRINGIFY(DEVICE_NAME_GET(name)) " too long")


//step2.4.:struct device 类型变量定义
#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, deps)                                                    \

	/*step2.4.1*/
	COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static))

	/*step2.4.2*/
	COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const))

	/*step2.4.3*/
	STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE
    (
		device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)),    

		Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)
    ) = 

		Z_DEVICE_INIT(name, pm, data, config, api, state, deps, node_id, dev_id)


//step2.4.:追踪
#define Z_DEVICE_SECTION_NAME(level, prio)  _CONCAT(INIT_LEVEL_ORD(level), _##prio)
#define INIT_LEVEL_ORD(level)                                                  \
	COND_CODE_1(Z_INIT_EARLY_##level, (Z_INIT_ORD_EARLY),                  \
	(COND_CODE_1(Z_INIT_PRE_KERNEL_1_##level, (Z_INIT_ORD_PRE_KERNEL_1),   \
	(COND_CODE_1(Z_INIT_PRE_KERNEL_2_##level, (Z_INIT_ORD_PRE_KERNEL_2),   \
	(COND_CODE_1(Z_INIT_POST_KERNEL_##level, (Z_INIT_ORD_POST_KERNEL),     \
	(COND_CODE_1(Z_INIT_APPLICATION_##level, (Z_INIT_ORD_APPLICATION),     \
	(COND_CODE_1(Z_INIT_SMP_##level, (Z_INIT_ORD_SMP),                     \
	(ZERO_OR_COMPILE_ERROR(0)))))))))))))

#define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
#define _CONCAT(x, y) _DO_CONCAT(x, y)
#define _DO_CONCAT(x, y) x ## y

//step2.4.3.:段详解
#define STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(struct_type, secname, name, varname) \
	TYPE_SECTION_ITERABLE(struct struct_type, varname, secname, name)

#define TYPE_SECTION_ITERABLE(type, varname, secname, section_postfix) \
	Z_DECL_ALIGN(type) varname \
	__in_section(_##secname, static, _CONCAT(section_postfix, _)) __used __noasan

//step2.4.3.:追踪
#define Z_DECL_ALIGN(type) __aligned(__alignof(type)) type

#define __in_section(a, b, c) ___in_section(a, b, c)

#define ___in_section(a, b, c) \
	__attribute__((section("." Z_STRINGIFY(a)			\
				"." Z_STRINGIFY(b)			\
				"." Z_STRINGIFY(c))))

#define STRINGIFY(s) Z_STRINGIFY(s)
#define Z_STRINGIFY(x) #x

#define _CONCAT(x, y) _DO_CONCAT(x, y)
#define _DO_CONCAT(x, y) x ## y
//step2.5.:struct init_entry 类型变量定义
	COND_CODE_1(DEVICE_DT_DEFER(node_id),                                   \
		    (Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id,          \
						      init_fn)),                \
		    (Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn,       \
						level, prio)));

//step2.5.:追踪
#define COND_CODE_1(_flag, _if_1_code, _else_code) \
	Z_COND_CODE_1(_flag, _if_1_code, _else_code)

#define _XXXX1 _YYYY,
#define Z_COND_CODE_1(_flag, _if_1_code, _else_code) \
	__COND_CODE(_XXXX##_flag, _if_1_code, _else_code)
#define __COND_CODE(one_or_two_args, _if_code, _else_code) \                                                 
    __GET_ARG2_DEBRACKET(one_or_two_args _if_code, _else_code)

#define __GET_ARG2_DEBRACKET(ignore_this, val, ...) __DEBRACKET val
#define __DEBRACKET(...) __VA_ARGS__

3、log&print宏定义

#define Z_LOG(_level, ...) \

    Z_LOG2(_level, 0, __log_current_const_data, __log_current_dynamic_data, __VA_ARGS__)

void os_printk(const char *fmt, ...)

{

    va_list ap;

    va_start(ap, fmt);

    if (IS_ENABLED(CONFIG_LOG_PRINTK)) {        //log_printk(fmt, ap);         }

   else {        vprintk(fmt, ap);        }

    va_end(ap);

}

void printk(const char *fmt, ...)

{

    va_list ap;

    va_start(ap, fmt);

    vprintk(fmt, ap);

    va_end(ap);

}

#ifdef CONFIG_PRINTK
void vprintk(const char *fmt, va_list args)
{
	printk_ctx_t *pctx = &g_pr_ctx;
	struct buf_out_ctx ctx_buf;
	
	if(!pctx->init){
		__vprintk(fmt, args);
		return ;
	}
	
	if(pctx->panic){
		dma_send_sync(pctx);
		k_busy_wait(100000); //wait fifo send finshed
		uart_dma_switch(pctx, 0); // CPU
		pctx->init = FALSE;
		__vprintk(fmt, args);
		return;
	}

	#ifdef CONFIG_PRINTK_TIME_FREFIX
	if ((pctx->isprint_time) && (pctx->last_char == '\0' ||
		pctx->last_char == '\n')) {
		ctx_buf.count = get_time_prefix(ctx_buf.buf);
	} else {
		ctx_buf.count = 0;
	}
	#else
	ctx_buf.count = 0;
	#endif
	
	cbvprintf(buf_char_out, &ctx_buf, fmt, args);
 	ctx_buf_flush(&ctx_buf);
	dma_start_tx(pctx);
}
#endif
int uart_dma_send_buf_prepare(const uint8_t *buf, int len)//打印预处理
{
	printk_ctx_t *pctx = &g_pr_ctx;
	int ret;

	if(!pctx->init){
		k_str_out((char *)buf, len);
		return len;
	}

	ret = cbuf_output(buf ,len, pctx);//核心函数:将数据写入到发送缓冲区
	return ret;
}

void uart_dma_send_buf_prepare_over(void)//启动DMA打印
{
     dma_start_tx(&g_pr_ctx);
}

4、shell宏定义

待续……

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐