跳转至

启动流程

本文档描述 WS63 芯片从上电到应用运行的启动全链路。先讲原理,后讲代码细节。


启动全景(原理篇)

WS63 的启动可以理解为 六段接力,每一段完成特定任务后把控制权交给下一段:

flowchart LR
    ROM[Boot ROM]
    FB[FlashBoot]
    APP[App 裸机启动]
    KERN[内核初始化]
    HW[硬件初始化]
    SCHED[调度器启动]

    ROM --> FB --> APP --> KERN --> HW --> SCHED
阶段 运行环境 核心任务
Boot ROM 出厂固化 ROM 找到 FlashBoot,加载到 SRAM
FlashBoot SRAM,裸机 初始化 Flash、校验 App 签名、跳转
App 裸机启动 Flash 原地执行 使能 Cache、代码段重定位
内核初始化 SRAM,裸机 初始化任务/中断/时钟/IPC 子系统
硬件初始化 SRAM,裸机 初始化所有外设驱动
调度器启动 SRAM,RTOS 启动调度,进入多任务世界

关键理解

  • osKernelInitialize()osKernelStart() 不是连续调用的——中间夹着 hw_init() 和任务创建
  • app_main() 不是系统入口——它只是系统创建的众多任务之一(默认优先级 27)
  • 最先运行的不是空闲任务——调度器启动后,最高优先级的就绪任务(AT/BT,优先级 1)先跑
  • 内核初始化前有一个"占位 TCB"——LOS_PrepareMainTask() 创建,让内核代码有合法的上下文可引用

启动详细流程(进阶篇)

以下为真实的代码级调用链,便于调试和问题定位。

源码入口速查

阶段 入口文件
Bootloader 汇编 bootloader/flashboot_ws63/startup/riscv_init.S
Bootloader C bootloader/flashboot_ws63/startup/main.c
Bootloader 跳转 App bootloader/commonboot/src/boot_jump.c
App 汇编 application/ws63/ws63_liteos_application/reset_vector.S
App C 初始化 application/ws63/ws63_liteos_application/main.c
内核 initcall 框架 kernel/liteos/.../kernel/init/los_init.c
内核 CMSIS 启动 kernel/liteos/.../compat/cmsis/cmsis_liteos2.c
板级 PreMainTask kernel/liteos/.../targets/ws63/board.c

调用链总览

flowchart LR
    RV[reset_vector]
    RI[runtime_init]
    M[main]
    PMT[LOS_PrepareMainTask]
    OKI[osKernelInitialize]
    HI[hw_init]
    MT[main_initialise]
    OKS[osKernelStart]

    RV --> RI --> M --> PMT --> OKI --> HI --> MT --> OKS

以上为 main() 核心路径,省略了 patch_init / AT / log / filesystem 等分支。

一、Boot ROM

芯片上电后执行固化在 ROM 中的代码:初始化基本时钟和栈,从 Flash 固定地址加载 FlashBoot 到 SRAM 并校验,然后跳转。

出厂固化,不可修改。

二、FlashBoot

汇编入口 bootloader/flashboot_ws63/startup/riscv_init.SReset_Handler

禁用 PMP → 保存启动标志 → 设 mtvec → 关全局中断 → 初始化 gp/sp → 填充栈(0xefbeadde)→ 清零 32 个通用寄存器 → 清零 .bss → 跳转 C 入口。

C 入口 start_fastboot()bootloader/flashboot_ws63/startup/main.c

IO 电平适配 → Watchdog(7s) → ws63_flashboot_init()(TCXO→UART→分区表→PMP→堆→SFC Flash)→ eFuse → ws63_upg_check()(FOTA 升级检查)→ ws63_verify_app_handle()(App 签名校验)→ 产测/备份恢复。

跳转 App bootloader/commonboot/src/boot_jump.c

void jump_to_execute_addr(uint32_t addr)
{
    void (*entry)(void) = (void*)(uintptr_t)(addr);
    entry();
}

跳转地址 = App 镜像基址 + APP_IMAGE_HEADER_LEN(0x400),落在 .text.entry 段。

三、App 裸机启动

汇编入口 application/ws63/ws63_liteos_application/reset_vector.SHandleReset

mtvec → 关中断 → 开 FPU → 初始化 gp/sp → 填充栈 → tail-call runtime_init()

runtime_init() application/ws63/ws63_liteos_application/main.c.text.runtime.init 段,Flash 原地执行):

dyn_mem_cfg()        → 配置动态内存
cpu_cache_init()     → 使能 I-Cache(32KB) + D-Cache(4KB)
do_relocation()      → 代码段重定位:
   rom_data / rom_patch    (Flash → DTCM/ITCM)
   tcm_text / tcm_data     (Flash → ITCM/DTCM)
   sram_text               (Flash → SRAM)
   .data / .bss            (Flash → SRAM)
main()                → 跳转入口

四、系统初始化 main()

application/ws63/ws63_liteos_application/main.c:整个 main() 是裸机到 RTOS 的桥梁,运行在调度器启动前的单任务上下文。

4.1 内核前硬件初始化

patch_init() → uapi_partition_init() → pmp_enable()
→ set_uart_tcxo_clock_period() → ArchSetExcHook(sys_fault_handler)

4.2 内核预初始化 LOS_PrepareMainTask()

kernel/liteos/.../targets/ws63/board.c:创建占位 TCB——

  • OsSetMainTask():创建 "osMain" 任务控制块,优先级 = LOWEST + 1
  • OsCurrTaskSet(OsGetMainTask()):设为"当前运行任务",确保后续内核代码有合法的 TCB

这个占位 TCB 在调度器启动后不再被调度,仅用于内核初始化期间的运行上下文。

4.3 RTOS 内核初始化 osKernelInitialize()

kernel/liteos/.../compat/cmsis/cmsis_liteos2.c → 内部调用 OsMain()

OsMain() 通过 initcall 框架按级别+同步阶段排序调用各内核模块:

级别 同步 函数 作用
AHEAD s0 OsMemExcInteractionDoInit 内存异常交互
AHEAD s0 OsRegister 内核全局变量
ARCH s0 ArchExcInit 架构异常
KERNEL s0 OsTaskInit 任务 CB 数组 + 优先级队列
KERNEL s0 OsTaskMonInit 任务监控
KERNEL s0 DoOsMemSystemInit 内核内存系统
KERNEL s1 OsHwiInit 硬件中断框架
KERNEL s1 OsIpcInit 信号量/互斥锁/队列
KERNEL s2 OsCpupInit CPU 占用率统计
KERNEL s2 OsTickInit 系统时钟节拍
KERNEL s3 OsSwtmrInit 软件定时器
KERNEL s3 OsIdleTaskCreate 创建空闲任务
KERNEL s4 OsMpInit 多核管理

4.4 内核后硬件初始化 hw_init()

RF 电源 → 时钟切换 → UART → pinctrl → GPIO → 硬件定时器 → SysTick → TCXO 校准 → Watchdog(15s) → eFuse → SFC Flash → NV 存储 → 温度传感器 → 加密引擎 → Wi-Fi MAC → XO 校准。

4.5 服务与应用初始化

AT 命令 init → 日志 init → LittleFS 挂载 → system_init_array() (C++ 构造)
→ main_initialise() (创建 AT/BT/WiFi/app 等 RTOS 任务)
→ app_tasks_init() (执行 sample 注册的 app_run() initcall)

创建的主要任务:

任务 优先级 说明
AT 命令 1 UART AT 消息处理
BT 协议栈 1 蓝牙协议栈主线程
Wi-Fi 25 Wi-Fi 协议栈
app_main 27 用户应用入口(条件编译)

五、调度器启动 osKernelStart()

kernel/liteos/.../compat/cmsis/cmsis_liteos2.cOsStart()

OsTickStart();                    // 启动系统时钟节拍
taskCB = OsGetTopTask();          // 选中最高优先级任务
taskCB->taskStatus = RUNNING;     // 标记运行态
ArchStartToRun(taskCB);           // mret 跳转,调度器正式接管

完整调用链(速查)

Boot ROM
  └→ FlashBoot: riscv_init.S:_start
       └→ start_fastboot()
            └→ jump_to_execute_addr(app_addr + 0x400)
                 └→ App: reset_vector.S:reset_vector → HandleReset
                      └→ runtime_init()
                           ├── dyn_mem_cfg / cpu_cache_init / do_relocation
                           └── main()
                                ├── patch / partition / PMP
                                ├── LOS_PrepareMainTask()     ← 占位 TCB
                                ├── osKernelInitialize()      ← OsMain initcall
                                ├── hw_init()
                                ├── AT / log / filesystem
                                ├── main_initialise()         ← 创建真实任务
                                ├── app_tasks_init()
                                └── osKernelStart()           ← 调度器接管

相关配置项

配置项 说明
CONFIG_SYS_CLOCK_FREQ 系统主频
CONFIG_KERNEL_HEAP_SIZE 内核堆大小
CONFIG_APP_TASK_STACK_SIZE 应用任务栈大小
CONFIG_APP_TASK_PRIORITY 应用任务优先级
CONFIG_SECURE_BOOT 安全启动
CONFIG_OTA_ENABLE OTA 升级

参考