IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【SemiDrive源码分析】【X9芯片启动流程】26 - R5 SafetyOS 之 LK_INIT_LEVEL_TARGET 阶段代码流程分析(TP Drvier、Audio Server初始化) -> 正文阅读

[嵌入式]【SemiDrive源码分析】【X9芯片启动流程】26 - R5 SafetyOS 之 LK_INIT_LEVEL_TARGET 阶段代码流程分析(TP Drvier、Audio Server初始化)


本 SemiDrive源码分析 之 Yocto源码分析 系列文章汇总如下:

  1. 【SemiDrive源码分析】【Yocto源码分析】01 - yocto/base目录源码分析(编译环境初始化流程)
  2. 【SemiDrive源码分析】【Yocto源码分析】02 - yocto/meta-openembedded目录源码分析
  3. 【SemiDrive源码分析】【Yocto源码分析】03 - yocto/meta-semidrive目录及Yocto Kernel编译过程分析(上)
  4. 【SemiDrive源码分析】【Yocto源码分析】04 - yocto/meta-semidrive目录及Yocto Kernel编译过程分析(下)
  5. 【SemiDrive源码分析】【Yocto源码分析】05 - 找一找Yocto Kernel编译过程中所有Task的源码在哪定义的呢?
  6. 【SemiDrive源码分析】【Yocto源码分析】06 - Kernel编译生成的Image.bin、Image_nobt.dtb、modules.tgz 这三个文件分别是如何生成的?
  7. 【SemiDrive源码分析】【Yocto源码分析】07 - core-image-base-x9h_ref_serdes.rootfs.ext4 文件系统是如何生成的
  8. 【SemiDrive源码分析】【X9芯片启动流程】08 - X9平台 lk 目录源码分析 之 目录介绍
  9. 【SemiDrive源码分析】【X9芯片启动流程】09 - X9平台系统启动流程分析
  10. 【SemiDrive源码分析】【X9芯片启动流程】10 - BareMetal_Suite目录R5 DIL.bin 引导程序源代码分析
  11. 【SemiDrive源码分析】【X9芯片启动流程】11 - freertos_safetyos目录Cortex-R5 DIL2.bin 引导程序源代码分析
  12. 【SemiDrive源码分析】【X9芯片启动流程】12 - freertos_safetyos目录Cortex-R5 DIL2.bin 之 sdm_display_init 显示初始化源码分析
  13. 【SemiDrive源码分析】【X9芯片驱动调试】13 - GPIO 配置方法
  14. 【SemiDrive源码分析】【X9芯片启动流程】14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析
  15. 【SemiDrive源码分析】【X9芯片启动流程】15 - freertos_safetyos目录 R5 SafetyOS 之 tcpip_init() 代码流程分析
  16. 【SemiDrive源码分析】【X9 Audio音频模块分析】16 - 音频模块框图及硬件原理图分析
  17. 【SemiDrive源码分析】【X9芯片启动流程】17 - R5 SafetyOS 之 LK_INIT_LEVEL_PLATFORM 阶段代码流程分析(上)dcf_init 核间通信初始化
  18. 【SemiDrive源码分析】【X9芯片启动流程】18 - R5 SafetyOS 之 LK_INIT_LEVEL_PLATFORM 阶段代码流程(下)启动QNX、Android
  19. 【SemiDrive源码分析】【X9芯片启动流程】19 - MailBox 核间通信机制介绍(理论篇)
  20. 【SemiDrive源码分析】【X9芯片启动流程】20 - MailBox 核间通信机制介绍(代码分析篇)之 MailBox for RTOS 篇
  21. 【SemiDrive源码分析】【X9芯片启动流程】21 - MailBox 核间通信机制介绍(代码分析篇)之 Mailbox for Linux 篇
  22. 【SemiDrive源码分析】【X9芯片启动流程】22 - MailBox 核间通信机制介绍(代码分析篇)之 RPMSG-VIRTIO Kernel 篇
  23. 【SemiDrive源码分析】【X9芯片启动流程】23 - MailBox 核间通信机制介绍(代码分析篇)之 RPMSG-IPCC Kernel 篇
  24. 【SemiDrive源码分析】【X9芯片启动流程】24 - MailBox 核间通信机制相关寄存器介绍
  25. 【SemiDrive源码分析】【X9芯片启动流程】25 - MailBox 核间通信机制介绍(代码分析篇)之 RPMSG-IPCC RTOS & QNX篇
  26. 【SemiDrive源码分析】【X9芯片启动流程】26 - R5 SafetyOS 之 LK_INIT_LEVEL_TARGET 阶段代码流程分析(TP Drvier、Audio Server初始化)
  27. 《【SemiDrive源码分析】【X9芯片启动流程】27 - R5 SafetyOS 之 .apps 应用启动代码流程分析》
  28. 《【SemiDrive源码分析】【X9芯片启动流程】28 - Android Preloader启动流程分析》
  29. 《【SemiDrive源码分析】【X9芯片启动流程】29 - MailBox 核间通信机制介绍(代码分析篇)之 Property篇》
  30. 《【SemiDrive源码分析】【X9芯片启动流程】30 - MailBox 核间通信机制介绍(代码分析篇)之 RPCall篇》
  31. 《【SemiDrive源码分析】【X9芯片启动流程】31 - MailBox 核间通信机制介绍(代码分析篇)之 Notify篇》
  32. 《【SemiDrive源码分析】【X9芯片启动流程】32 - MailBox 核间通信机制介绍(代码分析篇)之 Socket篇》
  33. 《【SemiDrive源码分析】【X9芯片启动流程】33 - MailBox 核间通信机制介绍(代码分析篇)之 /dev/vircan篇》


前面一段时间,我们在分析MailBox,虽然没全分析完,但MailBox 的原理已经差不多了解了,

由于项目快开始了,考虑到时间已经不支持继续详细分析MailBox 了,所以从本文开始,继续回归初始化流程的分析,尽快把启动流程看完,至于MailBox等后续再看吧。

在前面 《【SemiDrive源码分析】【X9芯片启动流程】14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析》 中,

我们分析到,R5 SafetyOSLK_INIT_LEVEL_TARGET 阶段主要是运行如下函数:
register_touch_driver_entry()
hal_vpu_create_mutex()
cospi_early_init()
hal_crypto_init()
(lk_init_hook)res_fs_init()
(lk_init_hook)audio_server_init()


一、register_touch_driver_entry() 注册TP 驱动

可以看出,触摸驱动是通过 register_touch_driver() 来探测初始化TP 的,

注册时,先调用 get_touch_device(&tsc, &tsc_num); 获取 TP 相关的配置信息保存在tsc[i] 中,
然后调用驱动换 probe 函数,传参 tsc[i]配置参数

# buildsystem\rtos\lk_boot\framework\service\input\include\touch_driver.h
#define register_touch_driver(drv) \
static void register_touch_driver_entry(uint level) \
{ \
    __register_touch_driver(&drv); \
} \
LK_INIT_HOOK(touch_driver##drv, register_touch_driver_entry, LK_INIT_LEVEL_TARGET)

# buildsystem\rtos\lk_boot\framework\service\input\touch_driver.c
void __register_touch_driver(struct touch_driver *driver)
{
    struct ts_board_config *tsc = NULL;
    int tsc_num = 0;
    get_touch_device(&tsc, &tsc_num);

    for (int i = 0; i < tsc_num; i++) {
        if (tsc[i].enable && driver->probe && !strcmp(tsc[i].device_name, driver->driver_name))
            driver->probe(&tsc[i]);
    }
}

1.1 TP 配置参数 ts_board_config

如下是 X9HP 默认的TP 配置参数,采用的是下LVDS3LVDS4 两个接口

# buildsystem\rtos\lk_boot\target\reference_x9\safety\touch_device.c
static struct ts_board_config tsc[] = {
    {
        /*---LVDS4---*/
        TS_ENABLE, "goodix", RES_I2C_I2C15, 0x5d,
        TS_SUPPORT_CTRLPANEL_MAIN, CONTROLPANEL,
        {1920, 720, 10, 0, 0, 0},
        {false, 12, 0x75, TCA9539_P07},
        {true, TI_SERDES, TI947_SINGLE, TI948, 0x1a, 0x2c, 3, 2},
        {0}, //reset-pin:0 not used yet
        {
            PortConf_PIN_I2S_MC_SD7, //irq-pin:131
            {0, 0}
        }
    },
    {
        /*---LVDS3---*/
        TS_DISABLE, "goodix", RES_I2C_I2C14, 0x5d,
        TS_SUPPORT_CTRLPANEL_AUX1, ENTERTAINMENT,
        {1920, 720, 10, 0, 0, 0},
        {false, 12, 0x75, TCA9539_P06},
        {false, TI_SERDES, TI947_SINGLE, TI948, 0x0, 0x0, 0, 0},
        {0}, //reset-pin:0 not used yet
        {
            PortConf_PIN_I2S_MC_SD6, //irq-pin:130
            {0, 0}
        }
    },
};

其结构体定义如下:
# buildsystem\rtos\lk_boot\framework\service\input\include\touch_device.h
struct ts_board_config {
    bool enable;
    const char *device_name;
    u32 res_id;
    u16 i2c_addr;
    u16 ts_domain_support;
    enum DISPLAY_SCREEN screen_id;
    struct ts_coord_config coord_config;
    struct port_expand_config port_config;
    struct ts_serdes_config serdes_config;
    struct ts_pin_config reset_pin;
    struct ts_pin_config irq_pin;
};

TP 使用串行、解串的芯片是 TI947_SINGLETI948

# buildsystem\rtos\lk_boot\framework\service\input\include\touch_device.h
enum ts_serdes_type {
    TI_SERDES,
    TS_SERDES_MAX,
};
enum ts_ser_type {
    TI941_SINGLE,
    TI941_SECOND,
    TI941_DUAL,
    TI947_SINGLE,
    TI947_SECOND,
    TI947_DUAL,
    TS_SER_MAX,
};
enum ts_des_type {
    TI948,
    TS_DES_MAX
};

1.2 探测函数 goodix_probe_device():初始化goodix->safe_ts_dev结构体,保存在全局safe_ts_dev[] 数组中,启动gt9xx_thread线程,注册中断函数

我们以 goodix.c 来举例,看看TP 初始化时做了什么:

# buildsystem\rtos\lk_boot\exdev\touch\src\goodix.c
static struct touch_driver goodix_driver = {
    "goodix",
    goodix_probe_device,
};
register_touch_driver(goodix_driver);

我们进入 goodix_probe_device() 函数,开始探测初始化:

  1. 申请并初始化 goodix 结构体,解析 dev_irq_pin_num 分别为 130131
  2. 获取 I2C 句柄 instance, 保存在 goodix->i2c_handle
  3. 解析 串行、解串 conf参数,配置串行解串链路: 检查 serdes 链路是否通、使能TI947_SINGLE 芯片、写寄存器 0x170x9e(启动i2c pass
  4. 检查 serdes 链路是否通,通过 I2C 直接读取 0x6 寄存器,在其中保存了对应的des地址
  5. 重置设备,读取版本号。
  6. 更新汇顶固件
  7. 启动gt9xx_thread线程运行goodix_ts_work_func()函数,及注册中断函数 goodix_irq_handler()
  8. 申请 struct safe_ts_device 结构体,保存在goodix->safe_ts_dev
  9. 注册 goodix->safe_ts_dev 设备,将其保存在全局 safe_ts_dev[TS_DO_CTRLPANEL_MAIN] = dev
# buildsystem\rtos\lk_boot\exdev\touch\src\goodix.c
static int goodix_probe_device(const struct ts_board_config *conf)
{
    struct goodix_ts_data *goodix = NULL;
    // 1. 申请并初始化 goodix 结构体,解析dev_irq_pin_num分别为130和131
    goodix = malloc(sizeof(struct goodix_ts_data));
    memset(goodix, 0, sizeof(struct goodix_ts_data));
    goodix->conf = conf;									// reference_x9\safety\touch_device.c
    goodix->instance = goodix->conf->ts_domain_support;		// 0x5d
    goodix->dev_irq = goodix->conf->irq_pin.pin_num;		// PortConf_PIN_I2S_MC_SD7:131, PortConf_PIN_I2S_MC_SD6:130
	
	// 2. 获取RES_I2C_I2C15和RES_I2C_I2C14 的I2C句柄instance, 保存在goodix->i2c_handle中
    hal_i2c_creat_handle(&goodix->i2c_handle, goodix->conf->res_id);	// RES_I2C_I2C15、RES_I2C_I2C14
    =====>  instance = hal_i2c_get_instance(i2c_res_glb_idx);
	
	// 3. 解析 串行、解串 conf参数,配置串行解串链路: 检查 serdes 链路是否通、使能TI947_SINGLE 芯片、写寄存器 0x17为0x9e(启动i2c pass)
    if (goodix->conf->serdes_config.enable) {
        if (goodix->conf->serdes_config.serdes_type == TI_SERDES) {
            enum ts_ser_type ser_type = goodix->conf->serdes_config.ser_type;	// TI947_SINGLE
            enum ts_des_type des_type = goodix->conf->serdes_config.des_type;	// TI948
            u16 ser_addr = goodix->conf->serdes_config.ser_addr;				// 0x1a
            u16 des_addr = goodix->conf->serdes_config.des_addr;				// 0x2c
			// 4. 检查 serdes 链路是否通,通过 I2C 直接读取 0x6 寄存器,在其中保存了对应的des 地址。
            ret = ti_serdes_link_check(goodix->i2c_handle, ser_addr, ser_type, des_addr, des_type);
			// 5. 使能TI947_SINGLE 芯片,写寄存器0x1e=0x01
            ret = ti_ser_enable_port(goodix->i2c_handle, ser_addr, ser_type);
			// 6. 写寄存器 0x17为0x9e: 启动i2c pas
            ret = ti_ser_enable_i2c_passthrough(goodix->i2c_handle, ser_addr, ser_type);
        }
    }
	// 7. 重置设备,读取版本号。
    do {
        goodix_reset_device(goodix);
        if (!goodix_read_version(goodix))
            break;
    } while (++count < 3);

	// 8. 更新汇顶固件
    ret = goodix_firmware_upgrade(goodix);
	// 9. 启动gt9xx_thread线程运行goodix_ts_work_func()函数,及注删中断函数 goodix_irq_handler()
    ret = goodix_config_device(goodix);
    =====================> // buildsystem\rtos\lk_boot\exdev\touch\src\goodix.c
    +	event_init(&goodix->event, false, EVENT_FLAG_AUTOUNSIGNAL);
	+   thread_t *tp_thread = thread_create("gt9xx_thread", goodix_ts_work_func, goodix, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
	+   thread_detach_and_resume(tp_thread);
	+   register_gpio_int_handler(goodix->dev_irq, IRQ_TYPE_EDGE_FALLING, goodix_irq_handler, goodix);
	+   unmask_gpio_interrupt(goodix->dev_irq);
    <=====================
	// 10. 申请 struct safe_ts_device 结构体,保存在goodix->safe_ts_dev中
    goodix->safe_ts_dev = safe_ts_alloc_device();
    goodix->safe_ts_dev->instance = goodix->conf->ts_domain_support;
    goodix->safe_ts_dev->screen_id = goodix->conf->screen_id;
    goodix->safe_ts_dev->vinfo.id = goodix->id;
    goodix->safe_ts_dev->vinfo.version = goodix->version;
    goodix->safe_ts_dev->vinfo.vendor = goodix->vendor;
    goodix->safe_ts_dev->vinfo.name = goodix->conf->device_name;
    goodix->safe_ts_dev->vinfo.ser_addr = goodix->conf->serdes_config.ser_addr;
    goodix->safe_ts_dev->vinfo.des_addr = goodix->conf->serdes_config.des_addr;
    goodix->safe_ts_dev->vinfo.ts_addr = goodix->conf->i2c_addr;
    goodix->safe_ts_dev->cinfo.max_touch_num = goodix->conf->coord_config.max_touch_num;
    goodix->safe_ts_dev->cinfo.swapped_x_y = goodix->conf->coord_config.swapped_x_y;
    goodix->safe_ts_dev->cinfo.inverted_x = goodix->conf->coord_config.inverted_x;
    goodix->safe_ts_dev->cinfo.inverted_y = goodix->conf->coord_config.inverted_y;
    goodix->safe_ts_dev->set_inited = goodix_set_inited;
    goodix->safe_ts_dev->vendor_priv = goodix;
	// 11. 注册 goodix->safe_ts_dev 设备,将其保存在全局 safe_ts_dev[TS_DO_CTRLPANEL_MAIN] = dev; 中
    ret = safe_ts_register_device(goodix->safe_ts_dev);
    dprintf(ALWAYS, "%s, instance=%#x, done ok\n", __func__, goodix->instance);
    return 0;
}

1.3 gt9xx_thread线程函数goodix_ts_work_func():解析event事件,读取tp坐标

static int goodix_ts_work_func(void *arg)
{
    struct goodix_ts_data *goodix = arg;
    u8 pdata[81] = {0,};
    int len, touch_num;
    struct touch_report_data report_data;

    while (1) {
        event_wait(&goodix->event);
        touch_num = goodix_ts_read_input_report(goodix, pdata);
        if (gdx_dbg_flag) {
            dprintf(ALWAYS, "%s: [%d] 0x%x, (0x%x, 0x%x, 0x%x, 0x%x)\n", __func__,
                    goodix->instance, pdata[0], pdata[3], pdata[2], pdata[5], pdata[4]);
        }

        report_data.key_value = pdata[0] & (1 << 4);
        report_data.touch_num = touch_num;

        for (int j = 0; j < touch_num; j++) {
            report_data.coord_data[j].id = *((u8 *)(pdata + 1 + GOODIX_CONTACT_SIZE * j));
            report_data.coord_data[j].x = *((u16 *)(pdata + 2 + GOODIX_CONTACT_SIZE * j));
            report_data.coord_data[j].y = *((u16 *)(pdata + 4 + GOODIX_CONTACT_SIZE * j));
            report_data.coord_data[j].w = *((u16 *)(pdata + 6 + GOODIX_CONTACT_SIZE * j));
        }

        len = 2 + touch_num * TS_COORD_METADATA_SIZE;
        safe_ts_report_data(goodix->safe_ts_dev, &report_data, len);
        unmask_gpio_interrupt(goodix->dev_irq);
    }
    return 0;
}

1.4 中断函数 goodix_irq_handler():在中断中触发 event事件

static enum handler_return goodix_irq_handler(void *arg)
{
    struct goodix_ts_data *goodix = arg;

    mask_gpio_interrupt(goodix->dev_irq);
    event_signal(&goodix->event, false);
    return INT_RESCHEDULE;
}

二、hal_vpu_create_mutex()

# buildsystem\rtos\lk_boot\hal\vpu_hal\codaj12\src\vpu_hal.c
void hal_vpu_create_mutex(uint level) { mutex_init(&vpu_mutex); }

三、cospi_early_init(): Nor Flash 读写服务初始化

启动了一个线程,不停的检测 xfer 事件,收到事件时,
根据事件的类型 SPI_NOR_OPS_READSPI_NOR_OPS_WRITE 做相应的读写动作。

# buildsystem\rtos\lk_boot\chipdev\spi_nor\host\cadence_ospi.c
static void cospi_early_init(uint level)
{
    struct cospi_pdata *cospi = &s_cospi;
    memset(cospi, 0, sizeof(struct cospi_pdata));

    mutex_init(&cospi->bus_mutex);

    event_init(&cospi->dma_event, false, EVENT_FLAG_AUTOUNSIGNAL);
    event_init(&cospi->complete_event, false, EVENT_FLAG_AUTOUNSIGNAL);
    event_init(&cospi->xfer_start_event, false, EVENT_FLAG_AUTOUNSIGNAL);
    event_init(&cospi->xfer_done_event, false, EVENT_FLAG_AUTOUNSIGNAL);
    dprintf(INFO, "creat cospi thread!\n");
    
    thread_t *thread =  thread_create("cospi_thread", cospi_data_thread, (void *)cospi,  HIGH_PRIORITY, DEFAULT_STACK_SIZE);
    thread_detach(thread);
    thread_resume(thread);
}

static int cospi_data_thread(void *arg)
{
    u32 ret;
    struct cospi_pdata *cospi = arg;
    struct spi_nor *nor = cospi->priv;
    struct spi_nor_handle *handle = NULL;

    for (;;) {
        event_wait(&cospi->xfer_start_event);
        nor = cospi->priv;
        ret = cospi_do_xfer(nor, &nor->data_cmd);
        if (nor->async_mode) {
            handle = nor->parent;
            if (handle && handle->event_handle) {
                handle->opt_type = nor->data_cmd.type;
                handle->opt_result = ret ? SPI_NOR_OPT_FAILED : SPI_NOR_OPT_COMPLETE;
                handle->event_handle(handle->opt_type, handle->opt_result);
            }
        }
        else {
            nor->data_error = ret;
            event_signal(&cospi->xfer_done_event, false);
        }
    }

    return 0;
}

static int cospi_do_xfer(struct spi_nor *nor, struct spi_nor_cmd *cmd)
{
    int ret = 0;
    struct cospi_pdata *cospi = nor->priv_data;
    uint32_t remaining = cmd->size;
    uint8_t *xfer_buf = (uint8_t *)cmd->buf;
    /* To prevent fifo overflow, set the max xfer length equel 128 * fifo_size. */
    const uint32_t max_xfer_length = cospi->fifo_depth * cospi->fifo_width * 128;
    uint32_t xfer_len;

    while(remaining) {
        switch (cmd->type) {
        case SPI_NOR_OPS_READ:
            ret = cospi_indirect_read(nor, &nor->data_cmd, xfer_buf, xfer_len);
            break;
        case SPI_NOR_OPS_WRITE:
            ret = cospi_indirect_write(nor, &nor->data_cmd, xfer_buf, xfer_len);
            break;
        }
        xfer_buf += xfer_len;
        nor->data_cmd.addr += xfer_len;
        remaining -= xfer_len;
    }

    nor->data_present = 0;
    return ret;
}

四、hal_crypto_init(): 加密环境CE初始化

# rtos\lk_boot\hal\crypto_hal\src\crypto_hal.c
void hal_crypto_init(uint level){
    ce_globle_init();
    return ;
}
# rtos\lk_boot\chipdev\crypto\silex\ce.c
int32_t ce_globle_init(void)
{
    LTRACEF("ce_globle_init enter\n");
    event_init(&g_trng_signal, false, 0);
    register_int_handler(ZONE_TRNG_INT, &trng_irq_handle, (void *)0);
    sram_config();
    init_vce_key_interface();
    g_ce_inited = true;
    return 0;
}

五、(lk_init_hook)res_fs_init()

static int res_fs_init(void)
{
    char diskd[3] = {DISKD+0x30,':',0};		// #define DISKD 7
    
    verified_res_image();
    r = f_mount(&fsd,diskd,1);

    return r;
}

六、(lk_init_hook)audio_server_init():音频服务初始化

# rtos\lk_boot\framework\audio\am\src\am_server.c
int audio_server_init(void)
{
    if (!is_str_resume(STR_AP1)) {
         am_init();
    } else {
         am_resume((void*)STR_AM_PATHS_ADDR);
    }
    return 0;
}

LK_INIT_HOOK(au_mgr, (lk_init_hook)audio_server_init,
             LK_INIT_LEVEL_TARGET + 2);

am_init() 函数定义在 buildsystem\rtos\freertos_safetyos\framework\audio\am\lib\libam_lib.a 中,看不到。



有关RTOS 的启动流程就看到这吧,
目前知道这个过程干了啥就够了,有关具体模块的内容,我也省略了,
一方面因为时间不太够,另一方面,这些具体模块,后面会单独分析。


本来下篇文章,按计划是要写《【SemiDrive源码分析】【X9芯片启动流程】27 - R5 SafetyOS 之 .apps 应用启动代码流程分析》的,
主要包含如下app:

# build-safety-x9plus-ref-serdes/safety-x9plus-ref-serdes.elf.map
# grep -rsn "__apps_start" ./build-safety-x9plus-ref-serdes/

.apps     0x0000000037908e24   0x168
          0x0000000037908e24             __apps_start = .
 *(.apps)
 .apps    0x0000000037908e24    0x14 ./build-safety-x9plus-ref-serdes/platform/kunlun/safety.mod.o
          0x0000000037908e24             _app_sysd_reboot_probe
 .apps    0x0000000037908e38    0x14 ./build-safety-x9plus-ref-serdes/application/services/pfmon.mod.o
          0x0000000037908e38             _app_pfm
 .apps    0x0000000037908e4c    0x14 ./build-safety-x9plus-ref-serdes/application/system/pvt.mod.o
          0x0000000037908e4c             _app_pvt_entry
 .apps    0x0000000037908e60    0x14 ./build-safety-x9plus-ref-serdes/application/test/spi_nor.mod.o
          0x0000000037908e60             _app_spi_nor_test
 .apps    0x0000000037908e74    0x28 ./build-safety-x9plus-ref-serdes/framework/service/audio.mod.o
          0x0000000037908e74             _app_i2s_rpc
          0x0000000037908e88             _app_audio_stream_rpc
 .apps    0x0000000037908e9c    0x14 ./build-safety-x9plus-ref-serdes/framework/service/camera.mod.o
          0x0000000037908e9c             _app_cam_srv
 .apps    0x0000000037908eb0    0x28 ./build-safety-x9plus-ref-serdes/framework/service/can_proxy.mod.o
          0x0000000037908eb0             _app_canproxy
          0x0000000037908ec4             _app_can_proxy_test
 .apps    0x0000000037908ed8    0x14 ./build-safety-x9plus-ref-serdes/framework/service/cluster_bridge.mod.o
          0x0000000037908ed8             _app_cluster_app
 .apps    0x0000000037908eec    0x14 ./build-safety-x9plus-ref-serdes/framework/service/display.mod.o
          0x0000000037908eec             _app_displayd
 .apps    0x0000000037908f00    0x14 ./build-safety-x9plus-ref-serdes/framework/service/update_monitor.mod.o
          0x0000000037908f00             _app_update_monitor
 .apps    0x0000000037908f14    0x28 ./build-safety-x9plus-ref-serdes/framework/test/dcf.mod.o
          0x0000000037908f14             _app_dcf_sample
          0x0000000037908f28             _app_test_posix
 .apps    0x0000000037908f3c    0x14 ./build-safety-x9plus-ref-serdes/lib/shell.mod.o
          0x0000000037908f3c             _app_shell
 .apps    0x0000000037908f50    0x14 ./build-safety-x9plus-ref-serdes/application/early_app/BootAnimation.mod.o
          0x0000000037908f50             _app_ba_replay
 .apps    0x0000000037908f64    0x14 ./build-safety-x9plus-ref-serdes/application/early_app/controlpanel.mod.o
          0x0000000037908f64             _app_sysd_controlpanel
 .apps    0x0000000037908f78    0x14 ./build-safety-x9plus-ref-serdes/application/early_app/main.mod.o
          0x0000000037908f78             _app_USM
          0x0000000037908f8c             __apps_end = .

实话说,对目前来说,看这个对我没任何作用,有兴趣的兄弟可以自行找到对应的代码去阅读。
后面项目中会涉及到的,如开机动画等,这些,后面涉及到时,我会单独起文章写。


从《【SemiDrive源码分析】【X9芯片启动流程】18 - R5 SafetyOS 之 LK_INIT_LEVEL_PLATFORM 阶段代码流程(下)启动QNX、Android》 中,
我们知道 R5是通过调用 reboot_ap1() 来启动 android preloader 的,那下篇文章,我们正式进入 android 分析 preloader 源码

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-06-16 21:49:32  更:2022-06-16 21:49:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 8:03:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计