XWOS移植说明

各种SOC平台移植XWOS的说明

概述

XWOS的移植包括以下几个要素:

  • XWOS移植层(XWOSPL):类似于C++中的抽象接口类,声明接口和实现部分成员函数。
  • XWOS移植实现层(XWOSIMPL):类似于C++,提供XWOS移植层(XWOSPL)接口的实现。
  • 初始化流程
  • 编译

为了提高代码的复用性,XWOS移植实现层(XWOSIMPL)相关的代码又细分为:

  • 架构描述层(ADL)
  • CPU描述层(CDL)
  • SOC描述层(SDL)
  • 电路板描述层(BDL)

例如,ARMv7m架构下,ADL目录为 xwcd/soc/arm/v7m/gcc/ ,其中代码对所有基于ARMv7-M的CPU都是复用的。 m3、m4、m7的差异又由CDL目录来描述。相同的CPU内核不同SOC又由SDL目录来描述。相同SOC不同的电路板由BDL目录来描述。

XWOS移植层(XWOSPL)头文件规则

由于C语言并不像C++一样拥有 virtual 关键字,因此有必要设定一个命名规则表达出与C++抽象接口类同样的意思:

  • xwos/ospl/*.h :XWOS提供给BSP的头文件, 不可 被XWOS自身的头文件包含。
    • 前缀 xwospl_ :类似于C++中的纯虚函数,XWOS不提供缺省实现。BSP中需要提供实现的函数。
    • 前缀 xwosplcb_ :类似于C++中已实现的成员函数,提供给BSP调用。
  • xwos/ospl/soc/*.h :其中包含了BSP提供给XWOS的头文件, 可被 XWOS的头文件包含。
    • xwos/ospl/soc/type.h :包含了平台类型的定义
    • xwos/ospl/soc/compiler.h :包含了平台编译器相关的定义
    • xwos/ospl/soc/isa.h :包含了平台指令和架构相关的定义
    • xwos/ospl/soc/lfq.h :包含了无锁队列相关的定义
      • 前缀 soc_ :类似于C++中的纯虚函数,XWOS不提供缺省实现。BSP中需要提供实现的函数。
    • xwos/ospl/soc/setjmp.h :包含了 setjmp.h 相关的定义
      • xwlib_setjmp() :类似于C++中的虚函数,XWOS提供缺省实现。若不提供覆盖实现,函数默认实现为C标准库中 setjmp()
      • xwlib_longjmp() :类似于C++中的虚函数,XWOS提供缺省实现。若不提供覆盖实现,函数默认实现为使用C标准库中 longjmp()
    • xwos/ospl/soc/spinlock.h :包含了自旋锁相关的定义
      • 前缀 soc_ :类似于C++中的纯虚函数,XWOS不提供缺省实现。BSP中需要提供实现的函数。
    • xwos/ospl/soc/xwaop.h :包含了原子操作相关的定义
      • 前缀 xwaop_ :类似于C++中的虚函数,XWOS提供了缺省实现。BSP中可提供一个覆盖实现。
    • xwos/ospl/soc/xwbop.h :包含了位操作相关的定义
      • 前缀 xwbop_ :类似于C++中的虚函数,XWOS提供了缺省实现。BSP中可提供一个覆盖实现。
    • xwos/ospl/soc/xwsc.h :包含了系统权限与系统调用相关的定义
      • xws64_t xwsc(xwsc_f func, xwreg_t argnum, ...) :类似于C++中的纯虚函数。XWOS不提供缺省实现,也可以不用实现。 若不提供实现,系统特权调用 xwsc() 不可用 。

移植

XWOS的移植,包括:基本类型、编译器、架构指令、无锁队列、setjmp/longjmp、系统调用与系统权限、自旋锁、位操作、原子操作、中断、硬件定时器、调度器、线程本地存储(TLS)。

基本类型

XWOS定义了自己的一套基本类型,所有源码都是围绕基本类型展开的。

  • XWOS头文件: xwos/lib/type.h ,被 xwos/standard.h 包含。
  • 接口: xwos/ospl/soc/type.h
  • 实现: xwosimpl_soc_type.h
    • ARCH_HAVE_xxxx 宏定义为 1 ,表明覆盖 xxxx 的默认定义。 此文件通常位于 ADL 目录,例如 xwcd/soc/arm/v7m/gcc/xwosimpl_soc_type.h
  • 所有基本类型可参考 基本类型

编译器

  • XWOS头文件: xwos/lib/compiler.h ,被 xwos/standard.h 包含。
  • 接口: xwos/ospl/soc/compiler.h
  • 实现: xwosimpl_soc_compiler.h ,根据所使用的编译器,提供定义。
  • 编译器相关的宏定义:
    • __xwcc_section(s) :表明符号属于段 s
    • __xwcc_aligned(x) :表明数据的起始地址对齐到 x 字节处。
    • __xwcc_inline :表明函数是内联函数,需要和 static 一起使用。
    • __xwcc_packed :表明数据结构体是紧凑分布的,编译器不要做优化对齐处理。
    • __xwcc_must_check :表明函数返回值必须被读取,否则编译器会报警告。
    • __xwcc_unused :表明变量或函数未被使用,用于去除编译警告。
    • __xwcc_noreturn :表明函数不会返回。
    • __xwcc_hot :表明函数在代码中经常被调用,可以帮助某些编译器优化编译。
    • __xwcc_atomic :表明变量是原子的,C11标准中被定义为 _Atomic ,C99标准中被定义为 volatile
    • __xwcc_likely(x) :表明条件 x 大概率为 true ,用于帮助编译器优化 if..else.. 的编译。
    • __xwcc_unlikely(x) :表明条件 x 大概率为 false ,用于帮助编译优化 if..else.. 的编译。
    • __xwcc_alignl1cache :表明数据的起始地址对齐到1级缓存(way-set缓存)的缓存线。
    • __xwcc_alignptr :表明数据的起始地址对齐到指针的尺寸。32位系统,数据对齐到4字节。64位系统,数据对齐到8字节。
    • xwcc_offsetof(type, member) :计算 member 在结构体 type 中的偏移,等价于标准C库中的 offsetof()

架构指令

CPU架构会提供一些特殊指令,这些指令通常很难用C语言直接表达出。为了方便使用,XWOS封装了部分常见的指令。

  • 接口: xwos/ospl/soc/isa.h
  • 实现: xwosimpl_soc_isa.h

这些架构指令包括但不限于:

  • XWOS头文件: xwos/lib/mb.h ,被 xwos/standard.h 包含。
    • 内存屏障
      • xwmb_compiler() :编译器的内存屏障,防止编译器对数据读写的乱序优化。
      • xwmb_isb() :指令同步屏障,用于等待指令流水线中的指令全部执行完毕才重新从指令缓存中取指令。
      • xwmb_ddb() :数据依赖屏障,第一次读取内存的数据作为第二次读取的地址,即会产生 数据依赖屏障 , 对应于 stdatomic.h 中定义的消费序( memory_order_consume )。
        • 大部分处理器架构都会自动产生数据依赖屏障,不需要额外的指令。此时, xwmb_ddb() 定义为 xwmb_compiler()
        • 只有少数CPU才会需要数据依赖屏障指令,例如DEC Alpha。
      • xwmb_rmb() :读内存屏障
      • xwmb_wmb() :写内存屏障
      • xwmb_mb() :读写内存屏障
      • xwmb_dma_rmb() :使用DMA时的读内存屏障
      • xwmb_dma_wmb() :使用DMA时的写内存屏障
      • xwmb_dma_mb() :使用DMA时的内存屏障
      • xwmb_mp_mb() :多核系统的内存屏障
      • xwmb_mp_rmb() :多核系统的读内存屏障
      • xwmb_mp_wmb() :多核系统的写内存屏障
      • xwmb_mp_acquire() :多核系统中确保 acquire 内存序的屏障。 acquire 内存序通常配合读取指令使用。
      • xwmb_mp_release() :多核系统中确保 release 内存序的屏障。 release 内存序通常配合存入指令使用。
  • XWOS头文件: xwos/standard.h
    • 调试
      • soc_bug() :通常用于ARCH、CPU、SOC、Board等比较底层的代码出错时的处理。通常定义为断点指令,方便用调试器来调试。

无锁队列

XWOS的C库中提供了无锁队列的函数,无锁队列的实现依赖于CPU的原子操作指令。

  • XWOS头文件: xwos/lib/lfq.h
  • 接口: xwos/ospl/soc/lfq.h
  • 实现: xwosimpl_soc_lfq.h

setjmp/longjmp

XWOS的C库中提供了类似于C标准库中的 setjmp()/longjmp() 函数组合。 其具体实现与OS切换上下文时如何切换寄存器有密切关系,C标准库中的标准实现可能不能满足要求。 若不提供实现,将默认使用C标准库中的标准实现。

  • XWOS头文件: xwos/lib/setjmp.h
  • 接口: xwos/ospl/soc/setjmp.h
  • 实现:
    • xwosimpl_soc_setjmp.h
    • xwosimpl_soc_setjmp.c

系统调用与系统特权

通常CPU都有两种权限模式:用户和系统。

  • 系统模式下可以访问所有的寄存器;
  • 用户模式下某些CPU内的寄存器无法被访问(例如开关中断),只能通过特殊指令让CPU进入系统模式才可访问。

XWOS的C库中提供了可切换CPU访问权限的函数 xwsc() 。通过 xwsc() 可以让用户模式暂时拥有系统特权调用某个函数。 xwsc() 并不要求必须被实现。这种情况下,移植XWOS时,所有线程应该只运行在系统权限模式。

  • XWOS头文件: xwos/lib/sc.h
  • 接口: xwos/ospl/soc/xwsc.h
  • 实现: xwosimpl_soc_xwsc.h

自旋锁

在多核系统中,被多个CPU共同访问的内存区域需要被自旋锁保护,自旋锁的实现依赖于原子操作指令与内存屏障指令。

  • XWOS头文件:
    • xwos/osal/lock/spinlock.h :自旋锁
    • xwos/osal/lock/seqlock.h :自旋锁的改良锁 —— 顺序锁
  • 接口: xwos/ospl/soc/spinlock.h
  • 实现: xwosimpl_soc_spinlock.h

位操作

XWOS的C库中提供了位操作的函数集合,为提高效率,部分位操作可使用特殊指令覆盖实现。

  • XWOS头文件: xwos/lib/xwbop.h
  • 接口: xwos/ospl/soc/xwbop.h
  • 实现:
    • xwosimpl_soc_xwbop.h
    • xwosimpl_soc_xwbop.c
  • 基本类型的位操作函数集合:
    • 位序镜面翻转:Intel位序(小端)与摩托罗拉位序(大端)之间的转换。
      • xwbop_rbit8() :镜面翻转8位数据的位序
      • xwbop_rbit16() :镜面翻转16位数据的位序
      • xwbop_rbit32() :镜面翻转32位数据的位序
      • xwbop_rbit64() :镜面翻转64位数据的位序
    • 大小端反转
      • xwbop_re16() :反转16位数据的字节序
      • xwbop_re16s32() :反转16位数据的字节序,并将符号位扩展到32位,返回有符号32位数据
      • xwbop_re32() :反转32位数据的字节序
      • xwbop_re32s64() :反转32位数据的字节序,并将符号位扩展到64位,返回有符号64位数据
      • xwbop_re64() ::反转64位数据的字节序
    • 查找被置 1 的位
      • xwbop_ffs8() :8位数据,从最低有效位开始查找
      • xwbop_fls8() :8位数据,从最高有效位开始查找
      • xwbop_ffs16() :16位数据,从最低有效位开始查找
      • xwbop_fls16() :16位数据,从最高有效位开始查找
      • xwbop_ffs32() :32位数据,从最低有效位开始查找
      • xwbop_fls32() :32位数据,从最高有效位开始查找
      • xwbop_ffs64() :64位数据,从最低有效位开始查找
      • xwbop_fls64() :64位数据,从最高有效位开始查找

原子操作

XWOS的C库中提供了原子操作的函数集合,原子操作的实现依赖于CPU的原子操作指令。

  • XWOS头文件:
    • xwos/lib/xwaop.h
  • 接口: xwos/ospl/soc/xwaop.h
  • 实现:
    • xwosimpl_soc_xwaop.h
    • xwosimpl_soc_xwaop/*.c
  • 说明
    • XWOS内核会基于8个基本类型( xws8_txwu8_txws16_txwu16_txws32_txwu32_txws64_txwu64_t)实现其他基本类型的原子操作。 因为其他基本类型都是基于这8个基本类型定义出来的。
    • 64位原子操作可不提供实现。
    • 如果CPU架构比较简单,无原子操作指令,可考虑基于自旋锁来实现原子操作函数。在单核系统,自旋锁的实现只需关闭/打开中断。
    • 某些CPU架构只提供与CPU位宽一致的原子操作指令,这种情况下,其他位宽的原子操作指令可考虑基于自旋锁来实现。在单核系统,自旋锁的实现只需关闭/打开中断。
  • 基本类型的原子操作函数集合
    • load() :加载(可指定内存序)
    • store() :存储(可指定内存序)
    • read() :读(内存序:load-require)
    • write() :写(内存序:store-release)
    • add() :加法运算
    • sub() :减法运算
    • rsb() :反向减法运算
    • and() :与运算
    • or() :或运算
    • xor() :异或运算
    • teq_then_write() :测试原子变量是否与测试值 相等 ,然后
    • teq_then_add() :测试原子变量是否与测试值 相等 ,然后做 加法 运算
    • teq_then_sub() :测试原子变量是否与测试值 相等 ,然后做 减法 运算
    • teq_then_rsb() :测试原子变量是否与测试值 相等 ,然后做 反向减法 运算
    • tne_then_write() :测试原子变量是否与测试值 不相等 ,然后
    • tne_then_add() :测试原子变量是否与测试值 不相等 ,然后做 加法 运算
    • tne_then_sub() :测试原子变量是否与测试值 不相等 ,然后做 减法 运算
    • tne_then_rsb() :测试原子变量是否与测试值 不相等 ,然后做 反向减法 运算
    • tge_then_write() :测试原子变量是否 大于等于 测试值,然后
    • tge_then_add() :测试原子变量是否 大于等于 测试值,然后做 加法 运算
    • tge_then_sub() :测试原子变量是否 大于等于 测试值,然后做 减法 运算
    • tge_then_rsb() :测试原子变量是否 大于等于 测试值,然后做 反向减法 运算
    • tgt_then_write() :测试原子变量是否 大于 测试值,然后
    • tgt_then_add() :测试原子变量是否 大于 测试值,然后做 加法 运算
    • tgt_then_sub() :测试原子变量是否 大于 测试值,然后做 减法 运算
    • tgt_then_rsb() :测试原子变量是否 大于 测试值,然后做 反向减法 运算
    • tle_then_write() :测试原子变量是否 小于等于 测试值,然后
    • tle_then_add() :测试原子变量是否 小于等于 测试值,然后做 加法 运算
    • tle_then_sub() :测试原子变量是否 小于等于 测试值,然后做 减法 运算
    • tle_then_rsb() :测试原子变量是否 小于等于 测试值,然后做 反向减法 运算
    • tlt_then_write() :测试原子变量是否 小于 测试值,然后
    • tlt_then_add() :测试原子变量是否 小于 测试值,然后做 加法 运算
    • tlt_then_sub() :测试原子变量是否 小于 测试值,然后做 减法 运算
    • tlt_then_rsb() :测试原子变量是否 小于 测试值,然后做 反向减法 运算
    • tgele_then_write() :测试原子变量是否在闭区间 [l,r] ,然后
    • tgele_then_add() :测试原子变量是否在闭区间 [l,r] ,然后做 加法 运算
    • tgele_then_sub() :测试原子变量是否在闭区间 [l,r] ,然后做 减法 运算
    • tgele_then_rsb() :测试原子变量是否在闭区间 [l,r] ,然后做 反向减法 运算
    • tgelt_then_write() :测试原子变量是否在左闭右开区间 [l,r) ,然后
    • tgelt_then_add() :测试原子变量是否在左闭右开区间 [l,r) ,然后做 加法 运算
    • tgelt_then_sub() :测试原子变量是否在左闭右开区间 [l,r) ,然后做 减法 运算
    • tgelt_then_rsb() :测试原子变量是否在左闭右开区间 [l,r) ,然后做 反向减法 运算
    • tgtle_then_write() :测试原子变量是否在左开右闭区间 (l,r] ,然后
    • tgtle_then_add() :测试原子变量是否在左开右闭区间 (l,r] ,然后做 加法 运算
    • tgtle_then_sub() :测试原子变量是否在左开右闭区间 (l,r] ,然后做 减法 运算
    • tgtle_then_rsb() :测试原子变量是否在左开右闭区间 (l,r] ,然后做 反向减法 运算
    • tgtlt_then_write() :测试原子变量是否在开区间 (l,r) ,然后
    • tgtlt_then_add() :测试原子变量是否在开区间 (l,r) ,然后做 加法 运算
    • tgtlt_then_sub() :测试原子变量是否在开区间 (l,r) ,然后做 减法 运算
    • tgtlt_then_rsb() :测试原子变量是否在开区间 (l,r) ,然后做 反向减法 运算
    • tst_then_op() :使用 tst() 函数测试原子变量,然后使用 op() 函数操作
  • 位图数组的原子操作
    • xwbmpaop_c0i() :将第 i 位清 0
    • xwbmpaop_s1i() :将第 i 位置 1
    • xwbmpaop_x1i() :翻转第 i
    • xwbmpaop_t1i() :测试第 i 位是否为 1
    • xwbmpaop_t0i_then_s1i() :测试第 i 位是否为 0 ,然后把它置 1
    • xwbmpaop_t1i_then_c0i() :测试第 i 位是否为 1 ,然后把它清 0
    • xwbmpaop_ffs_then_c0i() :从最低有效位开始查找第一个为 1 的位并把它清 0
    • xwbmpaop_ffz_then_s1i() :从最低有效位开始查找第一个为 0 的位并把它置 1
    • xwbmpaop_fls_then_c0i() :从最高有效位开始查找第一个为 1 的位并把它清 0
    • xwbmpaop_flz_then_s1i() :从最高有效位开始查找第一个为 0 的位并把它置 1

中断

  • XWOS头文件: xwos/osal/irq.h
  • 接口: xwos/ospl/irq.h
  • 实现:
    • xwosimpl_irq.h
    • xwosimpl_irq.c
  • 中断号:
    • XWOS定义了中断号类型 xwirq_t ,是一个有符号整数:
    • 整数和0:表示SOC的外设中断。
    • 负数:表示异常。
  • 中断优先级要求
  • 切换上下文的中断为系统中 最低优先级 中断。
  • 切换上下文的中断优先级 <= 滴答定时器的中断优先级 <= 调度器服务中断优先级
  • 操作系统移植层中需提供实现的函数:
    • void xwospl_cpuirq_enable_lc(void) :开启CPU的中断开关
    • void xwospl_cpuirq_disable_lc(void) :关闭CPU的中断开关
    • void xwospl_cpuirq_restore_lc(xwreg_t cpuirq) :保存当前CPU的中断开关状态后关闭
    • void xwospl_cpuirq_save_lc(xwreg_t * cpuirq) :恢复之前保存的CPU的中断开关状态
    • xwer_t xwospl_irq_get_id(xwirq_t * irqnbuf) :获取当前中断的中断号,亦可用于判断上下文
    • xwer_t xwospl_irq_enable(xwirq_t irqn) :开启某个外设中断
    • xwer_t xwospl_irq_disable(xwirq_t irqn) :关闭某个外设中断
    • xwer_t xwospl_irq_save(xwirq_t irqn, xwreg_t * flag) :保存某个外设中断的开关,然后将其关闭
    • xwer_t xwospl_irq_restore(xwirq_t irqn, xwreg_t flag) :恢复某个外设中断的开关

硬件定时器

每个CPU都需要一个私有的硬件定时器提供周期性的滴答中断。XWOS的调度、超时、软件定时器都基于滴答中断来实现。

  • 接口: xwos/ospl/syshwt.h
  • 实现:
    • xwosimpl_syshwt.h
    • xwosimpl_syshwt.c
  • 适配函数:
    • xwospl_syshwt_init() :初始化硬件定时器
    • xwospl_syshwt_start() :启动硬件定时器
    • xwospl_syshwt_stop() :关闭硬件定时器
    • xwospl_syshwt_get_timeconfetti() :返回还有多少纳秒进入下一次定时器中断

调度器

  • 接口: xwos/ospl/skd.h
  • 实现:
    • xwosimpl_skd.h
    • xwosimpl_skd.c
  • 适配函数:
    • xwospl_skd_init(struct xwospl_skd * xwskd) :初始化调度调度器
    • xwospl_skd_init_stack() :初始化调度对象(线程)的栈
    • xwospl_skd_get_id() :获取当前CPU的ID
    • xwospl_skd_start() :启动调度器
    • xwospl_skd_suspend() :暂停调度器,用于电源管理
    • xwospl_skd_resume() :继续调度器,用于电源管理
    • xwospl_skd_req_swcx() :请求调度
    • xwospl_skd_isr_swcx() :切换上下文的中断
    • xwospl_thd_exit_lc() :当前CPU上的线程退出
    • xwospl_thd_freeze_lc() :冻结当前CPU中正在运行的线程
    • xwospl_thd_outmigrate() :将线程迁出其他CPU,并准备迁入其他CPU(仅限多核)
    • xwospl_thd_immigrate() :迁移线程至目标CPU(仅限多核)

线程本地存储

从C11标准开始,C语言支持线程本地存储(TLS)。XWOS提供了对关键字 _Thread_local (C11) 以及 thread_local (C2X) 的支持。

  • 接口: xwos/ospl/tls.h
  • 实现: xwosimpl_tls.c
  • 适配函数:
    • void xwospl_tls_init(struct xwospl_skdobj_stack * stk) :在线程栈中初始化TLS。

线程本地存储(TLS)有4种标准模型:global-dynamic, local-dynamic, initial-exec, local-exec。 XWOS只支持 initial-execlocal-exec ,默认使用 -ftls-model=local-exec 。 移植XWOS时,需要将 .got 段放入链接脚本中:

        .got : {
                *(.got.plt) *(.igot.plt) *(.got) *(.igot)
        } > code_mr AT> code_mr

链接脚本

XWOS的链接脚本由两部分组成:

  • SOC描述层中的 xxx.lds 描述 SECTIONS
    • 用户可参考已有的文件进行修改,例如:
      • ARMv6M
        • STM32F0x: xwcd/soc/arm/v6m/m0/stm32/f0.lds
      • ARMv7M
        • STM32H7x: xwcd/soc/arm/v7m/m7/stm32/h7.lds
        • S32K3xx: xwcd/soc/arm/v7m/m7/s32k3xx/s32k3xx.lds
        • STM32F4x: xwcd/soc/arm/v7m/m4/stm32/f4.lds
        • S32K14x: xwcd/soc/arm/v7m/m4/s32k14x/s32k14x.lds
        • GD32F30x: xwcd/soc/arm/v7m/m4/gd32/f30x.lds
        • STM32F1x: xwcd/soc/arm/v7m/m3/stm32/f1.lds
        • GD32F10x: xwcd/soc/arm/v7m/m3/gd32/f10x.lds
      • ARMv8A
        • RPi4B: xwcd/soc/arm64/v8a/a72/bcm2711/soc.lds
      • PowerPC Embedded
        • MPC560xB: xwcd/soc/powerpc/e200x/e200z0h/mpc560xb/soc.lds
      • RISC-V
        • GD32VF10x: xwcd/soc/riscv/nuclei/bumblebee/gd32v/f10x.lds
  • 电路板目录中的 brd.lds 定义 MEMORY

初始化流程

XWOS提供了一个通用的 启动流程

flowchart LR
    预初始化阶段 --> 初始化阶段 --> 后初始化阶段 --> 主函数阶段

    subgraph 预初始化阶段
        direction TB
        exc["异常初始化"]
        exc["浮点单元初始化"]
        exc["内存初始化"]
    end

    subgraph 初始化阶段
        xwos_init["xwos_init()"]
    end

    subgraph 后初始化阶段
        direction LR
        device["设备驱动初始化"]
        mm["动态内存分配器的初始化"]
    end

    subgraph 主函数阶段
        direction LR
        skd_init["初始化调度器: xwos_skd_init_lc()"]
        thd["建立线程"]
        skd_start["启动调度器: xwos_skd_start_lc()"]
    end

XWOS将初始化流程分为四个阶段:

  • 预初始化阶段:xwos_preinit()
    • 由用户定义。
    • 不可访问全局变量,通常用于调用 arch_init() , cpu_init(), soc_init() ,加载内存数据。
  • 初始化阶段:xwos_init()
    • 由XWOS定义。
  • 后初始化阶段:xwos_postinit()
    • 由用户定义。
    • 可访问全局变量,通常用于初始化芯片驱动,初始电源管理、初始化内存管理。
  • 主函数阶段:xwos_main()
    • 由用户定义。
    • 通常用于定义线程,启动调度器。
    • 若需要使用libc中的标准函数,还需要初始化libc。依据配置 XWCFG_LIBC 选择的libc,选择调用 newlibac_init()picolibcac_init()
    • C++运行环境也会在调用 newlibac_init()picolibcac_init() 时被初始化。

配置

移植XWOS时,用户需要在电路板目录中提供配置 cfg/ 。配置的具体内容可参考 配置

集成编译环境

XWOS提供了 构建系统 ,可在Windows、Linux上运行。 用户代码需要使用 玄武模块 进行集成。