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_txwu8_t:类型,8位无符号整数ARCH_HAVE_ATOMIC_XWU8_T:宏,定义为1表示arch_type.h中提供类型atomic_xwu8_tatomic_xwu8_t:类型,原子的8位无符号整数ARCH_HAVE_XWS8_T:宏,定义为1表示arch_type.h中提供类型xws8_txws8_t:类型,8位有符号整数ARCH_HAVE_ATOMIC_XWS8_T:宏,定义为1表示arch_type.h中提供类型atomic_xws8_tatomic_xws8_t:类型,原子的8位有符号整数ARCH_HAVE_XWU16_T:宏,定义为1表示arch_type.h中提供类型xwu16_txwu16_t:类型,16位无符号整数ARCH_HAVE_ATOMIC_XWU16_T:宏,定义为1表示arch_type.h中提供类型atomic_xwu16_tatomic_xwu16_t:类型,原子的16位无符号整数ARCH_HAVE_XWS16_T:宏,定义为1表示arch_type.h中提供类型xws16_txws16_t:类型,16位有符号整数ARCH_HAVE_ATOMIC_XWS16_T:宏,定义为1表示arch_type.h中提供类型atomic_xws16_tatomic_xws16_t:类型,原子的16位有符号整数ARCH_HAVE_XWU32_T:宏,定义为1表示arch_type.h中提供类型xwu32_txwu32_t:类型,32位无符号整数ARCH_HAVE_ATOMIC_XWU32_T:宏,定义为1表示arch_type.h中提供类型atomic_xwu32_tatomic_xwu32_t:类型,原子的32位无符号整数ARCH_HAVE_XWS32_T:宏,定义为1表示arch_type.h中提供类型xws32_txws32_t:类型,32位有符号整数ARCH_HAVE_ATOMIC_XWS32_T:宏,定义为1表示arch_type.h中提供类型atomic_xws32_tatomic_xws32_t:类型,原子的32位有符号整数ARCH_HAVE_XWU64_T:宏,定义为1表示arch_type.h中提供类型xwu64_txwu64_t:类型,64位无符号整数ARCH_HAVE_ATOMIC_XWU64_T:宏,定义为1表示arch_type.h中提供类型atomic_xwu64_tatomic_xwu64_t:类型,原子的64位无符号整数ARCH_HAVE_XWS64_T:宏,定义为1表示arch_type.h中提供类型xws64_txws64_t:类型,64位有符号整数ARCH_HAVE_ATOMIC_XWS64_T:宏,定义为1表示arch_type.h中提供类型atomic_xws64_tatomic_xws64_t:类型,原子的64位有符号整数ARCH_HAVE_XWSZ_T:宏,定义为1表示arch_type.h中提供类型xwsz_txwsz_t:类型,无符号大小值类型ARCH_HAVE_ATOMIC_XWSZ_T:宏,定义为1表示arch_type.h中提供类型atomic_xwsz_tatomic_xwsz_t:类型,原子的无符号大小值类型ARCH_HAVE_XWSSZ_T:宏,定义为1表示arch_type.h中提供类型xwssz_txwssz_t:类型,有符号大小值类型ARCH_HAVE_ATOMIC_XWSSZ_T:宏,定义为1表示arch_type.h中提供类型atomic_xwssz_tatomic_xwssz_t:类型,原子的有符号大小值类型ARCH_HAVE_XWSTK_T:宏,定义为1表示arch_type.h中提供类型xwstk_txwstk_t:类型,无符号栈类型ARCH_HAVE_ATOMIC_XWSTK_T:宏,定义为1表示arch_type.h中提供类型atomic_xwstk_tatomic_xwstk_t:类型,原子的无符号栈类型ARCH_HAVE_XWPTR_T:宏,定义为1表示arch_type.h中提供类型xwptr_txwptr_t:类型,无符号指针值类型ARCH_HAVE_ATOMIC_XWPTR_T:宏,定义为1表示arch_type.h中提供类型atomic_xwptr_tatomic_xwptr_t:类型,原子的无符号指针值类型ARCH_HAVE_XWREG_T:宏,定义为1表示arch_type.h中提供类型xwreg_txwreg_t:类型,无符号寄存器类型ARCH_HAVE_ATOMIC_XWREG_T:宏,定义为1表示arch_type.h中提供类型atomic_xwreg_tatomic_xwreg_t:类型,原子的无符号寄存器类型ARCH_HAVE_XWSREG_T:宏,定义为1表示arch_type.h中提供类型xwsreg_txwsreg_t:类型,有符号寄存器类型ARCH_HAVE_ATOMIC_XWSREG_T:宏,定义为1表示arch_type.h中提供类型atomic_xwsreg_tatomic_xwsreg_t:类型,原子的有符号寄存器类型ARCH_HAVE_XWSQ_T:宏,定义为1表示arch_type.h中提供类型xwsq_txwsq_t:类型,无符号顺序值类型ARCH_HAVE_ATOMIC_XWSQ_T:宏,定义为1表示arch_type.h中提供类型atomic_xwsq_tatomic_xwsq_t:类型,原子的无符号顺序值类型ARCH_HAVE_XWSSQ_T:宏,定义为1表示arch_type.h中提供类型xwssq_txwssq_t:类型,有符号顺序值类型ARCH_HAVE_ATOMIC_XWSSQ_T:宏,定义为1表示arch_type.h中提供类型atomic_xwssq_tatomic_xwssq_t:类型,原子的有符号顺序值类型ARCH_HAVE_XWID_T:宏,定义为1表示arch_type.h中提供类型xwid_txwid_t:类型,无符号ID值类型ARCH_HAVE_ATOMIC_XWID_T:宏,定义为1表示arch_type.h中提供类型atomic_xwid_tatomic_xwid_t:类型,原子的无符号ID值类型ARCH_HAVE_XWSID_T:宏,定义为1表示arch_type.h中提供类型xwsid_txwsid_t:类型,有符号ID值类型ARCH_HAVE_ATOMIC_XWSID_T:宏,定义为1表示arch_type.h中提供类型atomic_xwsid_tatomic_xwsid_t:类型,原子的有符号ID值类型ARCH_HAVE_XWER_T:宏,定义为1表示arch_type.h中提供类型xwer_txwer_t:类型,有符号错误码类型ARCH_HAVE_ATOMIC_XWER_T:宏,定义为1表示arch_type.h中提供类型atomic_xwer_tatomic_xwer_t:类型,原子的有符号错误码类型ARCH_HAVE_XWPR_T:宏,定义为1表示arch_type.h中提供类型xwpr_txwpr_t:类型,有符号优先级类型ARCH_HAVE_ATOMIC_XWPR_T:宏,定义为1表示arch_type.h中提供类型atomic_xwpr_tatomic_xwpr_t:类型,原子的有符号优先级类型ARCH_HAVE_XWBMP_T:宏,定义为1表示arch_type.h中提供类型xwbmp_txwbmp_t:类型,无符号位图类型ARCH_HAVE_ATOMIC_XWBMP_T:宏,定义为1表示arch_type.h中提供类型atomic_xwbmp_txwbmpy_a:类型,原子的无符号位图类型ARCH_HAVE_XWTM_T:宏,定义为1表示arch_type.h中提供类型xwtm_txwtm_t:类型,有符号优先级类型ARCH_HAVE_ATOMIC_XWTM_T:宏,定义为1表示arch_type.h中提供类型atomic_xwtm_tatomic_xwtm_t:类型,原子的有符号优先级类型ARCH_HAVE_XWLFQ_T:宏,定义为1表示arch_type.h中提供类型xwlfq_txwlfq_t:类型,无锁队列类型ARCH_HAVE_ATOMIC_XWLFQ_T:宏,定义为1表示arch_type.h中提供类型atomic_xwlfq_tatomic_xwlfq_t:类型,原子的无锁队列类型ARCH_HAVE_XWISR_F:宏,定义为1表示arch_type.h中提供类型xwisr_fatomic_xwer_t:类型,原子的有符号错误码类型ARCH_HAVE_XWIRQ_T:宏,定义为1表示arch_type.hy中提供类型xwirq_txwirq_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.hxwosimpl_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的连接脚本。