SOC移植

概述

XWOS的移植,包括以下几个环节:

  • 编译环境
  • 初始化流程
  • XWOS移植层(XWOSPL)
  • XWOS移植实现层(XWOSIMPL)

XWOS采用 适配器模式 的方法来构建移植相关的代码:XWOS移植层(XWOSPL)定义 接口, XWOS移植实现层(XWOSIMPL)提供 实现

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

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

例如,ARMv7m架构下,ADL目录为 xwcd/soc/arm/v7m/gcc/ ,其中代码对 STM32、S32K、i.MX RT1052、GD32等都是复用的,m3、m4、m7的差异又由CDL目录来描述, 相同的CPU内核不同SOC又由SDL来描述,不同的电路板由BDL来描述,最后由他们共同完成 对编译环境、初始化流程以及XWOS移植实现层(XWOSIMPL)的 实现

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

  • xwos/ospl/*.h :XWOS提供给BSP的头文件, 不可 被XWOS自身的头文件包含。
    • 前缀 xwospl :BSP中需要提供实现的函数
    • 前缀 xwosplcb :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 :包含了无锁队列相关的定义
    • xwos/ospl/soc/setjmp.h :包含了 setjmp.h 相关的定义
    • xwos/ospl/soc/spinlock.h :包含了自旋锁相关的定义
    • xwos/ospl/soc/xwaop[bit].h :包含了原子操作相关的定义
    • xwos/ospl/soc/xwbmpaop.h :包含了位图原子操作相关的定义
    • xwos/ospl/soc/xwbop.h :包含了位操作相关的定义
    • xwos/ospl/soc/xwsc.h :包含了系统调用相关的定义

移植

XWOS的移植,包括:基本类型、编译器、断点、setjmp、系统调用与系统特权、 位操作、原子操作、无锁队列、自旋锁、中断、硬件定时器、调度器。

基本类型

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

  • XWOS头文件: xwos/lib/type.h , 详见基本类型
  • Adapter: xwos/ospl/soc/type.h
  • Adaptee: xwosimpl_soc_type.h 文件对某些类型按照架构的ELFABI规则重新进行了定义, 并且需要将 ARCH_HAVE_xxxx 宏定义为1,表明覆盖 xxxx 的默认定义, 此文件一般位于 ADL 目录,例如 xwcd/soc/arm/v7m/gcc/xwosimpl_soc_type.h
  • 基本类型:
    • ARCH_HAVE_XWU8_T :宏,定义为1表示 arch_type.h 中提供类型 xwu8_t
    • xwu8_t :类型,8位无符号整数
    • ARCH_HAVE_ATOMIC_XWU8_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwu8_t
    • atomic_xwu8_t :类型,原子的8位无符号整数
    • ARCH_HAVE_XWS8_T :宏,定义为1表示 arch_type.h 中提供类型 xws8_t
    • xws8_t :类型,8位有符号整数
    • ARCH_HAVE_ATOMIC_XWS8_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xws8_t
    • atomic_xws8_t :类型,原子的8位有符号整数
    • ARCH_HAVE_XWU16_T :宏,定义为1表示 arch_type.h 中提供类型 xwu16_t
    • xwu16_t :类型,16位无符号整数
    • ARCH_HAVE_ATOMIC_XWU16_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwu16_t
    • atomic_xwu16_t :类型,原子的16位无符号整数
    • ARCH_HAVE_XWS16_T :宏,定义为1表示 arch_type.h 中提供类型 xws16_t
    • xws16_t :类型,16位有符号整数
    • ARCH_HAVE_ATOMIC_XWS16_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xws16_t
    • atomic_xws16_t :类型,原子的16位有符号整数
    • ARCH_HAVE_XWU32_T :宏,定义为1表示 arch_type.h 中提供类型 xwu32_t
    • xwu32_t :类型,32位无符号整数
    • ARCH_HAVE_ATOMIC_XWU32_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwu32_t
    • atomic_xwu32_t :类型,原子的32位无符号整数
    • ARCH_HAVE_XWS32_T :宏,定义为1表示 arch_type.h 中提供类型 xws32_t
    • xws32_t :类型,32位有符号整数
    • ARCH_HAVE_ATOMIC_XWS32_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xws32_t
    • atomic_xws32_t :类型,原子的32位有符号整数
    • ARCH_HAVE_XWU64_T :宏,定义为1表示 arch_type.h 中提供类型 xwu64_t
    • xwu64_t :类型,64位无符号整数
    • ARCH_HAVE_ATOMIC_XWU64_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwu64_t
    • atomic_xwu64_t :类型,原子的64位无符号整数
    • ARCH_HAVE_XWS64_T :宏,定义为1表示 arch_type.h 中提供类型 xws64_t
    • xws64_t :类型,64位有符号整数
    • ARCH_HAVE_ATOMIC_XWS64_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xws64_t
    • atomic_xws64_t :类型,原子的64位有符号整数
    • ARCH_HAVE_XWSZ_T :宏,定义为1表示 arch_type.h 中提供类型 xwsz_t
    • xwsz_t :类型,无符号大小值类型
    • ARCH_HAVE_ATOMIC_XWSZ_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwsz_t
    • atomic_xwsz_t :类型,原子的无符号大小值类型
    • ARCH_HAVE_XWSSZ_T :宏,定义为1表示 arch_type.h 中提供类型 xwssz_t
    • xwssz_t :类型,有符号大小值类型
    • ARCH_HAVE_ATOMIC_XWSSZ_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwssz_t
    • atomic_xwssz_t :类型,原子的有符号大小值类型
    • ARCH_HAVE_XWSTK_T :宏,定义为1表示 arch_type.h 中提供类型 xwstk_t
    • xwstk_t :类型,无符号栈类型
    • ARCH_HAVE_ATOMIC_XWSTK_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwstk_t
    • atomic_xwstk_t :类型,原子的无符号栈类型
    • ARCH_HAVE_XWPTR_T :宏,定义为1表示 arch_type.h 中提供类型 xwptr_t
    • xwptr_t :类型,无符号指针值类型
    • ARCH_HAVE_ATOMIC_XWPTR_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwptr_t
    • atomic_xwptr_t :类型,原子的无符号指针值类型
    • ARCH_HAVE_XWREG_T :宏,定义为1表示 arch_type.h 中提供类型 xwreg_t
    • xwreg_t :类型,无符号寄存器类型
    • ARCH_HAVE_ATOMIC_XWREG_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwreg_t
    • atomic_xwreg_t :类型,原子的无符号寄存器类型
    • ARCH_HAVE_XWSREG_T :宏,定义为1表示 arch_type.h 中提供类型 xwsreg_t
    • xwsreg_t :类型,有符号寄存器类型
    • ARCH_HAVE_ATOMIC_XWSREG_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwsreg_t
    • atomic_xwsreg_t :类型,原子的有符号寄存器类型
    • ARCH_HAVE_XWSQ_T :宏,定义为1表示 arch_type.h 中提供类型 xwsq_t
    • xwsq_t :类型,无符号顺序值类型
    • ARCH_HAVE_ATOMIC_XWSQ_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwsq_t
    • atomic_xwsq_t :类型,原子的无符号顺序值类型
    • ARCH_HAVE_XWSSQ_T :宏,定义为1表示 arch_type.h 中提供类型 xwssq_t
    • xwssq_t :类型,有符号顺序值类型
    • ARCH_HAVE_ATOMIC_XWSSQ_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwssq_t
    • atomic_xwssq_t :类型,原子的有符号顺序值类型
    • ARCH_HAVE_XWID_T :宏,定义为1表示 arch_type.h 中提供类型 xwid_t
    • xwid_t :类型,无符号ID值类型
    • ARCH_HAVE_ATOMIC_XWID_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwid_t
    • atomic_xwid_t :类型,原子的无符号ID值类型
    • ARCH_HAVE_XWSID_T :宏,定义为1表示 arch_type.h 中提供类型 xwsid_t
    • xwsid_t :类型,有符号ID值类型
    • ARCH_HAVE_ATOMIC_XWSID_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwsid_t
    • atomic_xwsid_t :类型,原子的有符号ID值类型
    • ARCH_HAVE_XWER_T :宏,定义为1表示 arch_type.h 中提供类型 xwer_t
    • xwer_t :类型,有符号错误码类型
    • ARCH_HAVE_ATOMIC_XWER_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwer_t
    • atomic_xwer_t :类型,原子的有符号错误码类型
    • ARCH_HAVE_XWPR_T :宏,定义为1表示 arch_type.h 中提供类型 xwpr_t
    • xwpr_t :类型,有符号优先级类型
    • ARCH_HAVE_ATOMIC_XWPR_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwpr_t
    • atomic_xwpr_t :类型,原子的有符号优先级类型
    • ARCH_HAVE_XWBMP_T :宏,定义为1表示 arch_type.h 中提供类型 xwbmp_t
    • xwbmp_t :类型,无符号位图类型
    • ARCH_HAVE_ATOMIC_XWBMP_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwbmp_t
    • xwbmpy_a :类型,原子的无符号位图类型
    • ARCH_HAVE_XWTM_T :宏,定义为1表示 arch_type.h 中提供类型 xwtm_t
    • xwtm_t :类型,有符号优先级类型
    • ARCH_HAVE_ATOMIC_XWTM_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwtm_t
    • atomic_xwtm_t :类型,原子的有符号优先级类型
    • ARCH_HAVE_XWLFQ_T :宏,定义为1表示 arch_type.h 中提供类型 xwlfq_t
    • xwlfq_t :类型,无锁队列类型
    • ARCH_HAVE_ATOMIC_XWLFQ_T :宏,定义为1表示 arch_type.h 中提供类型 atomic_xwlfq_t
    • atomic_xwlfq_t :类型,原子的无锁队列类型
    • ARCH_HAVE_XWISR_F :宏,定义为1表示 arch_type.h 中提供类型 xwisr_f
    • atomic_xwer_t :类型,原子的有符号错误码类型
    • ARCH_HAVE_XWIRQ_T :宏,定义为1表示 arch_type.h y中提供类型 xwirq_t
    • xwirq_t :类型,有符号中断号类型

编译器

  • XWOS头文件: xwos/lib/compiler.h ,被 xwos/standard.h 包含。
  • Adapter: xwos/ospl/soc/compiler.h
  • Adaptee: 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 :表明数据的起始地址对齐到指针的尺寸
  • xwcc_offsetof(type, member) :计算member在结构体type中的偏移,等价于标准C库中的 offsetof()

架构指令

CPU架构会提供一些特殊指令,一般这些指令很难用C语言表达出,以方便使用,XWOS内核对统一的部分进行了相同的封装。

  • XWOS头文件:被包含在 xwos/standard.h 内。
  • Adapter: xwos/ospl/soc/isa.h
  • Adaptee: xwosimpl_soc_isa.h

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

  • 断点指令
  • 内存屏障

setjmp/longjmp

XWOS的C库中提供了类似于C标准库中的 setjmp()/longjmp() 函数组合, 其实现与切换上下文时如何保存寄存器有密切关系。

  • XWOS头文件: xwos/lib/setjmp.h
  • Adapter: xwos/ospl/soc/setjmp.h
  • Adaptee: xwosimpl_soc_setjmp.h

系统调用与系统特权

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

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

XWOS的C库中提供了可切换CPU访问权限的函数 xwsc() ,通过 xwsc() 可以让用户模式暂时拥有系统特权调用某个函数。

  • XWOS头文件: xwos/lib/sc.h
  • Adapter: xwos/ospl/soc/xwsc.h
  • Adaptee: xwosimpl_soc_xwsc.h

位操作

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

  • XWOS头文件: xwos/lib/xwbop.h
  • Adapter: xwos/ospl/soc/xwbop.h
  • Adaptee: xwosimpl_soc_xwbop.h
  • 基本类型的位操作函数集合:
    • 位序镜面翻转:Intel位序(主流的小端CPU都是Inter位序)是越往高位位序号越大, 摩托罗拉位序(PowerPC架构的CPU)是越往高位位序号越小, 因此在两个系统混用时需要将数据的位序进行镜面翻转
      • 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
  • Adapter:
    • xwos/ospl/soc/xwaop.h
  • Adaptee:
    • xwosimpl_soc_xwaop.h
    • xwosimpl_soc_xwaop/*
  • 说明
    • 其他类型的原子操作,XWOS内核会基于4个基本类型进行封装。 64位原子操作如果不支持可不提供;
    • 如果CPU架构比较简单,无原子操作指令,可通过关中断实现这些原子操作函数;
    • 某些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的C库中提供了无锁队列的函数,无锁队列的实现依赖于CPU的原子操作指令。

  • XWOS头文件: xwos/lib/lfq.h
  • Adapter: xwos/ospl/soc/lfq.h
  • Adaptee: xwosimpl_soc_lfq.h

自旋锁

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

  • XWOS头文件:
    • xwos/osal/lock/spinlock.h :自旋锁
    • xwos/osal/lock/seqlock.h :自旋锁的派生锁,顺序锁
  • Adapter: xwos/ospl/soc/spinlock.h
  • Adaptee: xwosimpl_soc_spinlock.h

中断

  • XWOS头文件: xwos/osal/irq.h
  • Adapter:
    • xwos/ospl/irq.h定义 了BSP中需要适配的函数;
  • Adaptee:
    • xwosimpl_irq.h实现 了XWOS移植层中定义的函数;
  • 中断号:
    • 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的中断
    • bool xwospl_cpuirq_test_lc(void) :测试本地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的调度、超时、软件定时器都基于滴答中断来实现。

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

调度器

  • Adapter: xwos/ospl/skd.h
  • Adaptee: xwosimpl_skd.h
  • 适配函数:
    • 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(仅限多核)

链接脚本

SOC描述层中包含了SOC的基本链接脚本,使用时需要在电路板目录的 cfg 文件夹中定义一个 XuanWuOS.lds , 其中包含了SOC的地址空间的定义,然后再 include SOC描述层中的连接脚本即可。 例如: xwbd/WeActH750/cfg/XuanWuOS.lds 中只定义了 MEMORYinclude xwcd/soc/arm/v7m/gcc/m7/stm32/h7.lds

  • XWOS定义了一些 段(section) ,链接时,可将内核代码、内核数据放在镜像文件的特定区域。 这需要在 链接脚本 中指明这些 如何存放。
    • __xwos_init_code :初始化代码,存放在 .xwos.init.text
    • __xwos_init_rodata :初始化阶段的const数据,存放在 .xwos.init.rodata
    • __xwos_exit_code :退出代码,存放在 .xwos.exit.text
    • __xwos_exit_rodata :退出阶段的const数据,存放在 .xwos.exit.rodata
    • __xwos_ivt :中断向量表,存放在 .xwos.ivt
    • __xwos_isr :中断代码,存放在 .xwos.isr.text
    • __xwos_bh :中断底半部代码,存放在 .xwos.isr.text
    • __xwos_code :XWOS内核代码,存放在 .xwos.text
    • __xwos_api :XWOS内核API,存放在 .xwos.text
    • __xwos_rodata :const数据,存放在 .xwos.rodata
    • __xwos_data :全局变量与静态变量,存放在 .xwos.data
  • 如果不需要这些自定义的 ,可将上面的宏定义为 ,相应的,代码会默认 放在 .text 段,数据会默认放在 .data 段,const数据会默认放在 .rodata 段。 这三个 都是由编译器默认产生的。
  • __xwos_data 定义为 时,配置文件 cfg/xwos.h 中的配置 XWKNCFG_RELOCATE_DATA 也应该不定义或定义为 0

初始化流程

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

flowchart LR
    poweron("上电") --> 低级初始化阶段 --> 系统初始化阶段 --> 用户程序

    subgraph 低级初始化阶段
        direction TB
        arch_lowlevel_init["arch_lowlevel_init()"] --> cpu_lowlevel_init
        cpu_lowlevel_init["cpu_lowlevel_init()"] --> soc_lowlevel_init
        soc_lowlevel_init["soc_lowlevel_init()"] --> board_lowlevel_init
        board_lowlevel_init["board_lowlevel_init()"]
    end

    subgraph 系统初始化阶段
        direction TB
        xwos_init["xwos_init()"] --> arch_relocate
        arch_relocate["arch_relocate()"] --> arch_init
        arch_init["arch_init()"] --> cpu_init
        cpu_init["cpu_init()"] --> soc_init
        soc_init["soc_init()"] --> board_init
    end

    subgraph 用户程序
        direction LR
        subgraph "xwos_main()"
            direction LR
            skd["启动调度器"]
            thd["线程初始化"]
            device["设备驱动初始化"]
            libc["C/C++标准库初始化"]
            lua["Lua虚拟机初始化"]
        end
    end
  • 用户可在流程中找地方插入SOC的初始化的代码,但要注意:
    • lowlevel_init的流程中不可访问全局变量,因为还未将全局变量的初值从flash中拷贝到RAM中;
    • cxx_init之后才可开始调用C++的代码;
  • XWOS的初始化流程中,在 soc_init() 中完成对中断控制器、调度器的初始化, 如果用户不使用XWOS的初始化流程,需要依次调用:
    • xwos_init() :初始化XWOS内核;
    • 多核系统:
      • xwmp_irqc_construct() :初始化每个CPU的中断控制器;
      • xwmp_irqc_register() :将每个CPU的中断控制器注册到中断控制子系统;
      • xwmp_skd_init_lc() :分别在每个CPU上都运行一次这个函数初始化自己的调度器;
    • 单核系统:
      • xwup_irqc_init() :初始化中断控制器;
      • xwup_skd_init_lc() :初始化调度器;

编译集成环境

XWOS提供了一个构建系统,可在Windows、Linux上运行。 用户可以选择使用XWOS的编译集成环境,也可以使用其他IDE进行编译。

使用玄武构建系统

  • XWOS的构建系统在构建 内核xwmd 模块、 xwcd 模块、 xwem 模块、 xwam 模块、 oem 模块时都是独立编译成静态库 .a ,然后再链接。 各个模块的编译配置(头文件、编译器选项)都是完全独立的,可以理解为不同的子工程。
  • 构建是从 xwbd/电路板名称/ 录下执行命令 make 开始的。

使用其他IDE构建系统

  • 需要增加的头文件搜索路径:
    • XWOS根目录 XWOS
    • 架构描述层(ADL)目录:以ARMv7m为例, xwcd/soc/arm/v7m/gcc
    • CPU描述层(CDL)目录:以ARMv7m7为例, xwcd/soc/arm/v7m/gcc/m7
    • SOC描述层(SDL)目录:以STM32H7为例, xwcd/soc/arm/v7m/gcc/m7/stm32h7x
    • 电路板目录:以开发板 WeActMiniStm32H750 为例, xwbd/WeActMiniStm32H750
  • 需要包含的源码文件:
    • 内核目录 xwos
    • 架构描述层(ADL)目录:以ARMv7m为例, xwcd/soc/arm/v7m/gcc
    • CPU描述层(CDL)目录:以ARMv7m7为例, xwcd/soc/arm/v7m/gcc/m7
    • SOC描述层(SDL)目录:以STM32H7为例, xwcd/soc/arm/v7m/gcc/m7/stm32h7x
    • 电路板目录:以开发板WeActH750为例, xwbd/WeActH750
    • 中间件 xwmd 、驱动框架 xwcd/ds 、第三方模块 xwem 、应用模块 xwam 不是必须的,若只使用XWOS内核,这些可以删除。
  • 若其他IDE的工具链不是gcc,则需要重新实现ADL、CDL、SDL中的 xwosimpl 的代码,此种情况 xwcd/soc 中的代码也不需要。
  • 需要修改配置, xwbd/WeActMiniStm32H750/cfg
  • 需要在 xwbd/WeActMiniStm32H750 目录,执行一次 make cfg ,生成 然后将 xwbd/WeActMiniStm32H750/wkspc/autogen.h 拷贝到 xwbd/WeActMiniStm32H750/cfg 中。
  • 需要配置IDE的连接脚本。