打印
[STM32F0]

os_tsk_create_user (); 如何设置堆栈参数

[复制链接]
2572|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhu51231|  楼主 | 2015-10-12 12:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在学习mdk的rtx在创建人物的时候遇到了问题,使用
os_tsk_create(); 语句创建没有问题,可是使用
os_tsk_create_user (); 语句创建的时候老是提示:
error:  #167: argument of type "int" is incompatible with parameter of type "void *"
语句:t_adc2=os_tsk_create_user(adc2,1,0x20002000,1024);
怎么修改都不能通过,求高人指点。
沙发
天灵灵地灵灵| | 2015-10-12 15:38 | 只看该作者
内核初始化函数:
<1> void os_sys_init (
    void (*task)(void) );  /* Task to start */
    初始化并启动RTX内核,内核起来后运行传进来的task任务.该任务的优先级为1, 堆栈大小在rtx_config.c文件中配置,默认为512字节.
<2> void os_sys_init_prio (
    void (*task)(void),   /* Task to start */
    U8 priority);         /* Task priority (1-254) */
  与os_sys_init功能一样, 多了配置task任务优先级的功能.
    priority范围为1~254, 0留给idle task使用,255为保留值.如果设置priority为0,内核自动调整为1.


<3> void os_sys_init_user (
    void (*task)(void),    /* Task to start */
    U8    priority,        /* Task priority (1-254) */
    void* stack,           /* Task stack */
    U16   size);           /* Stack size */
    与os_sys_init_prio功能一样, 多了配置task任务堆栈的功能.
    任务堆栈必须是8字节对齐,可以这样定义任务堆栈:
    static U64 stk1[400/8];    /* 400-byte stack */
    因为unsigned long long变量在cortex-m3内核是8字节对齐的.
    也可以这样定义:
    static __align(8) u8  stk1[400];


任务创建:


<1> OS_TID os_tsk_create (
    void (*task)(void),    /* Task to create */
    U8    priority );      /* Task priority (1-254) */

    返回值:
    成功返回任务ID号,失败时返回0.

    参数priority指定任务的优先级,如果为0,内核会将优先级调整为1(优先级0给idle task使用),255应该给优先级最高的任务使用,建议不要使用该优先级。
    如果新建任务的优先级比当前任务的大,会立即切换到新任务去运行,否则将新任务放到就绪队列中(任务状态为READY).任务使用默认的堆栈大小(512Byte),
    在rtx_confg.c中定义.


<2> OS_TID os_tsk_create_ex (
    void (*task)(void *),    /* Task to create */
    U8    priority,          /* Task priority (1-254) */
    void* argv );            /* Argument to the task */


    返回值:
    成功返回任务ID号,失败时返回0.


    在新任务启动时,可以将argv参数传递给任务,其他功能与os_tsk_create函数一样.


<3> OS_TID os_tsk_create_user(
    void (*task)(void),    /* Task to create */
    U8    priority,        /* Task priority (1-254) */
    void* stk,             /* Pointer to the task's stack */
    U16   size );          /* Number of bytes in the stack */

    返回值:
    成功返回任务ID号,失败时返回0.


    该函数可以配置任务的堆栈大小,其他功能与os_tsk_create函数一样.
    任务堆栈必须是8字节对齐,可以这样定义任务堆栈:
    static U64 stk1[400/8];    /* 400-byte stack */
    因为unsigned long long变量在cortex-m3内核是8字节对齐的.
    也可以这样定义:
    static __align(8) u8  stk1[400];


<4> OS_TID os_tsk_create_user_ex (
    void (*task)(void *),    /* Task to create */
    U8    priority,          /* Task priority (1-254) */
    void* stk,               /* Pointer to the task's stack */
    U16   size,              /* Size of stack in bytes */
    void* argv );            /* Argument to the task */

    返回值:
    成功返回任务ID号,失败时返回0.


    该函数是os_tsk_create_ex和os_tsk_create_user的合并版本,可以传argv参数给任务又可以定制任务堆栈大小,其他功能与os_task_create一样.

argv的使用例子:


同时创建两个task2任务,通过传进去的参数argv区别是哪一个任务.


#include <rtl.h>


OS_TID tsk1, tsk2_0, tsk2_1;
int param[2] = {0, 1};


__task void task1 (void) {
   ..
  tsk2_0 = os_tsk_create_ex (task2, 1, &param[0]);
  tsk2_1 = os_tsk_create_ex (task2, 1, &param[1]);
   ..
}


__task void task2 (void *argv) {
   ..
  switch (*(int *)argv) {
    case 0:
      printf("This is a first instance of task2.\n");
      break;
    case 1:
      printf("This is a second instance of task2.\n");
      break;
  }
   ..
}


其他相关函数


<1> OS_RESULT os_tsk_delete (
    OS_TID task_id );    /* Id of the task to delete */

    返回值:
  OS_R_OK: 要删除的任务已停止并已被删除
    OS_R_NOK: 删除任务出错,如任务不存在。

    该函数用于删除一个任务,task_id为要删除的任务ID号.task_id=0表示删除当前任务,当前任务被删除后,
    会从就绪对例中取出优先级最高的任务运行。


<2> void os_tsk_delete_self (void);

    该函数用于删除当前任务,当前任务被删除后,会从就绪对例中取出优先级最高的任务运行。


<3> void os_tsk_pass (void);

    主动将CPU控制权转交给就绪队例中同优先级的任务.如果就绪队例中有和当前任务优先级(任务A)一样的任务(任务B),
    内核会切换到任务B去运行.如果没有与当前任务优先级一样的任务,当前任务会继续运行.
    因为RTX允许任务的优先级一样,同优先级的任务可以调用该函数主动放弃CPU,让其他同优先级的任务运行.


<4> OS_RESULT os_tsk_prio (
    OS_TID task_id,       /* ID of the task */
    U8     new_prio );    /* New priority of the task (1-254) */


    返回值:
    OS_R_OK   任务优先级修改成功
    OS_R_NOK  修改优先级失败

    该函数修改任务的优先级,task_id为要修改的任务ID, new_prio为新优先级,new_prio范围为1~254, 0为idle task的
  优先级,如果new_prio为0,内核自动调整为1。如果task_id = 0,修改的是当前任务的优先级.如果新任务的优先级比当前
  任务要高,则切换到新任务运行。

<5> OS_RESULT os_tsk_prio_self (
    U8 new_prio );    /* New priority of task (1-254) */

    返回值:
    OS_R_OK   任务优先级修改成功
    OS_R_NOK  修改优先级失败

    功能与os_task_prio(0, new_prio)一样,修改的是当前任务的优先级.


<6> OS_TID os_tsk_self (void)

    返回值:
    当前任务的ID号

    获取当前任务的ID号.


<7> OS_TID isr_tsk_get (void);

    返回值:
    当前被中断的任务ID号


  该函数在中断处理程序中使用,获取当前被中断的任务的ID号

使用特权

评论回复
板凳
天灵灵地灵灵| | 2015-10-12 15:39 | 只看该作者
RTX_Config.c 宏定义详解
时间 2014-04-19 11:49:26  CSDN博客
原文  http://blog.csdn.net/yang627468471/article/details/24101245
主题 Linux
任务:
#define OS_TASKCNT     6            /*处于活动状态的最大任务数*/
#define OS_PRIVCNT     0            /*是否可以用户自定义任务*/
堆栈:
#define OS_STKSIZE     50            /*默认的堆栈大小*/
#define OS_STKCHECK    1            /*激活堆栈检查*/
#define OS_RUNPRIV     0            /*是否运行所有的任务在特权模式*/
用户定时器:
#define OS_TIMERCNT    0            /*指定的用户定时器数目*/
硬件时钟:
#define OS_CLOCK       72000000        /*为选定的时钟指定输入时钟的频率*/
#define OS_TICK        10000        /*指定时间脉冲间隔,单位us*/
多任务轮转
#define OS_ROBIN       1            /*是否激活多任务轮转*/
#define OS_ROBINTOUT   5            /*标识当前运行任务的时间片,当前时间片用完,当前运行任务被终止,下一个任务被重新开始*/
说明: ARM处理器共支持7种处理器模式,其中包括:用户模式、系统模式、管理模式、中止模式、未定义模式、中断模式、快速中断模式。其中管理、中止、未定义、中断、快速中断归属于异常模式。而异常和系统归属于特权模式。
3、在C文件中包含头文件#include <RTL.h>就可以使用RTX的库函数,启动内核了。下面举例说明。
#include <RTL.h>
OS_TID phase_A;                      /* 分配任务ID号: phase_A*/
OS_TID phase_B;                      /* 分配任务ID号: phase_B*/
static U64 stack[800/8];          /*自定义的堆栈大小*/
__task void init(void);              
__task void phase_A(void);           /* 进程函数的声明*/
__task void phase_B(void) ;
  
int main (void)
{                     
      SYS_Init ();                   /* 初始化系统的时钟*/
    os_sys_init (init);            /* 按照默认的配置初始化第一个进程*/
}
/*第一个进程:创建新的线程并删除自己*/
__task void init (void)  
{
    phase_A = os_tsk_create (task_A,  0);      /* 使用默认的配置创建一个进程*/
       phase_A = os_tsk_create_user (task_B,0,&stack,sizeof(stack));  /*使用自定义的堆栈创建进程*/
       os_tsk_delete_self ();                 /*删除自己*/
}
__task void task_A(void)  
{
    /*编写用户代码*/
}
__task void task_B(void)
{
        /*编写用户代码*/
}  

使用特权

评论回复
地板
zhu51231|  楼主 | 2015-10-12 19:25 | 只看该作者
按照2楼的提示,这样写编译通过:
uint64_t        stk1[256/8];
t_adc2=os_tsk_create_user(adc2,1,&stk1,256);
我这里一个有4个任务,加上初始化任务和空闲任务,一个有6个任务。我在设置文档里面只设置5个任务,所以在初始化任务里面只创建了3个任务,系统任务删除后,在第一个任务里面在创建最后一个任务,总任务还是6个:
__task  void        init(void)
        {
                t_adc2=os_tsk_create_user(adc2,1,&stk1,256);
                t_key=os_tsk_create(key,2);
                t_show=os_tsk_create(show,1);
                os_tsk_delete_self();//
        }
__task        void        adc2(void)
{
        t_control=os_tsk_create(control,1);//这里创建最后一个任务
        while(1)
        {
                toadc();
                adcmath();//计算数据采集的结果
                kzhitouqie();//分析采集数据的结果
        }
}
其余几个任务
__task        void        show(void)
{
        while(1)
        {
                ClrLcd1();
                loaddata();//lcd加载计算的结果
                readrtc();//读取RTC的系统时间
                playtime();//显示系统时间       
                lcdloaddata();//lcd加载数据
                os_evt_wait_or(0x0001,0xffff);
        }
}
__task        void        key(void)
{
        Key_Init();//按键初始化
        os_evt_wait_or(0x0001,0xffff);
        while(1)
        {
                senkey1();//按键处理程序
        }
}
__task        void        control(void)
{
        while(1)
        {
                on_off();//这里输出控制执行一遍之后就退出,等待事件(下一次数据分析结果)
                os_evt_wait_or(0x0001,0xffff);
        }
}
以上程序写入stm32f030r8t6里面可以运行,由于芯片的内存较小,adc2任务需要最小256堆栈,每个任务都设置256个堆栈,编译不通过,只好每个任务设置64个,然后单独设置adc2的堆栈。


使用特权

评论回复
5
zhu51231|  楼主 | 2015-10-12 19:36 | 只看该作者
程序可以运行了,可是运行几个循环之后就进入
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}
里面了,这个只好跟踪调试了,不过在没有使用rtx之前程序是没有这个问题的,这可能是rtx有什么特殊的要求吧。
调试的时候还发现一个问题,定时器的中断嵌套设为0,也会进入到上面的死循环,修改为3后解决,看来在rtx里面,中断优先级是不能设为0的。

使用特权

评论回复
6
zhu51231|  楼主 | 2015-10-14 20:46 | 只看该作者
本来要把分数给2楼的,老是显示:分数未分配完,或分数分配存在错误!
没有办法,只好直接结贴了,

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

117

帖子

1

粉丝