This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

如何设置任务事件优先级?

Other Parts Discussed in Thread: Z-STACK, CC2530

我起了一个用户任务,有3个事件,一个是系统的处理无线数据的随机事件,另一个是只要加入网络就会5秒一次轮询的ad采样事件,还有另一个事件是根据ad采样的结果,如果结果在我范围之内也会5秒一次的led灯闪烁事件,现在我不知道如何设置事件优先级,导致led灯闪烁事件和ad采样事件可以执行,但是无线数据接受处理事件却无法执行,该如何解决?需要如何设置事件?

  • CC2530是用的OSAL,可以看下Z-Stack Home Developer’s Guide中OSAL的介绍,包括任务如何建立,如何设置优先级。该文档可在协议栈中找到
  • cc2530無法设置事件优先级,先到先處理
  • 貌似只有任务有优先级
  • 拆分为两个任务:把AD采样监控定义为一个比无线连接优先级高的任务,如何?
  • 任务也沒有优先级
  • 不是吧?我理解OSAL 的TASKID 大小就决定了任务的优先级, tasksArr[] 里有定义,值越小,优先级越高。
  • 確實是 TASKID 值越小會先被處理,但是 把AD采样监控定义为一个比无线连接优先级高的任务可能會影響到无线连接吧,建議你如果這樣作的話要多測試看看有沒有問題
  • 那楼主的问题,您觉得怎么解决好呢?
  • 我認為這是應用程序沒有寫對、應該調试一下問題在哪

  • 我这边想要使无线连接事件的优先级高于那两个事件的优先级,是不是只要将ad采样和led灯的事件id改为无线连接之后的id就可以了?
  • 能不能发一些资料过来看看啊
  • 轮询的ad采样事件,还有另一个事件是根据ad采样的结果,如果结果在我范围之内也会5秒一次的led灯闪烁事件

    你能不能貼上你的程序解釋一下你怎樣作的?

  • #include "OSAL.h"
    #include "AF.h"
    #include "ZDApp.h"
    #include "ZDObject.h"
    #include "ZDProfile.h"
    #include <string.h>

    #include "Coordinator.h"
    #include "DebugTrace.h"

    #if !defined( WIN32 )
    #include "OnBoard.h"
    #endif


    #include "hal_lcd.h"
    #include "hal_led.h"
    #include "hal_key.h"
    #include "hal_uart.h"
    #include "hal_adc.h"
    #include "ioCC2530.h"

    #define ADC_TO_ALL_EVENT 0x1d //定义adc采样事件
    #define LED_TO_ALL_EVENT 0x1e //定义LED闪烁事件

    static uint16 EndDeviceId = 0x0001 ;
    int count = 0; //统计溢出次数
    int counter = 0; //PWM方波次数
    int timer = 0; //高电平时间
    uint16 voltage; //电压值
    long int sum; //电压和
    byte n=0,k=0; //k:ad采样周期时间,n为报警次数
    // This list should be filled with Application specific Cluster IDs.
    const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
    {
    PWM_ON,
    PWM_OFF,
    PWM_PRO,
    PWM_PUBLIC
    };

    const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
    {
    GENERICAPP_ENDPOINT, // int Endpoint;
    GENERICAPP_PROFID, // uint16 AppProfId[2];
    GENERICAPP_DEVICEID, // uint16 AppDeviceId[2];
    GENERICAPP_DEVICE_VERSION, // int AppDevVer:4;
    GENERICAPP_FLAGS, // int AppFlags:4;
    0,//GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters;
    (cId_t *)NULL,//(cId_t *)GenericApp_ClusterList, // byte *pAppInClusterList;
    GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters;
    (cId_t *)GenericApp_ClusterList // byte *pAppInClusterList;
    };

    // This is the Endpoint/Interface description. It is defined here, but
    // filled-in in GenericApp_Init(). Another way to go would be to fill
    // in the structure here and make it a "const" (in code space). The
    // way it's defined in this sample app it is define in RAM.
    endPointDesc_t GenericApp_epDesc;
    endPointDesc_t SpecialApp_epDesc;

    byte GenericApp_TaskID;
    byte GenericApp_TransID;
    void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
    void GenericApp_SendTheMessage( int flag );


    byte SpecialApp_TaskID;
    byte SpecialApp_TransID;
    void SpecialApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
    void SpecialApp_AdPro(void);
    void SpecialApp_AlarmPro(void);

    devStates_t SpecialApp_NwkState;



    void Init_Timer3(void);
    void Init_GPIO(void);
    void PWM_WORK(int time,int close_flag);

    _PRAGMA(T3_VECTOR) __near_func __interrupt void T3_ISR(void);

    void delay(int time_ms);
    void GREEN_LED(int count);
    void RED_LED(void);
    void BLUE_LED(int count);

    void GREEN_LED(int count)
    {
    int i;
    for(i=0;i<count;i++)
    {
    GREEN = 0;
    delay(3000);
    GREEN = 1;
    delay(3000);
    }
    }

    void BLUE_LED(int count)
    {
    int i;
    for(i=0;i<count;i++)
    {
    BLUE = 0;
    delay(2000);
    BLUE = 1;
    delay(2000);
    }
    }


    /*
    函数名:RED_LED
    参数: 无
    功能: 红灯闪烁,0.5秒一次
    返回值:无
    */
    void RED_LED(void)
    {
    RED = 0;
    delay(1000);
    RED = 1;
    delay(500);
    }



    /*
    函数名:delay
    参数: time_ms:延时时间,ms级
    功能: 延时
    返回值:无
    */
    void delay(int time_ms)
    {
    int i,j;
    for(i=0;i<1000;i++)
    for(j=0;j<time_ms;j++);
    }


    void Init_GPIO(void)
    {
    //设置为标准IO口
    P0SEL &= ~(1<<0|1<<1|1<<3|1<<5|1<<7);
    P1SEL &= ~(1<<1|1<<3|1<<5|1<<7);
    P2SEL &= ~1<<1;

    P0DIR &= ~(1<<0|1<<1|1<<3|1<<5); //设置为输入
    P0DIR |= 1<<7; //设置为输出

    P1DIR |= 1<<1|1<<3|1<<5|1<<7; //设置为输出

    P2DIR |= 1<<1; //设置为输出

    RED = 1;
    GREEN = 1;
    BLUE = 1;
    PWM = 0;
    Lock = 0;
    POWER = 0;
    }


    /****************************************************************************
    * 名 称: InitT3()
    * 功 能: 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
    * 入口参数: 无
    * 出口参数: 无
    ****************************************************************************/
    void Init_Timer3()
    {
    T3CTL |= 0x08 ; //开溢出中断
    T3IE = 1; //开总中断和T3中断
    T3CTL |= 0x40; //4分频,4/32000000*N=0.0001S,N=800
    T3CTL &= ~0x03; //自动重装 00->0xff 800/255=3.1(次)
    T3CTL |= 0x10; //启动
    EA = 1;
    }

    /*
    函数名:PWM_WORK
    参数: time:PWM方波高电平事件,close_flag开关标志,1关0开
    功能: 出pwm方波,达到开关舵机的效果
    返回值:无
    */
    void PWM_WORK(int time,int close_flag)
    {
    POWER = 1; //开启电源
    timer = time; //30为0.8~0.9ms,79为2.5ms
    if( close_flag == 1 ) //判断命令
    {
    int i;
    for( i=0;i<50;i++ )
    {
    if( Sensor1 == 0 && Sensor2 == 0 && Sensor3 == 0 ) //判断抽屉是否关上
    {
    Init_Timer3();
    break;
    }else delay(100);
    if( i== 49 ) //规定时间内没有关上退出此函数
    {
    POWER = 0; //关闭电源
    return;
    }
    }
    }else Init_Timer3();
    while(1)
    {
    if(counter > 250) //pwm方波次数判断
    {
    T3CTL &= ~1<<4;
    counter = 0;
    POWER = 0; //关闭电源
    return;
    }
    }
    }

    //定时器 T3 中断处理函数
    #pragma vector = T3_VECTOR
    __interrupt void T3_ISR(void)
    {
    IRCON = 0x00; //清中断标志,也可由硬件自动完成
    if(count++ < timer)
    {
    PWM = 1;
    }else
    {
    PWM = 0;
    }
    if(count == 628)
    {
    count = 0;
    counter++;
    }
    }

    /*void GPIO_INIT()
    {
    P0SEL &= ~(1<<2|1<<3|1<<4);
    P1SEL &= ~1<<5;
    P0DIR |= 1<<2|1<<3|1<<4; //p1.2~1.4为输出口
    P1DIR &= ~1<<5; //p1.5为输入口
    P1IEN |= 1<<5; //中断使能
    PICTL |= 1<<2; //下降沿触发
    EA = 1; //打开总中断
    IEN2 |= 1<<4; //端口1中断使能
    P1IFG = 0; //初始化P1中断标志
    }


    #pragma vector = P1INT_VECTOR
    __interrupt void P1_ISR(void)
    {
    if(P1IFG>0) //按键中断
    {
    HalLedBlink(HAL_LED_1,50,5,20);
    P1IFG = 0;
    }
    P1IF = 0; //清中断标志
    } */

    void GenericApp_Init( uint8 task_id )
    {
    GenericApp_TaskID = task_id;
    GenericApp_TransID = 0;

    // Fill out the endpoint description.
    GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
    GenericApp_epDesc.task_id = &GenericApp_TaskID;
    GenericApp_epDesc.simpleDesc
    = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
    GenericApp_epDesc.latencyReq = noLatencyReqs;
    // Register the endpoint description with the AF
    afRegister( &GenericApp_epDesc );
    }

    uint16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
    {
    afIncomingMSGPacket_t *MSGpkt;
    if ( events & SYS_EVENT_MSG )
    {
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
    while ( MSGpkt )
    {
    switch ( MSGpkt->hdr.event )
    {
    case AF_INCOMING_MSG_CMD: //无线消息事件处理
    GenericApp_MessageMSGCB(MSGpkt);
    break;
    default:
    break;
    }
    osal_msg_deallocate( (uint8 *)MSGpkt );

    // Next
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
    }
    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
    }
    return 0;
    }




    void SpecialApp_Init( uint8 task_id )
    {
    Init_GPIO();
    HalAdcInit();
    HalAdcSetReference(HAL_ADC_REF_125V);

    SpecialApp_TaskID = task_id;
    SpecialApp_NwkState = DEV_INIT;
    SpecialApp_TransID = 0;

    // Fill out the endpoint description.
    SpecialApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
    SpecialApp_epDesc.task_id = &SpecialApp_TaskID;
    SpecialApp_epDesc.simpleDesc
    = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
    SpecialApp_epDesc.latencyReq = noLatencyReqs;
    // Register the endpoint description with the AF
    afRegister( &SpecialApp_epDesc );
    }

    uint16 SpecialApp_ProcessEvent( byte task_id, UINT16 events )
    {
    afIncomingMSGPacket_t *MSGpkt;
    if ( events & SYS_EVENT_MSG )
    {
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SpecialApp_TaskID );
    while ( MSGpkt )
    {
    switch ( MSGpkt->hdr.event )
    {
    case ZDO_STATE_CHANGE: //建立网络后,设置事件
    SpecialApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
    if(SpecialApp_NwkState == DEV_END_DEVICE)
    {
    osal_set_event(SpecialApp_TaskID,ADC_TO_ALL_EVENT);
    }
    default:
    break;
    }
    osal_msg_deallocate( (uint8 *)MSGpkt );

    // Next
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SpecialApp_TaskID );
    }
    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
    }
    if(events & ADC_TO_ALL_EVENT) //AD采样事件处理
    {
    SpecialApp_AdPro();
    osal_start_timerEx(SpecialApp_TaskID,ADC_TO_ALL_EVENT,60000);
    return (events ^ ADC_TO_ALL_EVENT);
    }
    if(events & LED_TO_ALL_EVENT) //LED闪烁事件处理
    {
    RED_LED();
    osal_start_timerEx(SpecialApp_TaskID,LED_TO_ALL_EVENT,10000);
    return (events ^ LED_TO_ALL_EVENT);
    }
    return 0;
    }


    /*
    函数名:GenericApp_MessageMSGCB
    参数: afIncomingMSGPacket_t *pkt 无线消息
    功能: 处理协调器发来的消息
    返回值:无
    */
    void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
    {
    unsigned char *recvbuf;
    switch( pkt->clusterId)
    {
    case PWM_ON:
    osal_memcpy(recvbuf,pkt->cmd.Data,3);
    if(osal_memcmp(recvbuf,"O!",3))
    {
    GenericApp_SendTheMessage(1);
    }
    break;
    case PWM_OFF:
    osal_memcpy(recvbuf,pkt->cmd.Data,3);
    if(osal_memcmp(recvbuf,"C!",3))
    {
    GenericApp_SendTheMessage(0);
    }
    break;
    case PWM_PUBLIC:
    osal_memcpy(recvbuf,pkt->cmd.Data,6);
    if(osal_memcmp(recvbuf,"0001+O",6))
    {
    GenericApp_SendTheMessage(1);
    }else if(osal_memcmp(recvbuf,"0001+C",6))
    {
    GenericApp_SendTheMessage(0);
    }
    break;
    }
    }


    /*
    函数名:GenericApp_SendTheMessage
    参数: flag,pwm工作标志,1开0关
    功能: 根据标志去发pwm方波,从而达到驱动舵机的效果,并发送信息给协调器
    返回值:无
    */
    void GenericApp_SendTheMessage( int flag )
    {
    unsigned char *theMessageData = "EndDevice received!";
    afAddrType_t my_DstAddr;
    my_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
    my_DstAddr.endPoint = GENERICAPP_ENDPOINT;
    my_DstAddr.addr.shortAddr = 0x0000;
    if( flag == 1 )
    {
    PWM_WORK(30,0);
    }else if( flag == 0 )
    {
    PWM_WORK(79,1);
    }
    AF_DataRequest( &my_DstAddr,&GenericApp_epDesc,
    PWM_PRO,
    osal_strlen(theMessageData)+1,
    theMessageData,
    &GenericApp_TransID,
    AF_DISCV_ROUTE,
    AF_DEFAULT_RADIUS);
    }

    /*
    函数名:GenericApp_AdPro
    参数: 无
    功能: ad采样,当低于3.55v时触发报警
    返回值:无
    */
    void SpecialApp_AdPro(void)
    {
    sum = 0;
    for(int i=0;i<100;i++)
    {
    sum += HalAdcRead(HAL_ADC_CHN_AIN0, HAL_ADC_RESOLUTION_12);
    }
    voltage = sum / 100;
    if( voltage < 1700 )
    {
    if( n == 0 )
    {
    n = 1 ;
    SpecialApp_AlarmPro();
    }
    }else osal_stop_timerEx(SpecialApp_TaskID,LED_TO_ALL_EVENT);
    }

    /*
    函数名:GenericApp_AlarmPro
    参数: 无
    功能: 报警处理,发送缺电信息,开锁,红灯5秒闪一次
    返回值:无
    */
    void SpecialApp_AlarmPro(void)
    {
    unsigned char *theMessageData = "EndDevice power shortage!";
    afAddrType_t my_DstAddr;
    my_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
    my_DstAddr.endPoint = GENERICAPP_ENDPOINT;
    my_DstAddr.addr.shortAddr = 0x0000;

    Lock = 1;
    delay(500);
    Lock = 0;
    osal_set_event(SpecialApp_TaskID,LED_TO_ALL_EVENT);

    AF_DataRequest( &my_DstAddr,&SpecialApp_epDesc,
    PWM_PRO,
    osal_strlen(theMessageData)+1,
    theMessageData,
    &SpecialApp_TransID,
    AF_DISCV_ROUTE,
    AF_DEFAULT_RADIUS);
    }
  • 原来我使放在一个任务里面的,后来看不行想弄成两个任务,但是感觉还是不行不知道怎么回事?
  • 你程序裡面有太多for-loop/delay會持續佔用cpu,建議你降低for-loop次數或是delay時間,需要delay建議用timer event 去做,led闪烁建議用z-Stack API HalLedBlink去做就好
  • 用HalLedBlink函数的话,就怕功耗做不下来,我现在主要想知道的是,这个用户任务是不是可以设置两个或多个,如果可以的话怎么初始化设置和更改其优先级;如果不能的话,事件的优先级如何设置,我看好像事件是有优先级的,但是我手上资料太少,所以想让大佬指点一二