板级支持包函数组

更新时间:
2024-03-14
下载文档

板级支持包函数组

空闲 HOOK 初始化

系统启动时通过 halIdleInit 函数来初始化目标系统空闲时间作业,代码实现如下:

#include <SylixOS.h>
static VOID  halIdleInit (VOID)
{
    API_SystemHookAdd(__arm_wfi, LW_OPTION_THREAD_IDLE_HOOK);
}

API_SystemHookAdd 函数将 arm_wfi 函数注册为空闲 HOOK。此 HOOK 在任务上下文中被调用,空闲线程会不间断的调用此 HOOK,此 HOOK 只能在系统进入多任务前被设置。arm_wfi 函数的作用是使 CPU 进入空闲等待中断。

注意:
CPU0 不能使用 WFI 指令。
函数 API_SystemHookAdd 的原型如下:

#include <SylixOS.h>
ULONG  API_SystemHookAdd (LW_HOOK_FUNC  hookfunc, ULONG  ulOpt);

函数 API_KernelFpuPrimaryInit 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 hookfunc 是递的是 HOOK 功能函数。
  • 参数 ulOpt 是 HOOK 类型,如下表所示。
HOOK 类型含义
LW_OPTION_THREAD_CREATE_HOOK线程创建 HOOK
LW_OPTION_THREAD_DELETE_HOOK线程删除 HOOK
LW_OPTION_THREAD_SWAP_HOOK线程切换 HOOK
LW_OPTION_THREAD_TICK_HOOK时钟中断 HOOK
LW_OPTION_THREAD_INIT_HOOK线程初始化过程 HOOK
LW_OPTION_THREAD_IDLE_HOOK空闲线程 HOOK
LW_OPTION_KERNEL_INITBEGIN系统初始化 HOOK
LW_OPTION_KERNEL_INITEND系统初始化完成 HOOK
LW_OPTION_KERNEL_REBOOT系统重启(关机)HOOK
LW_OPTION_WATCHDOG_TIMER系统软件看门狗 HOOK
LW_OPTION_OBJECT_CREATE_HOOK内核对象创建 HOOK
LW_OPTION_OBJECT_DELETE_HOOK内核对象删除 HOOK
LW_OPTION_FD_CREATE_HOOK文件描述符创建 HOOK
LW_OPTION_FD_DELETE_HOOK文件描述符删除 HOOK
LW_OPTION_CPU_IDLE_ENTER当前 CPU 准备运行/恢复运行 IDLE 任务 HOOK
LW_OPTION_CPU_IDLE_EXIT当前 CPU IDLE 任务被抢占 HOOK
LW_OPTION_CPU_INT_ENTER当前 CPU 发生中断,在调用中断处理函数前 HOOK
LW_OPTION_CPU_INT_EXIT当前 CPU 发生中断,在调用中断处理函数后 HOOK
LW_OPTION_STACK_OVERFLOW_HOOK线程堆栈溢出 HOOK
LW_OPTION_FATAL_ERROR_HOOK线程出现致命错误(接收到异常信号)HOOK
LW_OPTION_VPROC_CREATE_HOOK进程创建 HOOK
LW_OPTION_VPROC_DELETE_HOOK进程删除 HOOK

浮点运算器初始化

早期的 ARM 没有协处理器,所有浮点运算是由 CPU 来模拟的,即所需浮点运算均在浮点运算模拟器(float math emulation)上进行,需要的浮点运算,常要耗费数千个循环才能执行完毕,因此特别缓慢。ARM 核浮点运算分为软浮点和硬浮点,软浮点是通过浮点库去实现浮点运算的,效率低。硬浮点是通过浮点运算单元(FPU)来完成的,效率高。

浮点运算器初始化函数是 halFpuInit,该函数的代码实现如下:

#include <SylixOS.h>
static VOID  halFpuInit (VOID)
{
    API_KernelFpuPrimaryInit(ARM_MACHINE_A7, ARM_FPU_NONE);
}

API_KernelFpuPrimaryInit 函数进行浮点运算器初始化。在该函数中,会调用 archFpuPrimaryInit 函数初始化 FPU 单元,此函数针对不同架构,有不同的实现。主要是针对不同的 FPU,初始化并获取 VFP 控制器操作函数集。

API_KernelFpuPrimaryInit 函数的原型如下:

#include <SylixOS.h>
VOID  API_KernelFpuPrimaryInit (CPCHAR  pcMachineName, CPCHAR  pcFpuName);

函数 API_KernelFpuPrimaryInit 原型分析:

  • 参数 pcMachineName 是处理器的名称。可选择的处理器如下表所示。
处理器架构处理器宏处理器名称
ARMARM_MACHINE_920920
ARMARM_MACHINE_926926
ARMARM_MACHINE_11361136
ARMARM_MACHINE_11761176
ARMARM_MACHINE_A5A5
ARMARM_MACHINE_A7A7
ARMARM_MACHINE_A8A8
ARMARM_MACHINE_A9A9
ARMARM_MACHINE_A15A15
ARMARM_MACHINE_A17A17
ARMARM_MACHINE_A53A53
ARMARM_MACHINE_A57A57
ARMARM_MACHINE_A72A72
ARMARM_MACHINE_A73A73
ARMARM_MACHINE_R4R4
ARMARM_MACHINE_R5R5
ARMARM_MACHINE_R7R7
MIPSMIPS_MACHINE_24KF24kf
MIPSMIPS_MACHINE_LS1Xloongson1x
MIPSMIPS_MACHINE_LS2Xloongson2x
MIPSMIPS_MACHINE_LS3Xloongson3x
MIPSMIPS_MACHINE_JZ47XXjz47xx
PPCPPC_MACHINE_603603
PPCPPC_MACHINE_EC603EC603
PPCPPC_MACHINE_604604
PPCPPC_MACHINE_750750
PPCPPC_MACHINE_MPC83XXMPC83XX
PPCPPC_MACHINE_E200E200
PPCPPC_MACHINE_E300E300
PPCPPC_MACHINE_E500E500
PPCPPC_MACHINE_E500V1E500V1
PPCPPC_MACHINE_E500V2E500V2
PPCPPC_MACHINE_E500MCE500MC
PPCPPC_MACHINE_E600E600
x86X86_MACHINE_PCx86
  • 参数 pcFpuName 是 FPU 的名称,可选择的 FPU 如下表所示。
处理器架构FPU 宏或变量FPU 名称
ARMARM_FPU_NONEnone
ARMARM_FPU_VFP9_D16vfp9-d16
ARMARM_FPU_VFP9_D32vfp9-d32
ARMARM_FPU_VFP11vfp11
ARMARM_FPU_VFPv3vfpv3
ARMARM_FPU_VFPv4vfpv4
ARMARM_FPU_NEONv3ARM_FPU_VFPv3
ARMARM_FPU_NEONv4ARM_FPU_VFPv4
MIPSMIPS_FPU_NONEnone
MIPSMIPS_FPU_VFP32vfp32
PPCPPC_FPU_NONEnone
PPCPPC_FPU_VFPvfp
PPCPPC_FPU_SPEspe
PPCPPC_FPU_ALTIVECaltivec
x86_G_bX86HasX87FPUx87 FPU

实时时钟初始化

实时时钟(RTC)的主要功能是在系统掉电的情况下,利用备用电源使时钟继续运行,保证不会丢失时间信息。系统启动时通过 halTimeInit 函数初始化目标电路板时间系统,该函数代码实现如下:

#include <SylixOS.h>
static VOID  halTimeInit (VOID)
{
    boardTimeInit();
}

在 halTimeInit 函数中,调用 boardTimeInit 函数初始化目标电路板时间系统。用户可以根据需要,实现对应开发板的初始化代码。现以 SylixOS-EVB-i.MX6Q 验证平台为例,该平台 BSP 的 boardTimeInit 函数代码实现如下:

#include <SylixOS.h>
VOID  boardTimeInit (VOID)
{
    PLW_RTC_FUNCS   pRtcFuncs;
    pRtcFuncs = rtcGetFuncs();
    rtcDrv();
    rtcDevCreate(pRtcFuncs);
    rtcToSys();
}

在 boardTimeInit 函数中,通过 rtcGetFuncs 函数获取 RTC 驱动硬件函数接口。

rtcDrv 宏定义的是 API_RtcDrvInstall 函数。该函数向内核注册了一组操作接口,包括设备打开、设备关闭、设备 I/O 控制接口,函数原型如下:

#include <SylixOS.h>
INT  API_RtcDrvInstall (VOID);

rtcDevCreate 宏定义的是 API_RtcDevCreate 函数。该函数建立一个 RTC 设备,并调用 RTC_pfuncInit 成员函数初始化硬件 RTC,函数原型如下:

#include <SylixOS.h>
INT  API_RtcDevCreate (PLW_RTC_FUNCS    prtcfuncs);

函数 API_RtcDevCreate 原型分析如下:

  • 该函数成功返回 ERROR_NONE
  • 参数 prtcfuncs 是rtc操作函数集。

rtcToSys 宏定义的是 API_RtcToSys 函数,该函数将RTC设备时间同步到系统时间,函数原型如下:

#include <SylixOS.h>
INT  API_RtcToSys (VOID);

MMU 全局内存映射表

内存管理单元(Memory Management Unit)简称 MMU,负责虚拟地址到物理地址的转换,并提供硬件机制的内存访问权限检查。MMU 全局内存映射表的初始化函数是 halVmmInit,该函数的代码实现如下:

#include <SylixOS.h>
static VOID  halVmmInit (VOID)
{
    API_VmmLibInit(_G_physicalDesc, _G_virtualDesc, ARM_MACHINE_A7);
    API_VmmMmuEnable();
}

API_VmmLibInit 宏定义的是 API_VmmLibPrimaryInit 函数,该函数初始化 VMM 系统,函数原型如下所示:

#include <SylixOS.h>
ULONG  API_VmmLibPrimaryInit (LW_MMU_PHYSICAL_DESC        pphydesc[], 
                              LW_MMU_VIRTUAL_DESC         pvirdes[],
                              CPCHAR                      pcMachineName);

函数 API_VmmLibPrimaryInit 原型分析:

  1. 此函数成功返回 ERROR_NONE
  2. 参数 pphydesc 是物理内存区描述表;
  3. 参数 pvirdes 是虚拟内存区描述表;
  4. 参数 pcMachineName 是 CPU 型号。

CACHE 初始化

在计算机系统中,CPU 的速度远远高于内存的速度,为了解决内存速度低下的问题,CPU 内部会放置一些 SRAM 用做 Cache(缓存),来提高 CPU 访问程序和数据的速度。Cache 的初始化函数是 halCacheInit,函数代码实现如下:

#include <SylixOS.h>
static VOID  halCacheInit (VOID)
{
    API_CacheLibInit(CACHE_COPYBACK, CACHE_COPYBACK, ARM_MACHINE_A7);
    API_CacheEnable(INSTRUCTION_CACHE);
    API_CacheEnable(DATA_CACHE);
}

该函数中,主要调用 API_CacheLibInit 初始化 Cache 系统,以及调用 API_CacheEnable 使能指令和数据 CACHE。

API_CacheLibPrimaryInit 功能是初始化 Cache 功能,CPU 构架相关,函数原型如下:

#include <SylixOS.h>
ULONG  API_CacheLibPrimaryInit (CACHE_MODE      uiInstruction, 
                                CACHE_MODE      uiData, 
                                CPCHAR          pcMachineName);

函数 API_CacheLibPrimaryInit 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 uiInstruction 是 Cache 模式,可参见表 CACHE 模式。
  • 参数 uiData 是数据 Cache 模式。可选择的模式与指令 Cache 一样。
  • 参数 pcMachineName 是CPU类型。支持的处理器可以参见上面表 支持的处理器。
Cache 模式说明
CACHE_COPYBACK回写模式
CACHE_WRITETHROUGH写通模式
CACHE_DISABLED旁路模式

API_CacheEnable 功能是使能指定类型的 Cache,函数原型如下:

#include <SylixOS.h>
INT  API_CacheEnable (LW_CACHE_TYPE  cachetype);

函数 API_CacheEnable 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 cachetype 指定Cache类型可参见下表。
Cache 类型说明
INSTRUCTION_CACHE指令 Cache
DATA_CACHE数据 Cache

内核 shell 系统初始化

内核 shell 系统初始化函数是 halShellInit,函数代码实现如下所示:

#include <SylixOS.h>
static VOID  halShellInit (VOID)
{
    API_TShellInit();
    zlibShellInit();
    viShellInit();
    gdbInit();
    gdbModuleInit();
}

在该函数中主要有以下操作:

API_TShellInit 函数安装 Tshell 程序,函数原型如下:

#include <SylixOS.h>
VOID  API_TShellInit (VOID);

zlibShellInit 函数用于初始化 zlib shell 接口,函数原型如下:

#include <SylixOS.h>
VOID  zlibShellInit (VOID);

viShellInit 函数用于初始化 vi shell 接口,函数原型如下:

#include <SylixOS.h>
VOID  viShellInit (VOID);

gdbInit 宏定义的是 API_GdbInit 函数,该函数的作用是注册 GDBServer 命令,函数原型如下:

#include <SylixOS.h>
VOID  API_GdbInit (VOID);

gdbModuleInit 宏定义的是 API_GdbModuleInit 函数。该函数的作用是注册 GDB module 命令,函数原型如下:

#include <SylixOS.h>
VOID  API_GdbModuleInit (VOID);

总线系统初始化

总线系统初始化函数是 halBusInit,该函数的代码实现如下所示:

#include <SylixOS.h>
static VOID  halBusInit (VOID)
{
    boardBusInit();
}

在该函数中,boardBusInit 函数用于初始化目标开发板总线系统。用户可以根据需要,实现对应开发板的初始化程序。现以 SylixOS-EVB-i.MX6Q 验证平台的 BSP 为例,代码实现如下:

#include <SylixOS.h>
VOID  boardBusInit (VOID)
{
    PLW_I2C_FUNCS    pI2cFuncs;
    PLW_SPI_FUNCS    pSpiFuncs;
    API_I2cLibInit();
    API_SpiLibInit();
    pI2cFuncs = i2cBusFuns(0);
    if (pI2cFuncs) {
        API_I2cAdapterCreate("/bus/i2c/0", pI2cFuncs, 10, 1);
    }
    pI2cFuncs = i2cBusFuns(1);
    if (pI2cFuncs) {
        API_I2cAdapterCreate("/bus/i2c/1", pI2cFuncs, 10, 1);
    }
    pI2cFuncs = i2cBusFuns(2);
    if (pI2cFuncs) {
        API_I2cAdapterCreate("/bus/i2c/2", pI2cFuncs, 10, 1);
    }
}

该函数调用 API_I2cLibInit 和 API_SpiLibInit 函数,初始化 I2C 和 SPI 组件库;调用 i2cBusFuns 函数初始化 I2C 总线并获取驱动程序;最后调用 API_I2cAdapterCreate 函数创建 I2C 适配器。初始化 I2C 总线并获取操作函数集:

#include <SylixOS.h>
PLW_I2C_FUNCS  i2cBusFuns (UINT  uiChannel);

函数 i2cBusFuns 原型分析:

  • 此函数返回总线操作函数集。
  • 参数 uiChannel 是通道号。

创建一个 I2C 适配器

#include <SylixOS.h>
INT  API_I2cAdapterCreate (CPCHAR               pcName, 
                           PLW_I2C_FUNCS        pi2cfunc,
                           ULONG                ulTimeout,
                           INT                  iRetry);

函数 API_I2cAdapterCreate 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 pcName 是适配器名称。
  • 参数 pi2cfunc 是操作函数组,可通过 i2cBusFuns 函数获得。
  • 参数 ulTimeout 是操作超时时间(ticks)。
  • 参数 iRetry 是重试次数。

驱动程序初始化

系统启动时通过 halDrvInit 函数初始化目标系统静态驱动程序,代码实现如下:

#include <SylixOS.h>
static VOID  halDrvInit (VOID)
{
    rootFsDrv();
    procFsDrv();
    shmDrv();
    randDrv();
    ptyDrv();
    ttyDrv();
    memDrv();
    pipeDrv();
    spipeDrv();
    fatFsDrv();
    tpsFsDrv();
    ramFsDrv();
    romFsDrv();
    nfsDrv();
    yaffsDrv();
    canDrv();
}

在初始化标准设备驱动之前,需要安装 rootfs 和 procfs。halDrvInit 函数中都是宏操作,该函数内的初始化操作主要是向内核注册了操作接口。用户可以根据需要,在该函数中添加自己的驱动初始化程序,函数说明如下表所示:

宏定义的函数说明
rootFsDrvAPI_RootFsDrvInstall安装 rootfs 文件系统驱动程序
procFsDrvAPI_ProcFsDrvInstall安装 procfs 文件系统驱动程序
shmDrvAPI_ShmDrvInstall安装共享内存驱动程序
randDrvAPI_RandDrvInstall安装随机数发生器设备驱动程序
ptyDrvAPI_PtyDrvInstall安装 PTY 设备驱动程序
ttyDrvAPI_TtyDrvInstall安装 TTY 设备驱动程序
memDrvAPI_MemDrvInstall安装内存设备驱动程序
pipeDrvAPI_PipeDrvInstall安装管道设备驱动程序
spipeDrvAPI_SpipeDrvInstall安装字符流管道设备驱动程序
tpsFsDrvAPI_TpsFsDrvInstall安装 TPS 文件系统驱动程序
fatFsDrvAPI_FatFsDrvInstall安装 FAT 文件系统驱动程序
ramFsDrvAPI_RamFsDrvInstall安装 ramfs 文件系统驱动程序
romFsDrvAPI_RomFsDrvInstall安装 romfs 文件系统驱动程序
nfsDrvAPI_NfsDrvInstall安装 NFS 文件系统驱动程序
yaffsDrvAPI_YaffsDrvInstall安装 yaffs 文件系统驱动程序
canDrvAPI_CanDrvInstall安装 can 驱动程序

创建设备

系统启动时通过 halDevInit 函数初始化目标系统静态设备组件,该函数中的代码实现如下:

#include <SylixOS.h>
static VOID  halDevInit (VOID)
{
    rootFsDevCreate();
    procFsDevCreate();
    shmDevCreate();
    randDevCreate();
    SIO_CHAN    *psio0 = sioChanCreate(0);
    ttyDevCreate("/dev/ttyS0", psio0, 30, 50); 
    boardDevInit();
    yaffsDevCreate("/yaffs2");
}

用户可以根据需要,在该函数中创建设备。该函数中主要做了如下操作:

rootFsDevCreate 宏定义的是 API_RootFsDevCreate 函数,该函数创建根文件系统,函数原型如下:

#include <SylixOS.h>
INT  API_RootFsDevCreate (VOID);

procFsDevCreate 宏定义的是 API_ProcFsDevCreate 函数,该函数创建 proc 文件系统,函数原型如下:

#include <SylixOS.h>
INT  API_ProcFsDevCreate (VOID);

shmDevCreate 宏定义的是 API_ShmDevCreate 函数,该函数创建共享内存设备,函数原型如下:

#include <SylixOS.h>
INT  API_ShmDevCreate (VOID);

randDevCreate 宏定义的是 API_RandDevCreate 函数,该函数创建随机数文件,函数原型如下:

#include <SylixOS.h>
INT  API_RandDevCreate (VOID);

sioChanCreate 函数用于创建串口 0 通道,函数原型如下:

#include <SylixOS.h>
SIO_CHAN  *sioChanCreate (INT  iChannelNum);

函数 sioChanCreate 原型分析:

  • 此函数成功返回 SIO 通道。
  • 参数 iChannelNum 是硬件通道号。

ttyDevCreate 宏定义的是 API_TtyDevCreate 函数,该函数用于添加 TTY 设备,函数原型如下:

#include <SylixOS.h>
INT  API_TtyDevCreate (PCHAR         pcName,
                       SIO_CHAN    *psiochan,
                       size_t         stRdBufSize,
                       size_t         stWrtBufSize)

函数 API_TtyDevCreate 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 pcName 是设备名。
  • 参数 psiochan 是同步 I/O 函数集。
  • 参数 stRdBufSize 是输入缓冲区大小。
  • 参数 stWrtBufSize 是输出缓冲区大小。

7.yaffsDevCreate 宏定义的是 API_YaffsDevCreate 函数,该函数创建 YAFFS 设备,函数原型如下:

#include <SylixOS.h>
LW_API INT  API_YaffsDevCreate(PCHAR   pcName);

函数 API_YaffsDevCreate 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 pcName 是设备名(设备挂接的节点地址)。

创建内核标准文件描述符

系统启动时通过 halStdFileInit 函数初始化目标系统标准文件描述符,函数代码实现如下:

#include <SylixOS.h>
static VOID  halStdFileInit (VOID)
{
    int     iFd = open("/dev/ttyS0", O_RDWR, 0);
    if (iFd >= 0) {
        ioctl(iFd, FIOBAUDRATE,   SIO_BAUD_115200);
        ioctl(iFd, FIOSETOPTIONS, (OPT_TERMINAL & (~OPT_7_BIT)));
        ioGlobalStdSet(STD_IN,  iFd);
        ioGlobalStdSet(STD_OUT, iFd);
        ioGlobalStdSet(STD_ERR, iFd);
    }
}

内核标准文件描述符有三种,具体参见下表。在 halStdFileInit 函数中,将这三个标准文件描述符定向到串口设备/dev/ttyS0。

标准文件描述符说明
STD_IN标准输入
STD_OUT标准输出
STD_ERR标准错误

日志系统初始化

日志系统将系统运行的每一个状况信息都使用文字记录下来,这些信息有助于观察系统运行过程中正常状态和系统运行错误时快速定位错误位置的途径等。

系统启动时通过 halLogInit 函数初始化目标系统日志系统。代码实现如下所示:

#include <SylixOS.h>
static VOID  halLogInit (VOID)
{
    fd_set      fdLog;
    FD_ZERO(&fdLog);
    FD_SET(STD_OUT, &fdLog);
    API_LogFdSet(STD_OUT + 1, &fdLog);
}

该函数中主要调用 API_LogFdSet 函数初始化日志系统。API_LogFdSet 函数首先设置 LOG 需要关心的文件集,然后启动内核打印线程。函数原型如下所示:

#include <SylixOS.h>
INT  API_LogFdSet (INT  iWidth, fd_set  *pfdsetLog);

函数 API_LogFdSet 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 iWidth 是最大的文件描述符加一,类似 select()第一个参数。
  • 参数 pfdsetLog 是新的文件集。

在日志系统中,使用消息队列来传递信息。当内核打印线程从消息队列中读取到数据时,就向文件集中的所有对象输出信息。消息的来源为 API_LogPrintk 函数和 API_logMsg 函数。

挂载磁盘系统

用户可以根据需要,在 halBootThread 函数中挂载对应的磁盘系统。现以 mini2440 的 SylixOS BSP 为例,代码片段如下:

#ifdef __GNUC__
    nand_init();
    mtdDevCreateEx("/n");
#else
    nandDevCreateEx("/n");
#endif

nandInit 函数初始化 NandFlash 驱动,函数原型如下:

#include <SylixOS.h>
VOID nandInit (VOID);

mtdDevCreateEx 函数用来挂载文件系统。该函数中,会首先初始化 boot 分区 YAFFS 设备结构体以及 common 分区 YAFFS 设备结构体,然后调用 yaffs_add_device 函数,将这两个对象添加到 YAFFS 设备表,执行 yaffs_mount 命令进行挂载。函数原型如下:

#include <SylixOS.h>
int  mtdDevCreateEx (char  *pcDevName);

函数 mtdDevCreateEx 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 pcDevName 是设备名。

创建根文件系统目录

系统启动时通过 halStdDirInit 函数创建根文件系统目录,目录的权限为文件夹默认权限(754)。需要创建的目录如下表所示:

目录SD 或 eMMC 符号链接路径NAND FLASH 符号链接路径说明
/usb通常用于挂载 USB 设备
/boot/media/sdcard0/yaffs2/n0/boot引导程序文件,例如:BSP;时常是一个单独的分区
/etc/media/sdcard1/etc/yaffs2/n0/etc系统主要的设定档几乎都放置在这个目录内,例如环境变量配置文件 profile、网络配置文件 ifparam.ini、系统启动脚本 startup.sh
/ftk/media/sdcard1/ftk/yaffs2/n1/ftkFTK 图形系统
/qt/media/sdcard1/qt/yaffs2/n1/qtQt 图形系统
/lib/media/sdcard1/lib/yaffs2/n1/lib/bin/和/sbin/中二进制文件必要的库文件。对于 NAND Flash 还会创建/yaffs2/n1/lib/modules 文件夹
/usr/media/sdcard1/usr/yaffs2/n1/usr默认软件都会存于该目录下。用于存储只读用户数据的第二层次;包含绝大多数的用户工具和应用程序。对于 NAND Flash 还会创建/yaffs2/n1/usr/lib 文件夹
/bin/media/sdcard1/bin/yaffs2/n1/bin需要在单用户模式可用的必要命令(可执行文件);面向所有用户,例如:cat、ls、cp,和/usr/bin 类似
/sbin/media/sdcard1/sbin/yaffs2/n1/sbin必要的系统二进制文件
/apps/media/sdcard1/apps/yaffs2/n1/apps用户应用程序
/home/media/sdcard1/home/yaffs2/n1/home用户的家目录,包含保存的文件、个人设置等
/root/media/sdcard1/root/yaffs2/n1/root超级用户的家目录
/var/media/sdcard1/var/yaffs2/n1/var变量文件,即在正常运行的系统中其内容不断变化的文件,如日志,脱机文件和临时电子邮件文件
/tmp/var/tmp/yaffs2/n1/tmp临时文件,在系统重启时目录中文件不会被保留

sdcard0 和 sdcard1 分别为 SD 或 eMMC 的两个分区,其中 sdcard0 通常为 FAT32 文件系统,作为启动分区;sdcard1 通常为 TpsFs 文件系统。n0 和 n1 为 NAND 的两个分区,均为 YAFFS 文件系统。

配置系统环境

系统环境的配置包括环境变量的配置、设置时区和设置 rootfs 时间基准,下面分别介绍。

环境变量的配置

环境变量(environment variables)是指在操作系统中用来指定操作系统运行环境的参数,如:临时文件夹位置和系统文件夹位置等。SylixOS 初始环境变量如下表所示:

数据传输标志含义
SYSTEM系统打印信息
VERSION版本信息
LICENSE许可信息
TMPDIR临时文件夹
TZ时区
KEYBOARD键盘
MOUSE鼠标
TSLIB_TSDEVICE触摸屏校准关联设备
TSLIB_CALIBFILE触摸屏校准文件
SO_MEM_PAGES动态内存虚拟页面数量
FIO_FLOATfio 浮点支持
SYSLOGD_HOSTsyslog 服务器地址
NFS_CLIENT_AUTHNFS 默认使用 auth_unix
NFS_CLIENT_PROTONFS 默认使用 udp 协议
PATHPATH 启动时默认路径
LD_LIBRARY_PATHLD_LIBRARY_PATH 默认值
LANG多国语言与编码
LC_ALL多国语言与编码
PATH_LOCALE多国语言与编码
DEBUG_CPU是否将被调对象锁定到一个 CPU
LOGINBL_TO网络登录黑名单刷新时间
LOGINBL_REP连续出现几次则加入黑名单
LUA_PATHLUA 环境
LUA_CPATHLUA 环境
TERM终端
TERMCAP终端

内核 shell 系统初始化时,halShellInit 中的 API_TShellInit 函数会初始化系统环境变量。函数原型如下所示:

#include <SylixOS.h>
VOID  API_TShellInit (VOID);

在 halBootThread 函数中会调用 system("varload")指令,从/etc/profile 中读取环境变量。

设置时区

环境变量配置完成后,会调用 lib_tzset 函数,该函数通过环境变量中的 TZ 设置时区。在 lib_tzset 函数中,如果获取 TZ 环境变量失败,则使用默认时区信息,为中国标准时间。该函数原型如下所示:

#include <SylixOS.h>
VOID  lib_tzset (VOID);

设置 rootfs 时间基准

rtcToRoot 宏定义的是 API_RtcToRoot 函数,该函数用于设置当前 RTC 时间为根文件系统基准时间。此函数成功返回 ERROR_NONE 。函数原型如下所示:

#include <SylixOS.h>
INT  API_RtcToRoot (VOID);

网络系统初始化

系统启动时通过 halNetInit 和 halNetifAttch 函数初始化网络系统。网络初始化一般放在 shell 初始化之后,因为初始化网络组件时,会自动注册 shell 命令。

halNetInit 函数主要是初始化网络组件,函数代码实现如下:

#include <SylixOS.h>
static VOID  halNetInit (VOID)
{
    API_NetInit();
    API_NetSnmpInit();
#if LW_CFG_NET_PING_EN > 0
    API_INetPingInit();
    API_INetPing6Init();
#endif
#if LW_CFG_NET_NETBIOS_EN > 0
    API_INetNetBiosInit();
    API_INetNetBiosNameSet("sylixos");
#endif
#if LW_CFG_NET_TFTP_EN > 0
    API_INetTftpServerInit("/tmp");
#endif
#if LW_CFG_NET_FTPD_EN > 0
    API_INetFtpServerInit("/");
#endif
#if LW_CFG_NET_TELNET_EN > 0
    API_INetTelnetInit(LW_NULL);
#endif
#if LW_CFG_NET_NAT_EN > 0
    API_INetNatInit();
#endif
#if LW_CFG_NET_NPF_EN > 0
    API_INetNpfInit();
#endif
#if LW_CFG_NET_VPN_EN > 0
    API_INetVpnInit();
#endif
}

函数中的主要操作如下:

API_NetInit 函数:向操作系统内核注册网络组件,函数原型如下:

#include <SylixOS.h>
VOID  API_NetInit (VOID);

API_INetPingInit 函数:初始化 ping 工具,函数原型如下:

#include <SylixOS.h>
VOID  API_INetPingInit (VOID);

API_INetPing6Init 函数:初始化 Ipv6 ping 工具,函数原型如下:

#include <SylixOS.h>
VOID  API_INetPing6Init (VOID);

API_INetNetBiosInit 和 API_INetNetBiosNameSet 函数:初始化 lwip netbios 简易名字服务器,函数原型如下:

#include <SylixOS.h>
VOID   API_INetNetBiosInit (VOID);
ULONG  API_INetNetBiosNameSet (CPCHAR  pcLocalName);

函数 API_INetNetBiosNameSet 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 pcLocalName 是名称。

API_INetTftpServerInit 函数:初始化 tftp 服务器,函数原型如下:

#include <SylixOS.h>
VOID  API_INetTftpServerInit (CPCHAR  pcPath);

函数 API_INetTftpServerInit 原型分析:

  • 参数 pcPath 是本地目录。

API_INetFtpServerInit 函数:初始化 tftp 服务器根目录,函数原型如下:

#include <SylixOS.h>
VOID  API_INetFtpServerInit (CPCHAR  pcPath);

函数 API_INetFtpServerInit 原型分析:

  • 参数 pcPath 是本地目录。

API_INetTelnetInit 函数:初始化 telnet 工具,函数原型如下:

#include <SylixOS.h>
VOID  API_INetTelnetInit (const PCHAR  pcPtyStartName);

函数 API_INetFtpServerInit 原型分析:

  • 参数 pcPtyStartName 是 pty 起始文件名。

API_INetNatInit 函数:internet NAT 初始化,函数原型如下:

#include <SylixOS.h>
VOID  API_INetNatInit (VOID);

API_INetNpfInit 函数:net packet filter 初始化,函数原型如下:

#include <SylixOS.h>
INT  API_INetNpfInit (VOID);

函数 API_INetNpfInit 原型分析:

  • 此函数成功返回 ERROR_NONE

API_INetVpnInit 函数:初始化VPN服务,函数原型如下:

#include <SylixOS.h>
VOID  API_INetVpnInit (VOID);

POSIX 兼容系统初始化

POSIX 子系统的初始化函数是 halPosixInit。如果系统支持 proc 文件系统,则必须放在 proc 文件系统安装之后。halPosixInit 函数的代码实现如下:

#include <SylixOS.h>
static VOID  halPosixInit (VOID)
{
    API_PosixInit();
}

该函数中调用 API_PosixInit 函数初始化 posix 系统,函数原型如下:

#include <SylixOS.h>
VOID  API_PosixInit (VOID);

内核符号系统初始化

驱动也是存在于内核空间的,它的每一个函数每一个变量都会有对应的符号,这部分符号也可以称作内核符号,它们不导出就只能为自身所用,导出后就可以成为公用,对于导出的那部分内核符号就是常说的内核符号表。

halSymbolInit 函数初始化目标系统符号表环境,为模块加载提供环境。halSymbolInit 函数代码实现如下:

#include <SylixOS.h>
static VOID  halSymbolInit (VOID)
{
#ifdef __GNUC__
    void *__aeabi_read_tp();
#endif
    API_SymbolInit();
#ifdef __GNUC__
    symbolAddAll();
    API_SymbolAdd("__aeabi_read_tp", (caddr_t)__aeabi_read_tp, 
                LW_SYMBOL_FLAG_XEN);
    API_SymbolAdd("lcdDevInit", (caddr_t)lcdDevInit, LW_SYMBOL_FLAG_REN);
    API_SymbolAdd("boardGpioCheck", (caddr_t)boardGpioCheck, 
                LW_SYMBOL_FLAG_REN);
    API_SymbolAdd("sysClockGet", (caddr_t)sysClockGet, LW_SYMBOL_FLAG_REN);
#endif
}

函数中的主要操作如下:

API_SymbolInit 函数:初始化系统符号表,函数原型如下:

#include <SylixOS.h>
VOID  API_SymbolInit (VOID);

symbolAddAll 函数:将系统的所有 API 导入到符号表中,供模块装载器使用,函数原型如下:

#include <SylixOS.h>
static LW_INLINE  INT symbolAddAll (VOID);

API_SymbolAdd 函数:向符号表添加一个符号,函数原型如下:

#include <SylixOS.h>
INT  API_SymbolAdd (CPCHAR  pcName, caddr_t  pcAddr, INT  iFlag);

函数 API_SymbolAdd 原型分析:

  • 此函数成功返回 ERROR_NONE
  • 参数 pcName 是符号名。
  • 参数 pcAddr 是地址。
  • 参数 iFlag 参数是符号类型,可参见下表。
符号类型说明
LW_SYMBOL_FLAG_STATIC不能删除的静态符号
LW_SYMBOL_FLAG_REN可读符号
LW_SYMBOL_FLAG_WEN可写符号
LW_SYMBOL_FLAG_XEN可执行符号

内核装载器初始化

系统启动时通过 halLoaderInit 函数初始化目标系统程序或模块装载器,函数的代码实现如下:

#include <SylixOS.h>
static VOID  halLoaderInit (VOID)
{
    API_LoaderInit();
}

该函数调用 API_LoaderInit 函数初始化 loader 组件。主要是安装符号表查询的回调函数、安装 I/O 系统回调组和系统重启回调函数、以及初始化 loader 内部 shell 命令。函数原型如下:

#include <SylixOS.h>
VOID  API_LoaderInit (VOID);

内核跟踪器初始化

SylixOS 提供了内核跟踪的功能,通过该功能上层应用程序可以很方面地监视到内核的运行情况(例如:中断信息、信号量信息,文件操作信息等),以下函数为跟踪器创建一个跟踪通道:

static VOID  halMonitorInit (VOID)
{
}

注意
SylixOS 支持普通文件与网络两种跟踪通道,也可以通过“monitor”命令启动跟踪器,需要注意的是,需要配置 LW_CFG_MONITOR_EN 宏来启用内核跟踪器功能。

执行系统启动脚本

系统启动时通过执行 system("shfile /etc/startup.sh")指令,执行系统启动脚本 startup.sh。该指令必须在 shell 初始化后调用。

用户可以通过该启动脚本,设置开机自启动。编辑“/etc/startup.sh”,把启动程序的 shell 命令输入进去即可,类似于 windows 下的“启动”。

启动系统内核主线程

在 BSP 的初始化工作完成后,会创建并启动 t_main 线程,即系统内核主线程。t_main 的代码实现如下:

#include <SylixOS.h>
int  t_main (void)
{
    struct utsname  name;
    uname(&name);
    printf("sysname  : %s\n", name.sysname);
    printf("nodename : %s\n", name.nodename);
    printf("release  : %s\n", name.release);
    printf("version  : %s\n", name.version);
    printf("machine  : %s\n", name.machine);
    Lw_TShell_Create(STDOUT_FILENO, LW_OPTION_TSHELL_PROMPT_FULL | LW_OPTION_TSHELL_VT100);
    return  (0);
}

在该函数中,通过调用 uname 函数,获取当前系统的信息。在输出这些信息后,会调用 Lw_TShell_Create 来创建一个 ttiny shell 系统。Lw_TShell_Create 宏定义的是 API_TShellCreate 函数,函数原型如下:

#include<SylixOS.h>
LW_OBJECT_HANDLE  API_TShellCreate (INT  iTtyFd, ULONG  ulOption)

函数 API_TShellCreate 原型分析:

  • 该函数返回 shell 线程的句柄。
  • 参数 iTtyFd 是终端设备的文件描述符。在 BSP 中传的参数是 STDOUT_FILENO ,该宏是标准输出描述符。
  • 参数 ulOption 是启动参数。具体参见下表。
启动参数说明
LW_OPTION_TSHELL_VT100使用 VT100 终端控制字符
LW_OPTION_TSHELL_AUTHEN使用用户认证
LW_OPTION_TSHELL_NOLOGO是否不显示 logo
LW_OPTION_TSHELL_NOECHO无回显
LW_OPTION_TSHELL_PROMPT_FULL全部显示命令提示符
LW_OPTION_TSHELL_CLOSE_FDshell 退出时关闭 fd
文档内容是否对您有所帮助?
有帮助
没帮助