SOC移植
6 分钟阅读
概述
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位数据,从最高有效位开始查找
- 位序镜面翻转:Intel位序(主流的小端CPU都是Inter位序)是越往高位位序号越大,
摩托罗拉位序(PowerPC架构的CPU)是越往高位位序号越小,
因此在两个系统混用时需要将数据的位序进行镜面翻转
原子操作
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位清0xwbmpaop_s1i()
:将第i位置1xwbmpaop_x1i()
:翻转第i位xwbmpaop_t1i()
:测试第i位是否为1xwbmpaop_t0i_then_s1i()
:测试第i位是否为0,然后把它置1xwbmpaop_t1i_then_c0i()
:测试第i位是否为1,然后把它清0xwbmpaop_ffs_then_c0i()
:从最低有效位开始查找第一个为1的位并把它清0xwbmpaop_ffz_then_s1i()
:从最低有效位开始查找第一个为0的位并把它置1xwbmpaop_fls_then_c0i()
:从最高有效位开始查找第一个为1的位并把它清0xwbmpaop_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的外设中断;
- 负数:表示异常。
- XWOS定义了中断号类型
- 中断优先级要求
切换上下文的中断为系统中最低优先级中断
切换上下文的中断 <= 滴答定时器的中断 <= 调度器服务中断
- 操作系统移植层中需要提供的函数:
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的IDxwospl_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
中只定义了 MEMORY
和 include 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根目录
- 需要包含的源码文件:
- 内核目录
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的连接脚本。