编译控制的Json文件
业务gn文件,这里以my_led目录下的为例
- 编译后生的libmyled.a
模块gn文件,这里选择 "my_led:myled"模块参与编译
# Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http:
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
#"A1_kernal_thread:thread_example",
#"A2_kernel_timer:timer_example",
#"A3_kernel_event:event_example",
#"A4_kernel_mutex:mutex_example",
#"A5_kernel_semaphore:semaphore_example",
#"A6_kernel_message:message_example",
#"B1_basic_led_blink:led_example",
#"B2_basic_button:button_example",
#"B3_basic_pwm_led:pwm_example",
#"B4_basic_adc:adc_example",
#"B5_basic_i2c_nfc:i2c_example",
#"B6_basic_uart:uart_example",
#"C1_e53_sf1_mq2:e53_sf1_example",
#"C2_e53_ia1_temp_humi_pls:e53_ia1_example",
#"C3_e53_sc1_pls:e53_sc1_example",
#"C4_e53_sc2_axis:e53_sc2_example",
#"C5_e53_is1_infrared:e53_is1_example",
#"D1_iot_wifi_ap:wifi_ap",
#"D2_iot_wifi_sta_connect:wifi_sta_connect",
#"D3_iot_udp_client:udp_client",
#"D4_iot_tcp_server:tcp_server",
#"D5_iot_mqtt:iot_mqtt",
#"D6_iot_cloud_oc:oc_mqtt",
#"D7_iot_cloud_onenet:onenet_mqtt",
#"D8_iot_cloud_oc_smoke:cloud_oc_smoke",
#"D9_iot_cloud_oc_light:cloud_oc_light",
#"D10_iot_cloud_oc_manhole_cover:cloud_oc_manhole_cover",
#"D11_iot_cloud_oc_infrared:cloud_oc_infrared",
#"D12_iot_cloud_oc_agriculture:cloud_oc_agriculture",
#"D13_iot_cloud_oc_gps:cloud_oc_gps",
"my_led:myled",
]
}
注册入口函数
void my_led_example(void)
{
static uint8_t cnt;
cnt++;
printf("-------> my_led_example %d",cnt);
usleep(1000000);
}
SYS_RUN(my_led_example);
- 使用SYS_RUN宏关联入口函数,SYS_RUN宏原型如下:
#define SYS_RUN(func) LAYER_INITCALL_DEF(func, run, "run")
#define LAYER_INITCALL_DEF(func, layer, clayer) \
LAYER_INITCALL(func, layer, clayer, 2)
#define LAYER_INITCALL(func, layer, clayer, priority) \
static const InitCall USED_ATTR __zinitcall_##layer##_##func \
__attribute__((section(".zinitcall." clayer #priority ".init"))) = func
typedef void (*InitCall)(void);
#define USED_ATTR __attribute__((used))
-
SYS_RUN(my_led_example)展开分析: -
LAYER_INITCALL_DEF(my_led_example, run, “run”) -
LAYER_INITCALL(my_led_example, run, “run”, 2) -
static const InitCall USED_ATTR __zinitcall_run_my_led_example attribute((section(“.zinitcall.run2.init”))) = my_led_example 这样函数指针_zinitcall_run_my_led_example指向了my_led_example,并编译到.zinitcall.run2.init段当中。
HOS_SystemInit中调用MODULE_INIT(run)来调用注册的入口函数my_led_example
void HOS_SystemInit(void)
{
MODULE_INIT(bsp);
MODULE_INIT(device);
MODULE_INIT(core);
SYS_INIT(service);
SYS_INIT(feature);
MODULE_INIT(run);
SAMGR_Bootstrap();
}
#define MODULE_INIT(name) \
do { \
MODULE_CALL(name, 0); \
} while (0)
#define MODULE_CALL(name, step) \
do { \
InitCall *initcall = (InitCall *)(MODULE_BEGIN(name, step)); \
InitCall *initend = (InitCall *)(MODULE_END(name, step)); \
for (; initcall < initend; initcall++) { \
(*initcall)(); \
} \
} while (0)
#define MODULE_BEGIN(name, step) __section_begin(MODULE_NAME(name, step))
#define MODULE_END(name, step) __section_end(MODULE_NAME(name, step))
do { \
MODULE_CALL(run, 0); \
} while (0)
do { \
InitCall *initcall = (InitCall *)(MODULE_BEGIN(run, 0)); \
InitCall *initend = (InitCall *)(MODULE_END(run, 0)); \
for (; initcall < initend; initcall++) { \
(*initcall)(); \
} \
} while (0)
__section_begin(MODULE_NAME(run, 0))
#define MODULE_NAME(name, step) ".zinitcall." #name #step ".init"
- 最后展开MODULE_BEGIN(run, 0)如下
__section_begin(".zinitcall.run0.init"))
__section_end(".zinitcall.run0.init")
- 通过函数指针遍历指定段保存的函数指针进行调用 (*initcall)();
do { \
InitCall *initcall = (InitCall *)__section_begin(".zinitcall.run0.init")); \
InitCall *initend = (InitCall *)__section_end(".zinitcall.run0.init"); \
for (; initcall < initend; initcall++) { \
(*initcall)(); \
} \
} while (0)
编译烧录,运行结果如下
通过宏生成的函数指针变量名进行调用,测试函数如下
void test(void)
{
__zinitcall_run_my_led_example();
}
- 在HOS_SystemInit函数中调用test函数
void HOS_SystemInit(void)
{
MODULE_INIT(bsp);
MODULE_INIT(device);
MODULE_INIT(core);
SYS_INIT(service);
SYS_INIT(feature);
MODULE_INIT(run);
test();
SAMGR_Bootstrap();
}
- 编译烧录,运行结果如下
|