从 VxWorks 到 SylixOS
VxWorks 也是一款符合 POSIX 标准的实时操作系统(这一点同 SylixOS 完全相同),因此对于 POSIX 应用程序开发两款操作系统没有太大的区别,基本可以完全兼容(SylixOS 对 POSIX 标准的兼容度要高于 VxWorks),另外 SylixOS 为了使 VxWorks 开发者能够更快地适应 SylixOS 的程序开发,提供了 VxWorks 兼容接口,以下是 SylixOS 日志系统中的 API 示例。
#include <SylixOS.h>
INT logFdSet(INT iWidth, fd_set *pfdsetLog);
INT logFdGet(INT *piWidth, fd_ser *pfdsetLog);
开发 VxWorks 应用
RealEvo-IDE 为 VxWorks 程序开发提供了兼容库,这使得 SylixOS 在代码上与 VxWorks 实现了完全兼容(下图是 SylixOS 对 VxWorks 支持的兼容库文件)。
以下过程描述了,如何使用 RealEvo-IDE 开发 VxWorks 程序:
创建 SylixOS Base 工程
打开 RealEvo-IDE,创建新的 SylixOS base 工程(创建过程见“创建 SylixOS Base 工程”),需要注意的是,默认库选择对话框,需要选择 libVxWorks 兼容库(VxWorks 应用程序依赖该库),最后点击“Finish”完成工程创建,如下图所示。
创建完成的 SylixOS base 工程目录包含了:libcextern(标准 C 库)、libsylixos(SylixOS 内核库)、libVxWorks(VxWorks 程序兼容库)等,如下图所示。
编译 SylixOS base 工程,编程成功后,将在 libVxWorks/Debug 下生成 libVxWorks/.so 文件,此文件即为 VxWorks 应用程序在 SylixOS 下运行时需要链接的动态库。libVxWorks 目录结构如下图所示。
创建 VxWorks 应用程序
创建 VxWorks 应用程序工程(见“创建 Hello world 工程”节),创建完成后,需要对工程的目标 Makefile(*.mk)文件进行修改,如下图所示:
- LOCAL_INC_PATH:包含头文件目录,增加 libVxWorks 头文件路径。
- LOCAL_DEPEND_LIB:包含依赖的动态库,增加 VxWorks 动态库。
- LOCAL_DEPEND_LIB_PATH:包含依赖的动态库路径,增加 VxWorks 动态库路径。
下面程序展示了 VxWorks 中二进制信号量的使用,该程序通过调用 taskSpawn 函数来创建两个任务,任务 A 中 Take 信号量 1(semId1),之后 Give 信号量 2(semId2)任务 B 开始运行并 Give 信号量 1(semId1),这样实现了任务 A 和任务 B 的同步。
#include <vxWorks.h>
#include <taskLib.h>
#include <semLib.h>
#include <stdio.h>
#define TASK_PRI (98) /* 任务优先级 */
#define TASK_STACK_SIZE (5000) /* 任务栈大小 */
LOCAL SEM_ID semId1; /* 二进制信号量 1 */
LOCAL SEM_ID semId2; /* 二进制信号量 2 */
LOCAL BOOL flag;
LOCAL int num = 4;
LOCAL STATUS taskA()
{
int i;
for (i = 0; i < num; i++) {
if (semTake(semId1, WAIT_FOREVER) == ERROR) {
perror("taskA: semTake");
return (ERROR);
}
printf("[done-%d]taskA: Releasing semId2 [taskB process]\n", i + 1);
if (semGive(semId2) == ERROR) {
perror("taskA: semGive");
return (ERROR);
}
}
return (OK);
}
LOCAL STATUS taskB()
{
int i;
for (i = 0; i < num; i++) {
if (semTake(semId2, WAIT_FOREVER) == ERROR) {
perror("taskB: semTake");
return (ERROR);
}
printf("[done-%d]taskB: Releasing semId1 [taskA process]\n", i + 1);
if (semGive(semId1) == ERROR) {
perror("taskB: semGive");
return (ERROR);
}
}
flag = FALSE;
return (OK);
}
STATUS synch ()
{
flag = TRUE;
if ((semId1 = semBCreate(SEM_Q_PRIORITY, SEM_FULL)) == (SEM_ID)NULL) {
perror("synch: semBCreate");
return (ERROR);
}
if ((semId2 = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)) == (SEM_ID)NULL) {
perror("synch: semBCreate");
return (ERROR);
}
if (taskSpawn("tTaskA", TASK_PRI, 0, TASK_STACK_SIZE, (FUNCPTR)taskA, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0) == ERROR) {
perror("synch: taskSpawn");
return (ERROR);
}
if (taskSpawn("tTaskB", TASK_PRI, 0, TASK_STACK_SIZE, (FUNCPTR)taskB, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0) == ERROR) {
perror("synch: taskSpawn");
return (ERROR);
}
while (flag)
taskDelay(sysClkRateGet());
if (semDelete(semId1) == ERROR) {
perror("synch: semDelete");
return (ERROR);
}
if (semDelete(semId2) == ERROR) {
perror("synch: semDelete");
return (ERROR);
}
printf("synch now completed.\n");
return (OK);
}
int main(int argc, char * argv[])
{
synch ();
return (OK);
}
在 SylixOS Shell 下运行程序,结果如下:
# ./vxworks_test
VxWork compatibility library enter.
[done-1]taskA: Releasing semId2 [taskB process]
[done-1]taskB: Releasing semId1 [taskA process]
[done-2]taskA: Releasing semId2 [taskB process]
[done-2]taskB: Releasing semId1 [taskA process]
[done-3]taskA: Releasing semId2 [taskB process]
[done-3]taskB: Releasing semId1 [taskA process]
[done-4]taskA: Releasing semId2 [taskB process]
[done-4]taskB: Releasing semId1 [taskA process]
synch now completed.
VxWork compatibility library exit.
从运行结果可以看出 VxWorks 的应用程序,无需任何修改即可在 SylixOS 下正常运行。并
且运行结果与程序预期(任务 A 与任务 B 运行同步)的相同。