NuttX的学习笔记 8

来源:互联网 发布:推广软件拦截 编辑:程序博客网 时间:2024/04/30 06:52

好了,新开一篇继续新的内容

      • Task Scheduling Interfaces
        • sched_setparam
        • sched_getparam
        • sched_setscheduler
        • sched_getscheduler
        • sched_yield
        • sched_get_priority_max
        • sched_get_priority_min
        • sched_get_rr_interval
      • 任务调度的接口实验

Task Scheduling Interfaces

任务调度接口

By default, NuttX performs strict priority scheduling: Tasks of higher priority have exclusive access to the CPU until they become blocked. At that time, the CPU is available to tasks of lower priority. Tasks of equal priority are scheduled FIFO.

默认情况下,NuttX执行严格的优先级调度:更高优先级的任务独占访问CPU,直到他们变得阻塞。当时,可用CPU低优先级的任务。相同优先级的任务计划FIFO。

Optionally, a Nuttx task or thread can be configured with round-robin or sporadic scheduler. The round-roben is similar to priority scheduling except that tasks with equal priority and share CPU time via time-slicing. The time-slice interval is a constant determined by the configuration setting CONFIG_RR_INTERVAL to a positive, non-zero value. Sporadic scheduling scheduling is more complex, varying the priority of a thread over a replenishment period. Support for sporadic scheduling is enabled by the configuration option CONFIG_SCHED_SPORADIC.

可选的Nuttx任务或线程可以配置循环或零星的调度器。round-roben类似于优先级调度,除了任务同等优先级和通过次共享CPU时间。分配间隔设置的配置是一个常数由CONFIG_RR_INTERVAL积极,非零值。零星的调度调度更加复杂,不同的优先级线程补充一段。支持配置选项CONFIG_SCHED_SPORADIC启用了零星的调度。

首先,在-> RTOS Features -> Tasks and Scheduling中启用 Support sporadic scheduling 而参数CONFIG_RR_INTERVAL 只要调整Round robin timeslice (MSEC) 即可。

sched_setparam

int sched_setparam(pid_t pid, const struct sched_param *param);

这个函数使用pid设置指定任务的调度优先级。

sched_getparam

int sched_getparam (pid_t pid, struct sched_param *param);

这个函数使用pid获取指定任务的调度优先级。

sched_setscheduler

int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param);

sched_setscheduler()通过pid确定任务并设置调度策略和任务的优先级。如果pid等于零,调用线程的调度程序将参数参数。持有新策略下的线程的优先级。

sched_getscheduler

int sched_getscheduler (pid_t pid);

sched_setscheduler()通过pid确定任务并获取调度策略。

sched_yield

int sched_yield(void);

调用这个函数将使任务让出CPU。

sched_get_priority_max

int sched_get_priority_max (int policy);
调用这个函数将返回 指定的使特殊调度策略 的最高可能的任务优先级。

sched_get_priority_min

int sched_get_priority_min (int policy);
与上面的相反,上面的是获取最大,这个是获取最小。

sched_get_rr_interval

int sched_get_rr_interval (pid_t pid, struct timespec *interval);
sched_rr_get_interval()将获取确定pid任务的时间片间隔并写入由 interval 指针传入的时间片结构体中。

任务调度的接口实验

前两个函数接口可以一起调试,将已创建任务的任务优先级往下调。并查询其值。这里先要说一下这个测试代码:

#include <nuttx/config.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#define CONFIG_EXAMPLES_HELLO_TASK_PRIORITY  SCHED_PRIORITY_DEFAULT#define CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE 2048int print_hello(int argc, char *argv[]) {    long int i;    printf("%s: pid = %d \n", argv[0], getpid());    for (i = 0; i < 20; ++i) {        printf("%d\n", i);    }    exit(EXIT_SUCCESS);}int hello_task_main(int argc, char *argv[]) {    int ret;    /* Started print_hello */    pid_t print_hello_pid;    print_hello_pid = task_create("print_hello",    CONFIG_EXAMPLES_HELLO_TASK_PRIORITY,    CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE, print_hello, &argv[1]);    if (print_hello_pid < 0) {        int errcode = errno;        printf("%s: ERROR: Failed to start print_hello: %d\n", argv[0],                errcode);        return EXIT_FAILURE;    } else        printf("%s: Started print_hello at PID=%d\n", argv[0], print_hello_pid);    /* print print_hello sched_param  */    struct sched_param print_hello_sched_param;    ret = sched_getparam(print_hello_pid, &print_hello_sched_param);    if (ret == 0) {        printf("%s: Get print_hello priority success\n", argv[0]);        printf("print_hello_sched_param:\n  sched_priority: %d\n",                print_hello_sched_param.sched_priority);        printf("  sched_ss_low_priority: %d\n",                print_hello_sched_param.sched_ss_low_priority);        printf("  sched_ss_repl_period:\n    tv_sec: %d\n",                print_hello_sched_param.sched_ss_repl_period.tv_sec);        printf("    tv_nsec: %d\n",                print_hello_sched_param.sched_ss_repl_period.tv_nsec);        printf("  sched_ss_init_budget:\n    tv_sec: %d\n",                print_hello_sched_param.sched_ss_init_budget.tv_sec);        printf("    tv_nsec: %d\n  sched_ss_max_repl: %d\n",                print_hello_sched_param.sched_ss_init_budget.tv_nsec,                print_hello_sched_param.sched_ss_max_repl);    } else {        printf("%s: ERROR: Failed to get print_hello priority\n", argv[0]);        exit(EXIT_FAILURE);    }    /* Set print_hello priority to 50  */    print_hello_sched_param.sched_priority = 50;    ret = sched_setparam(print_hello_pid, &print_hello_sched_param);    if (ret == 0) {        printf("%s: Set print_hello priority to 50\n", argv[0]);    } else {        printf("%s: ERROR: Failed to set print_hello priority to 50\n",                argv[0]);        int errcode = errno;        switch (errcode) {        case EINVAL:            printf("sched_setparam: %s\n", EINVAL_STR);            break;        case EPERM:            printf("sched_setparam: %s\n", EPERM_STR);            break;        case ESRCH:            printf("sched_setparam: %s\n", ESRCH_STR);            break;        default:            break;        }        exit(EXIT_FAILURE);    }    /* print print_hello sched_param  */    ret = sched_getparam(print_hello_pid, &print_hello_sched_param);    if (ret == 0) {        printf("%s: Get print_hello priority success\n", argv[0]);        printf("print_hello_sched_param:\n  sched_priority: %d\n",                print_hello_sched_param.sched_priority);        printf("  sched_ss_low_priority: %d\n",                print_hello_sched_param.sched_ss_low_priority);        printf("  sched_ss_repl_period:\n    tv_sec: %d\n",                print_hello_sched_param.sched_ss_repl_period.tv_sec);        printf("    tv_nsec: %d\n",                print_hello_sched_param.sched_ss_repl_period.tv_nsec);        printf("  sched_ss_init_budget:\n    tv_sec: %d\n",                print_hello_sched_param.sched_ss_init_budget.tv_sec);        printf("    tv_nsec: %d\n  sched_ss_max_repl: %d\n",                print_hello_sched_param.sched_ss_init_budget.tv_nsec,                print_hello_sched_param.sched_ss_max_repl);    } else {        printf("%s: ERROR: Failed to get print_hello priority\n", argv[0]);        exit(EXIT_FAILURE);    }    exit(EXIT_SUCCESS);    return EXIT_SUCCESS;}

因为里面还掺着 print_hello 的输出,将其去掉,运行结果,:

nsh> hello_taskhello_task: Started print_hello at PID=3hello_task: Get print_hello priority successprint_hello_sched_param:  sched_priority: 100  sched_ss_low_priority: 0  sched_ss_repl_period:    tv_sec: 0    tv_nsec: 0  sched_ss_init_budget:    tv_sec: 0    tv_nsec: 0print_hello: pid = 3   sched_ss_max_repl: 0hello_task: Set print_hello priority to 50hello_task: Get print_hello priority successprint_hello_sched_param:  sched_priority: 50  sched_ss_low_priority: 0  sched_ss_repl_period:    tv_sec: 0    tv_nsec: 0  sched_ss_init_budget:    tv_sec: 0    tv_nsec: 0  sched_ss_max_repl: 0nsh> 

虽然时间片的其他都是0而且我也不知倒是干嘛的,但是至少可以修改任务的优先级(priority)。好,继续。

下两个是 sched_setschedulersched_getscheduler 。按照惯例,先获取,再更改,再获取。
获取一次后,发现

hello_task: Get myself policy success
hello_task: myself policy = 2
hello_task: Get print_hello policy success
hello_task: print_hello policy = 1

这里我就有点奇怪了,为什么先启动的 hello_task 调度策略为2,后启动的调度策略为1。测试了很多遍,都是这样。着实奇怪。然后又加了一个任务启动,获得其调度策略还是1:

hello_task: Get myself policy success
hello_task: myself policy = 2
hello_task: Started print_hello at PID=3
hello_task: Get print_hello policy success
hello_task: print_hello policy = 1
hello_task: Started print_world at PID=4
hello_task: Get print_world policy success
hello_task: print_world policy = 1

好吧,先放着。至少现在可以获取。并且后面两个进程的输出几乎是同时的。

print_hello: pid = 3
print_world: pid = 4
nsh> print_hello: Hello 0
print_world: World 0
print_hello: Hello 1
print_world: World 1
print_hello: Hello 2
print_world: World 2
print_hello: Hello 3
print_world: World 3
print_hello: Hello 4
print_world: World 4

将输出的次数增加到100次,

print_world: World 96
print_hello: Hello 97
print_world: World 97
print_hello: Hello 98
print_world: World 98
print_hello: Hello 99
print_world: World 99

并没有因为改动了任务的调度策略而发生变化。
代码如下:

#include <nuttx/config.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#define CONFIG_EXAMPLES_HELLO_TASK_PRIORITY  SCHED_PRIORITY_DEFAULT#define CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE 2048int str2num(const char *s) {    int rt = 0;    while (*s >= '0' && *s <= '9') {        rt = rt * 10 + (*s - '0');        s++;    }    return rt;}int print_hello(int argc, char *argv[]) {    int i;    printf("%s: pid = %d \n", argv[0], getpid());    int a = str2num(argv[1]);    for (i = 0; i < a; ++i) {        printf("%s: Hello %d\n", argv[0], i);    }    exit(EXIT_SUCCESS);}int print_world(int argc, char *argv[]) {    int i;    printf("%s: pid = %d \n", argv[0], getpid());    int a = str2num(argv[1]);    for (i = 0; i < a; ++i) {        printf("%s: World %d\n", argv[0], i);    }    exit(EXIT_SUCCESS);}int hello_task_main(int argc, char *argv[]) {    int ret;    int print_hello_policy, hello_task_policy, print_world_policy;    struct sched_param print_hello_sched_param;    pid_t print_hello_pid, hello_task_pid, print_world_pid;    /* print hello_task policy  */    hello_task_pid = getpid();    hello_task_policy = sched_getscheduler(hello_task_pid);    if (hello_task_policy >= 0) {        printf("%s: Get myself policy success\n", argv[0]);        printf("%s: myself policy = %d\n", argv[0], hello_task_policy);    } else {        int errcode = errno;        switch (errcode) {        case ESRCH:            printf("%s: ERROR: Failed to get myself policy: %s\n", argv[0],            ESRCH_STR);            break;        default:            printf("%s: ERROR: Failed to get myself policy\n", argv[0]);            break;        }        exit(EXIT_FAILURE);    }    /* Started print_hello */    print_hello_pid = task_create("print_hello",    CONFIG_EXAMPLES_HELLO_TASK_PRIORITY,    CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE, print_hello, &argv[1]);    if (print_hello_pid < 0) {        int errcode = errno;        printf("%s: ERROR: Failed to start print_hello: %d\n", argv[0],                errcode);        return EXIT_FAILURE;    } else        printf("%s: Started print_hello at PID=%d\n", argv[0], print_hello_pid);    /* print print_hello policy  */    print_hello_policy = sched_getscheduler(print_hello_pid);    if (print_hello_policy >= 0) {        printf("%s: Get print_hello policy success\n", argv[0]);        printf("%s: print_hello policy = %d\n", argv[0], print_hello_policy);    } else {        int errcode = errno;        switch (errcode) {        case ESRCH:            printf("%s: ERROR: Failed to get print_hello policy: %s\n", argv[0],            ESRCH_STR);            break;        default:            printf("%s: ERROR: Failed to get print_hello policy\n", argv[0]);            break;        }        exit(EXIT_FAILURE);    }    /* Get print_hello sched_param */    ret = sched_getparam(print_hello_pid, &print_hello_sched_param);    if (ret == 0) {        printf("%s: Get print_hello sched_param success\n", argv[0]);    } else {        printf("%s: ERROR: Failed to get print_hello sched_param\n", argv[0]);        exit(EXIT_FAILURE);    }    /* Change print_hello policy to SCHED_RR */    ret = sched_setscheduler(print_hello_pid, SCHED_RR,            &print_hello_sched_param);    if (ret == OK) {        printf("%s: Change print_hello policy to 2 success\n", argv[0]);    } else {        printf("%s: ERROR: Failed to change print_hello policy to 2\n",                argv[0]);        int errcode = errno;        switch (errcode) {        case EINVAL:            printf("sched_setscheduler: %s\n", EINVAL_STR);            break;        case ESRCH:            printf("sched_setscheduler: %s\n", ESRCH_STR);            break;        default:            printf("sched_setscheduler: unknow reason!\n");            break;        }        exit(EXIT_FAILURE);    }    /* Started print_world */    print_world_pid = task_create("print_world",    CONFIG_EXAMPLES_HELLO_TASK_PRIORITY,    CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE, print_world, &argv[1]);    if (print_world_pid < 0) {        int errcode = errno;        printf("%s: ERROR: Failed to start print_world: %d\n", argv[0],                errcode);        exit(EXIT_FAILURE);    } else        printf("%s: Started print_world at PID=%d\n", argv[0], print_world_pid);    /* print print_world policy  */    print_world_policy = sched_getscheduler(print_world_pid);    if (print_world_policy >= 0) {        printf("%s: Get print_world policy success\n", argv[0]);        printf("%s: print_world policy = %d\n", argv[0], print_world_policy);    } else {        int errcode = errno;        switch (errcode) {        case ESRCH:            printf("%s: ERROR: Failed to get print_world policy: %s\n", argv[0],            ESRCH_STR);            break;        default:            printf("%s: ERROR: Failed to get print_world policy\n", argv[0]);            break;        }        exit(EXIT_FAILURE);    }    exit(EXIT_SUCCESS);    return EXIT_SUCCESS;}

测试结果:

nsh> hello_task 20
hello_task: Get myself policy success
hello_task: myself policy = 2
hello_task: Started print_hello at PID=6
hello_task: Get print_hello policy success
hello_task: print_hello policy = 1
hello_task: Get print_hello sched_param success
hello_task: Change print_hello policy to 2 success
print_hello: pid = 6
hello_task: Started print_world at PID=7
print_world: pid = 7
print_hello: Hello 0
hello_task: Get print_world policy success
print_world: World 0
print_hello: Hello 1
hello_task: print_world policy = 1
print_world: World 1
print_hello: Hello 2
nsh> print_world: World 2
print_hello: Hello 3
print_world: World 3
print_hello: Hello 4
print_world: World 4
print_hello: Hello 5
print_world: World 5
print_hello: Hello 6
print_world: World 6
print_hello: Hello 7
print_world: World 7
print_hello: Hello 8
print_world: World 8
print_hello: Hello 9
print_world: World 9
print_hello: Hello 10
print_world: World 10
print_hello: Hello 11
print_world: World 11
print_hello: Hello 12
print_world: World 12
print_hello: Hello 13
print_world: World 13
print_hello: Hello 14
print_world: World 14
print_hello: Hello 15
print_world: World 15
print_hello: Hello 16
print_world: World 16
print_hello: Hello 17
print_world: World 17
print_hello: Hello 18
print_world: World 18
print_hello: Hello 19
print_world: World 19

闲暇至之余,去查了一下任务调度策略。才发现并不是简单的数字,而是有定义的。定义在

~/nuttx/nuttx/include/sched.h

#define SCHED_FIFO       1  /* FIFO priority scheduling policy */#define SCHED_RR         2  /* Round robin scheduling policy */#define SCHED_SPORADIC   3  /* Sporadic scheduling policy */#define SCHED_OTHER      4  /* Not supported */

而关于这几个定义,其中三个有其他说明:

SCHED_OTHER    分时调度策略SCHED_FIFO     实时调度策略,先到先服务SCHED_RR       实时调度策略,时间片轮转

SHCED_RR和SCHED_FIFO的不同

SHCED_RR策略的进程的时间片用完时,系统将重新分配时间片,并置于就绪队列尾。SCHED_FIFO一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。

我想这没法解释多个调度策略都为1也就是 SCHED_FIFO 的任务为何可以同时 printf 。(之后为了区分1 2,在1 2的地方替换字符串)。甚至我在修改 print_helloprint_world 的任务优先级都为不同值的时候也没有出现预期的“一直运行”。关于这个问题,我这里先放着。顺便测试一下当任务为死循环时会怎么样。
。。。
结果一样,两个 print_helloprint_world 出现了同时 printf 的情况。看样子还真得先放着了。

继续 sched_yield 那就让print_hello 让出CPU看看效果如何。

然而效果并不是那么好,甚至说没有效果。

print_hello: Hello 96
print_world: World 84
print_hello: Hello 97
print_world: World 85
print_hello: Hello 98
print_world: World 86
print_hello: Hello 99
print_world: World 87
print_world: World 88
print_world: World 89
print_world: World 90
print_world: World 91
print_world: World 92
print_world: World 93
print_world: World 94

一点都没有要让出来的意思。。。这让我怀疑这是不是NuttX系统的调度系统没有在 configure 打开。先放着,下一个。
sched_get_priority_max
在某种固定的调度策略下可取的优先级。

测试代码:

#include <nuttx/config.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#define CONFIG_EXAMPLES_HELLO_TASK_PRIORITY  SCHED_PRIORITY_DEFAULT#define CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE 2048int str2num(const char *s) {    int rt = 0;    while (*s >= '0' && *s <= '9') {        rt = rt * 10 + (*s - '0');        s++;    }    return rt;}int print_hello(int argc, char *argv[]) {    int i;    sleep(2);    //printf("%s: pid = %d \n", argv[0], getpid());    int a = str2num(argv[1]);    for (i = 0; i < a; ++i) {        sched_yield();        printf("%s: Hello %d\n", argv[0], i);    }    exit(EXIT_SUCCESS);}int print_world(int argc, char *argv[]) {    int i;    sleep(2);    //printf("%s: pid = %d \n", argv[0], getpid());    int a = str2num(argv[1]);    for (i = 0; i < a; ++i) {        printf("%s: World %d\n", argv[0], i);    }    exit(EXIT_SUCCESS);}int hello_task_main(int argc, char *argv[]) {    static char* scheduling_policies_str[4] = { "SCHED_FIFO", "SCHED_RR",            "SCHED_SPORADIC", "SCHED_OTHER" };    int ret;    int print_hello_policy, hello_task_policy, print_world_policy;    struct sched_param print_hello_sched_param;    pid_t print_hello_pid, hello_task_pid, print_world_pid;    /* print hello_task policy  */    hello_task_pid = getpid();    hello_task_policy = sched_getscheduler(hello_task_pid);    if (hello_task_policy >= 0) {        printf("%s: Get myself policy success\n", argv[0]);        printf("%s: myself policy = %s\n", argv[0],                scheduling_policies_str[hello_task_policy - 1]);    } else {        int errcode = errno;        switch (errcode) {        case ESRCH:            printf("%s: ERROR: Failed to get myself policy: %s\n", argv[0],            ESRCH_STR);            break;        default:            printf("%s: ERROR: Failed to get myself policy\n", argv[0]);            break;        }        exit(EXIT_FAILURE);    }    /* Started print_hello */    print_hello_pid = task_create("print_hello",    CONFIG_EXAMPLES_HELLO_TASK_PRIORITY - 1,    CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE, print_hello, &argv[1]);    if (print_hello_pid < 0) {        int errcode = errno;        printf("%s: ERROR: Failed to start print_hello: %d\n", argv[0],                errcode);        return EXIT_FAILURE;    } else        printf("%s: Started print_hello at PID=%d\n", argv[0], print_hello_pid);    /* print print_hello policy  */    print_hello_policy = sched_getscheduler(print_hello_pid);    if (print_hello_policy >= 0) {        printf("%s: Get print_hello policy success\n", argv[0]);        printf("%s: print_hello policy = %s\n", argv[0],                scheduling_policies_str[print_hello_policy - 1]);    } else {        int errcode = errno;        switch (errcode) {        case ESRCH:            printf("%s: ERROR: Failed to get print_hello policy: %s\n", argv[0],            ESRCH_STR);            break;        default:            printf("%s: ERROR: Failed to get print_hello policy\n", argv[0]);            break;        }        exit(EXIT_FAILURE);    }    /* get the max priority in a policy */    ret = sched_get_priority_max(SCHED_FIFO);    if (ret == -1) {        printf("%s: ERROR: Failed to get the max priority in %s\n", argv[0],                "SCHED_FIFO");    } else {        printf("%s: get the max priority in %s success\n", argv[0],                scheduling_policies_str[0]);        auto int SCHED_FIFO_max_priority = ret;        printf("%s: the max priority in %s is: %d\n", argv[0],                scheduling_policies_str[0], SCHED_FIFO_max_priority);    }    exit(EXIT_SUCCESS);    return EXIT_SUCCESS;}

理论上说,应该可以获取到255的。结果:

nsh> hello_task 5
hello_task: Get myself policy success
hello_task: myself policy = SCHED_RR
hello_task: Started print_hello at PID=3
hello_task: Get print_hello policy success
hello_task: print_hello policy = SCHED_FIFO
hello_task: get the max priority in SCHED_FIFO success
hello_task: the max priority in SCHED_FIFO is: 255
nsh> print_hello: Hello 0
print_hello: Hello 1
print_hello: Hello 2
print_hello: Hello 3
print_hello: Hello 4

和想象的一样。下一个。
sched_get_priority_min
和上一个相反,理论上应该是1,代码就把上面的max改成min即可
结果:

nsh> hello_task 5
hello_task: Get myself policy success
hello_task: myself policy = SCHED_RR
hello_task: Started print_hello at PID=3
hello_task: Get print_hello policy success
hello_task: print_hello policy = SCHED_FIFO
hello_task: get the min priority in SCHED_FIFO success
hello_task: the min priority in SCHED_FIFO is: 1
nsh> print_hello: Hello 0
print_hello: Hello 1
print_hello: Hello 2
print_hello: Hello 3
print_hello: Hello 4

正常。下一个是用来获取时间片的函数,但是首先这个函数得运行在SCHED_RR 调度策略下。直接检测hello_task 即可,因为这个任务就是RR的。
代码:

#include <sched.h>#include <nuttx/config.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#define CONFIG_EXAMPLES_HELLO_TASK_PRIORITY  SCHED_PRIORITY_DEFAULT#define CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE 2048int hello_task_main(int argc, char *argv[]) {    static char* scheduling_policies_str[4] = { "SCHED_FIFO", "SCHED_RR",            "SCHED_SPORADIC", "SCHED_OTHER" };    int ret;    int print_hello_policy, hello_task_policy, print_world_policy;    struct sched_param print_hello_sched_param;    struct timespec hello_task_timespec;    pid_t print_hello_pid, hello_task_pid, print_world_pid;    hello_task_pid = getpid();    ret = sched_rr_get_interval(hello_task_pid, &hello_task_timespec);    if (ret == 0) {        printf("%s: Get myself timespec success\n", argv[0]);        printf("%s:\nMy timespec:\n  tv_sec:  %d\n  tv_nsec: %d\n", argv[0], hello_task_timespec.tv_sec, hello_task_timespec.tv_nsec);    } else {        int errcode = errno;        switch (errcode) {        case EFAULT:            printf("%s: ERROR: Failed to get myself timespec: %s\n", argv[0],            EFAULT_STR);            break;        case EINVAL:            printf("%s: ERROR: Failed to get myself timespec: %s\n", argv[0],            EINVAL_STR);            break;        case ENOSYS:            printf("%s: ERROR: Failed to get myself timespec: %s\n", argv[0],            ENOSYS_STR);            break;        case ESRCH:            printf("%s: ERROR: Failed to get myself timespec: %s\n", argv[0],            ESRCH_STR);            break;        default:            printf("%s: ERROR: Failed to get myself timespec\n", argv[0]);            break;        }        exit(EXIT_FAILURE);    }    exit(EXIT_SUCCESS);    return EXIT_SUCCESS;}

接下来又查到一个有趣的东西。函数 strerror(int errnum) 这个函数需要在配置中开启。位置: -> Library Routines -> Enable strerror 这样就可以不用写 switch 语句了。优化后的代码:

#include <sched.h>#include <nuttx/config.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#define CONFIG_EXAMPLES_HELLO_TASK_PRIORITY  SCHED_PRIORITY_DEFAULT#define CONFIG_EXAMPLES_HELLO_TASK_STACKSIZE 2048int hello_task_main(int argc, char *argv[]) {    int ret;    struct timespec hello_task_timespec;    pid_t hello_task_pid;    hello_task_pid = getpid();    ret = sched_rr_get_interval(hello_task_pid, &hello_task_timespec);    if (ret == 0) {        printf("%s: Get myself timespec success\n", argv[0]);        printf("%s:\nMy timespec:\n  tv_sec:  %d\n  tv_nsec: %d\n", argv[0], hello_task_timespec.tv_sec, hello_task_timespec.tv_nsec);    } else {        int errcode = errno;        printf("%s: ERROR: Failed to get myself timespec: %s\n", argv[0], strerror(errcode));        exit(EXIT_FAILURE);    }    exit(EXIT_SUCCESS);    return EXIT_SUCCESS;}

一下子就精简了很多。结果:

nsh> hello_taskhello_task: Get myself timespec successhello_task:                    My timespec:                  tv_sec:  0  tv_nsec: 200000000nsh> 

虽然不知道是个什么情况,但是已经成功了。


任务调度的接口试验到此结束。

0 0