已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在分析之前我先说一下ZStack协议栈有很多版本,版本不一样,代码多少有一些不一样,我的ZStack是ZStack-CC2530-2.3.1-1.4.0。另外我的这篇文章中有很多内容是参考网友的文章,不知道有没有侵犯版权。我自己总结一下按键处理流程,在ZStack协议栈中,按键的处理有两种方式,一种是中断方式,另一种是轮询方式,在这里,我以中断的方式来处理按键。我的按键接在P0_1,如图所示:从图中可以看出,当按键没有按下的时候P0_1引脚为高电平,当按键按下时,引脚变成低电平,在这里,我的按键的中断触发方式为下降沿有效。为了让按键按下后,程序能做点事情,我以LED灯为例,也就是说,当按键按下后,我让LED的状态翻转,也就是说按键按下一次,LED灯亮,在按下一次,LED灯灭,在按一下一次,LED灯亮。下图是LED的引脚图:纵观总的ZStack协议栈,我们发现P0_1和P1_0接的正好是按键和LED灯,因此在协议栈中,关于的按键和LED灯的代码我们不需要修改的太多。我从main函数开始一步一步的分析,为了减小篇幅和代码量,我只分析与按键和中断有关的代码。Int main()/ Turn off interrupts关闭中断 osal_int_disable( INTS_ALL );/就是设置EA为0,EA为各种中断的总开关/ Initialization for board related stuff such as LEDs /初始化系统时钟,LED等 HAL_BOARD_INIT();/这个里面我没有动 /电压检测,最好是能保证芯片能正常工作的电压 / Make sure supply voltage is high enough to run zmain_vdd_check();/ Initialize board I/O初始化板载IO InitBoard( OB_COLD ); / Initialze HAL drivers初始化HAL驱动 HalDriverInit(); / Initialize NV System初始化NV系统 osal_nv_init( NULL ); / Initialize the MAC初始化MAC ZMacInit(); / Determine the extended address确定IEEE地址 zmain_ext_addr();#if defined ZCL_KEY_ESTABLISH / Initialize the Certicom certificate information. zmain_cert_init();#endif / Initialize basic NV items/初始化基本NV条目 zgInit();#ifndef NONWK / Since the AF isnt a task, call its initialization routine afInit();#endif / Initialize the operating system/初始化操作系统 osal_init_system(); / Allow interrupts使能所有中断,就是让EA为1 osal_int_enable( INTS_ALL ); / Final board initialization最后的板载初始化 InitBoard( OB_READY ); / Display information about this device zmain_dev_info(); /* Display the device info on the LCD */#ifdef LCD_SUPPORTED zmain_lcd_init();#endif#ifdef WDT_IN_PM1 /* If WDT is used, this is a good place to enable it. */ WatchDogEnable( WDTIMX );#endif osal_start_system(); / No Return from here return 0; / Sh在这里只分析红色部分的代码: / Initialize board I/O初始化板载IO InitBoard( OB_COLD );我们进入到到这个函数void InitBoard( uint8 level ) if ( level = OB_COLD ) / IAR does not zero-out this byte below the XSTACK. *(uint8 *)0x0 = 0; / Interrupts off osal_int_disable( INTS_ALL ); / Check for Brown-Out reset ChkReset(); else / !OB_COLD /* Initialize Key stuff */ /这个函数的作用是对按键使用的IO进行初始以及设置按键工作方式,按键IO初始化主要是将按键所对应的IO口定义为输入口 /如果这个函数的第一个参数是HAL_KEY_INTERRUPT_ENABLE,那么按下该按键会触发IO终端,因此这个函数还要对IO终端 /进行初始化的配置;如果这个函数的第一个参数是HAL_KEY_INTERRUPT_DISABLE,那么主程序后周期性的执行按键扫描程序 /查看按键状态 HalKeyConfig(HAL_KEY_INTERRUPT_ENABLE, OnBoard_KeyCallback);/在TI的源码中,第一个参数是HAL_KEY_INTERRUPT_DISABLE 进入这个函数的时候,if条件成立,在这个if语句中没有做什么实际的事情,我们不管它,else语句不成立,我暂且先部分分析,在下面还会被调用,在下面我们在分析这个else语句。/ Initialze HAL drivers初始化HAL驱动 HalDriverInit();进入这个函数中,我们发现有很多初初始化,例如,TIMER,ADC,DMA等等,我们只分析LED和KEY部分的代码,先分析KEY部分的代码,进入到函数中。void HalKeyInit( void ) /* Initialize previous key to 0 */ halKeySavedKeys = 0; HAL_KEY_SW_6_SEL &= (HAL_KEY_SW_6_BIT); /* Set pin function to GPIO 设置p0_1为通用的IO口*/ HAL_KEY_SW_6_DIR &= (HAL_KEY_SW_6_BIT); /* Set pin direction to Input设置p0_1为输入的方式 */ HAL_KEY_JOY_MOVE_SEL &= (HAL_KEY_JOY_MOVE_BIT); /* Set pin function to GPIO */ HAL_KEY_JOY_MOVE_DIR &= (HAL_KEY_JOY_MOVE_BIT); /* Set pin direction to Input */ /* Initialize callback function */ /这个玩意是一个回调函数的指针,初始化的初始化按键的时候,初始化指针为NULL pHalKeyProcessFunction = NULL; /* Start with key is not configured */ HalKeyConfigured = FALSE;在这里我说一下,TI他们自己板子上,有很多按键,其中有5个是用来模拟我们的游戏手柄,有UP,DOEN,RIGHT,LEFT,CENTER,上面的蓝色部分的代码就是对这个按键的设置,在这里我们没有用到,我们就不管这些代码了,在这里我们约定,凡是与这5个按键有关的代码(就是.JOY.)我们就都不分析了。/* LED 在TI设计的板子上p1.0,p1.1,p1.4这三个引脚上接了三个不同颜色的LED灯,在初始化的时候全部设置成立灭的状态*/void HalLedInit (void)#if (HAL_LED = TRUE) /* Initialize all LEDs to OFF */ /即在初始化工作中关闭所有的LED灯,这个函数其实就是LED的驱动函数,右面 /应用层调用的也是此函数 HalLedSet (HAL_LED_ALL, HAL_LED_MODE_OFF);#endif /* HAL_LED */#ifdef BLINK_LEDS /* Initialize sleepActive to FALSE */ HalLedStatusControl.sleepActive = FALSE;#endif/ Initialize the operating system/初始化操作系统 osal_init_system();osalInitTasks();Hal_Init( taskID+ );Hal_Init( taskID+ );这个函数中只有一句话void Hal_Init( uint8 task_id ) /* Register task ID */ Hal_TaskID = task_id;osal_init_system();osalInitTasks();SampleApp_Init( taskID ); RegisterForKeys( SampleApp_TaskID );/登记所有的按键事件 进入到这个函数里面看一下:uint8 RegisterForKeys( uint8 task_id ) / Allow only the first task if ( registeredKeysTaskID = NO_TASK_ID ) registeredKeysTaskID = task_id; return ( true ); else return ( false );/ Final board initialization最后的板载初始化 InitBoard( OB_READY );进入到这个函数,我们这次分析else的语句,在else部分调用这个函数HalKeyConfig(HAL_KEY_INTERRUPT_ENABLE, OnBoard_KeyCallback);这个函数的分析在上面已经分析过了,这里在做一下补充,因为我们对按键的处理是中断方式的,因此第一个参数一定得是HAL_KEY_INTERRUPT_ENABLE,第二个参数一个函数的名字,它在这里表示的是函数的地址,我们知道函数的名字就是函数的地址,这个函数我们管它叫回调函数,这里的意思就是注册回调函数,将这个函数的地址作为参数传递到HalKeyConfig这个函数中,我们进入到这个函数中,这个函数的代码还是蛮多的,我还是贴出来吧。void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback) /* Enable/Disable Interrupt or */ Hal_KeyIntEnable = interruptEnable; /* Register the callback fucntion */ pHalKeyProcessFunction = cback;/让这个pHalKeyProcessFunction函数指针指向这个函数OnBoard_KeyCallback /* Determine if interrupt is enable or not */ if (Hal_KeyIntEnable)/中断方式处理按键 /* Rising/Falling edge configuratinn */ PICTL &= (HAL_KEY_SW_6_EDGEBIT); /* Clear the edge bit */ /* For falling edge, the bit must be set. */ #if (HAL_KEY_SW_6_EDGE = HAL_KEY_FALLING_EDGE) PICTL |= HAL_KEY_SW_6_EDGEBIT;/ P0(P0口有8个引脚)口上所有的引脚配置终端成下降沿触发 #endif /* Interrupt configuration: * - Enable interrupt generation at the port * - Enable CPU interrupt * - Clear any pending interrupt */ HAL_KEY_SW_6_ICTL |= HAL_KEY_SW_6_ICTLBIT;/p0_1引脚的中断使能 HAL_KEY_SW_6_IEN |= HAL_KEY_SW_6_IENBIT;/p0端口中断使能 HAL_KEY_SW_6_PXIFG = (HAL_KEY_SW_6_BIT);/清除p0_1的中断标志位 /* Rising/Falling edge configuratinn */ HAL_KEY_JOY_MOVE_ICTL &= (HAL_KEY_JOY_MOVE_EDGEBIT); /* Clear the edge bit */ /* For falling edge, the bit must be set. */ #if (HAL_KEY_JOY_MOVE_EDGE = HAL_KEY_FALLING_EDGE) HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_EDGEBIT; #endif /* Interrupt configuration: * - Enable interrupt generation at the port * - Enable CPU interrupt * - Clear any pending interrupt */ HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_ICTLBIT; HAL_KEY_JOY_MOVE_IEN |= HAL_KEY_JOY_MOVE_IENBIT; HAL_KEY_JOY_MOVE_PXIFG = (HAL_KEY_JOY_MOVE_BIT); /* Do this only after the hal_key is configured - to work with sleep stuff */ if (HalKeyConfigured = TRUE) osal_stop_timerEx( Hal_TaskID, HAL_KEY_EVENT); /* Cancel polling if active */ else /Interrupts NOT enabled 以轮询的方式处理按键 /既然以轮询的方式查询按键,当然让终端失能 HAL_KEY_SW_6_ICTL &= (HAL_KEY_SW_6_ICTLBIT); /* dont generate interrupt */ HAL_KEY_SW_6_IEN &= (HAL_KEY_SW_6_IENBIT); /* Clear interrupt enable bit */ /100ms后向Hal_TaskID发送HAL_KEY_EVENT事件,是事件处理代码中(Hal_ProcessEvent()使用函数HalKeyPoll()查询是否有按键按下 osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_POLLING_VALUE); /* Kick off polling */ /* Key now is configured */ HalKeyConfigured = TRUE;这个函数的作用就是使能中断,设置下降沿触发等等,具体的分析看结合协议栈里面的宏定义和我的注释。到这里LED灯和按键中断的初始化工作基本上就完成了,下面就是当按键按下触发中断的中断处理函数了。我们进入到这个文件中,hal_key.c,找到这个函数HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )这个函数就是端口P0的中断程序,也就是当端口p0上有按键中断发生的时候,第一个进入的就是这个函数/halKeyPort0Isr是中断的函数名字,P0INT_VECTOR是中断的入口我把代码贴出来HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) HAL_ENTER_ISR();/设置EA = 1; /当p0.1引脚上的中断到来的时候,P0IFG的p0.1位会置1 if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT) /这个函数的作用就是25ms后向Hal_TaskID发送HAL_KEY_EVENT事件,为什么要25ms之后发送事件呢?是为了延时去按键抖动 halProcessKeyInterrupt(); /*我自己解释一下Hal_TaskID这个任务ID所表示的意思:平时我们写按键的中断服务函数的时候,例如当中断发生的时候,我们让LED灯状态翻转(LED = LED;)这个让LED状态翻转就是任务,这个任务是直接写在了中断服务函数中了,但是在ZStack协议栈中,当按键中断发生的时候没有直接把这个任务写在这里,而是产生一个标志,这个标志就是HAL_KEY_EVENT事件,这样就可以把任务(例如让LED灯状态翻转)写在别处,ZStack通过一定方法,把这个事件(标志)发送出去,当任务函数接收到这个事件的时候,就会执行任务(让LED灯的状态翻转)了。 */ /* Clear the CPU interrupt flag for Port_0 PxIFG has to be cleared before PxIF */ HAL_KEY_SW_6_PXIFG = 0;/清除p0_1的中断标志位 HAL_KEY_CPU_PORT_0_IF = 0;/ 清除端口0的中断标志,IRCON的bit5位 CLEAR_SLEEP_MODE(); HAL_EXIT_ISR();这里面调用了这个函数void halProcessKeyInterrupt ()我们进去看一次:/这个函数可以理解为只是个中断标志。没有对中断做具体处理,同时延时25ms设置一个HAL_KEY_EVENT事件,让Hal_TaskID去处理,延时的目的是去抖动void halProcessKeyInterrupt (void) bool valid=FALSE; /当p0.1引脚上的终端到来的时候,P0IFG的p0.1位会置1 if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT) /* Interrupt Flag has been set */ /清除这个中断标志位 HAL_KEY_SW_6_PXIFG = (HAL_KEY_SW_6_BIT); /* Clear Interrupt Flag */ valid = TRUE; if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT) /* Interrupt Flag has been set */ HAL_KEY_JOY_MOVE_PXIFG = (HAL_KEY_JOY_MOVE_BIT); /* Clear Interrupt Flag */ valid = TRUE; if (valid) /*在HAL_KEY_DEBOUNCE_VALUE时间(25ms)后触发,用于按键去抖, 然后osal_start_timerEx()会触发Hal_ProcessEvent()函数,*/ /系统会把这个定时的时间,事件,任务的ID添加到定时器链表中 osal_start_timerEx(Hal_TaskID,HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE); 这里面调用了这个函数osal_start_timerEx(),我们找到HAL_KEY_EVENT事件的处理部分,在hal_drivers.c的这个函数中Hal_ProcessEvent()我们进去:uint16 Hal_ProcessEvent( uint8 task_id, uint16 events ). if (events & HAL_KEY_EVENT) #if (defined HAL_KEY) & (HAL_KEY = TRUE) /* Check for keys */ HalKeyPoll();/按键检测在这里执行 /* if interrupt disabled, do next polling */ /如果按键不是以中断方式进行触发,而是轮询方式,则在100ms后将置HAL_KEY_EVENT事件 /也就是每隔100ms,这个函数讲得到一次执行,随后上面的HalKeyPoll()以一起执行 if (!Hal_KeyIntEnable) osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100); #endif / HAL_KEY return events HAL_KEY_EVENT; .这里面调用了这个函数,HalKeyPoll();我们进去void HalKeyPoll (void) uint8 keys = 0; /halGetJoyKeyInput()调用HalAdcRead()得出操纵杆的值,是通过AD进来了模拟电压值得出 /*if (HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT) / Key is active HIGH keys = halGetJoyKeyInput();/通过AD转换来判断按键 */我觉得这点代码需要注释掉, /* If interrupts are not enabled, previous key status and current key status * are compared to find out if a key has changed status. */ if (!Hal_KeyIntEnable)/如果没有使能按键中断 if (keys = halKeySavedKeys) /* Exit - since no keys have changed */ return; /* Store the current keys for comparation next time */ halKeySavedKeys = keys; else/如果使能了按键中断 /* Key interrupt handled here */ if (HAL_PUSH_BUTTON1() /keys |= HAL_KEY_SW_6;/检测HAL_KEY_SW_6键值状态; keys = HAL_KEY_SW_6; /* Invoke Callback if new keys were depressed 如果有按键按下,回调函数*/ if (keys & (pHalKeyProcessFunction)/键值为非零且按键处理函数指针非空则调用回调函数; /这个回调函数在void HalKeyInit(void)中得对初始化pHalKeyProcessFunction = NULL; (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);/这个函数将实现对不同键值的不同处理 /我们发现在void HalKeyConfig(bool interrruptEnable,halKeyCBack_t cback)函数中有这样的语句 /pHalKeyProcessFunction = cback; 也就是说(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL) /是在执行这个函数void OnBoard_KeyCallback(uint8 keys,uint8 state) (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);这个函数其实是在执行void OnBoard_KeyCallback(uint8 keys,uint8 state),我们进入到这个函数中void OnBoard_KeyCallback ( uint8 keys, uint8 state ) uint8 shift = 0; (void)state; /默认将 HAL_KEY_SW_6作为组合键辅助键shift使用; /若shift为true,则进入后续的组合键程序;否则进入相应 HAL_KEY_SW_6的单按键程序; shift = (keys & HAL_KEY_SW_6) ? true : false; if ( OnBoard_SendKeys( keys, shift ) != ZSuccess )/如果执行不成功,则执行下面 / Process SW1 here if ( keys & HAL_KEY_SW_1 ) / Switch 1 / Process SW2 here if ( keys & HAL_KEY_SW_2 ) / Switch 2 / Process SW3 here if ( keys & HAL_KEY_SW_3 ) / Switch 3 / Process SW4 here if ( keys & HAL_KEY_SW_4 ) / Switch 4 / Process SW5 here if ( keys & HAL_KEY_SW_5 ) / Switch 5 / Process SW6 here if ( keys & HAL_KEY_SW_6 ) / Switch 6 我们发现调用了这个函数OnBoard_SendKeys().我们进去uint8 OnBoard_SendKeys( uint8 keys, uint8 state ) keyChange_t *msgPtr; if ( registeredKeysTaskID != NO_TASK_ID ) / Send the address to the task /其实分配的内存大小为osal_msg_hdr_t + keyChange_t msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) ); if ( msgPtr ) msgPtr-hdr.event = KEY_CHANGE;/事件类型按键变化 msgPtr-state = state; msgPtr-keys = keys; /将按键事件产生的消息发送到注册啦按键这一事件的任务 osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr ); return ( ZSuccess ); else return ( ZFailure );里面调用了这个函数,osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );,这个函数很神奇,我们进入这个函数uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr ) if ( msg_ptr = NULL ) return ( INVALID_MSG_POINTER ); if ( destination_task = tasksCnt ) osal_msg_deallocate( msg_ptr ); return ( INVALID_TASK ); / Check the message header if ( OSAL_MSG_NEXT( msg_ptr ) != NULL | OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK ) osal_msg_deallocate( msg_ptr ); return ( INVALID_MSG_POINTER ); OSAL_MSG_ID( msg_ptr ) = destination_task; / queue message将消息加到消息队列中 osal_msg_enqueue( &osal_qHead, msg_ptr ); / Signal the task that a message is waiting osal_set_event( destination_task, SYS_EVENT_MSG ); return ( SUCCESS );里面调用了这个函数osal_set_event( destination_task, SYS_EVENT_MSG );这个函数里面有更神奇的东西uint8 osal_set_event( uint8 task_id, uint16 event_flag ) if ( task_id tasksCnt ) halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); / Hold off interrupts tasksEventstask_id |= event_flag; / Stuff the event bit(s) HAL_EXIT_CRITICAL_SECTION(intState); / Release interrupts return ( SUCCESS ); else return ( INVALID_TASK ); 红色部分的代码是不是很熟悉,是不是在哪里见过,如果红色的代码你有点熟悉,就说明你对ZStack是有很深了解的,如果还不是很熟悉,我建议您在把ZStack协议栈在好好熟悉熟悉,在看这些代码。osal_set_event()函数的作用就是把我们的HAL_KEY_EVENT事件和对应的ID放进tasksEvents数组里面。然后进入到这个文件中OSAL.c,找到这个函数void osal_start_system( void ),我们发现tasksEvents就在这个函数中,进入这个函数,do if (tasksEventsidx) / Task is highest priority that is ready. break; while (+idx state, (keyChange_t *)MSGpkt)-keys );/调用按键事件处理函数这里就是按键事件的处理了,有专门的按键事件处理函数,就是这个函数SampleApp_HandleKeys()我们进入这个函数/按键处理函数void SampleApp_HandleKeys( uint8 shift, uint8 keys ) (void)shift; / Intentionally unreferenced parameter if ( keys & HAL_KEY_SW_1 ) /* This key sends the Flash Command is sent to Group 1. * This device will not receive the Flash Command from this * device (even if it belongs to group 1). */ /HalLedSet(HAL_LED_1,HAL_LED_MODE_TOGGLE); SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION ); if ( keys & HAL_KEY_SW_6 ) /* The Flashr Command is sent to Group 1. * This key toggles this device in and out of group 1. * If this device doesnt belong to group 1, this application * will not receive the Flash command sent to group 1. */LED灯状态翻转 HalLedSet(HAL_LED_1,HAL_LED_MODE_TOGGLE); /HalUARTWrite(0,Hello,World,11); aps_Group_t *grp; grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); if ( grp ) / Remove from the group aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); else / Add to the flash group aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); 至此,我们就实现了按键按下一次LED灯的状态翻转一下的功能。其实我们能实现这个功能是紧紧依靠ZStack协议栈的任务调度机制的,这个函数void osal_start_system()在不停的查找哪个事件发生了,当事件发生后就执行相应的事件处理函数。当时我分析到这里的时候,我还有一事不明就是这个函数, osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);这个函数是在25ms后,性Hal_TaskID 发送HAL_KEY_EVENT事件,我们知道这个事件的处理是在uint16 Hal_ProcessEvent( uint8 task_id, uint16 events )函数中,那么这个函数是在哪里被调用呢,我发现在OSAL_SampleApp.c文件中的这个地方有const pTaskEventHandlerFn tasksArr = macEventLoop, nwk_event_loop, Hal_ProcessEvent,/硬件处理函数#if defined( MT_TASK ) MT_ProcessEvent,#endif APS_event_loop,#if defined ( ZIGBEE_FRAGMENTATION ) APSF_ProcessEvent,#endif ZDApp_event_loop,#if defined ( ZIGBEE_FREQ_AGILITY ) | defined ( ZIGBEE_PANID_CONFLICT ) ZDNwkMgr_event_loop,#endif SampleApp_ProcessEvent;而这个数组的执行是在OSAL.c文件中的void osal_start_system(void)中,也就是说,osal_start_timerEx()将事件发送出,事件的处理函数是在void osal_start_system()这里,那么void osal_start_system()是怎样得到这个事件呢?那么我们现在就分析osal_start_timerEx()函数,进入函数体uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value ) halIntState_t intState; osalTimerRec_t *newTimer; HAL_ENTER_CRITICAL_SECTION( intState ); / Hold off interrupts. / Add timer newTimer = osalAddTimer( taskID, event_id, timeout_value ); HAL_EXIT_CRITICAL_SECTION( intState ); / Re-enable interrupts. return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL );里面调用了这个函数,这个函数的作用就是把任务ID、事件和定时时间加入到定时器
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 机场飞行区课程设计
- 一年级信息技术上册 农家小院-图形工具的使用 1教案 河大版
- 九年级化学下册 第9单元 实验活动5 一定溶质质量分数的氯化钠溶液的配制教案 (新版)新人教版
- 机器人机构学课程设计
- 本科环评课程设计
- 本班近视人数研究报告
- 2024年供暖系统换热工程施工协议
- 本地污水管网施工方案
- 2024至2030年干花礼品项目投资价值分析报告
- 木储物柜施工方案
- 初中数学人教七年级下册第六章 实数 《实数》说课PPT
- 部编版《美丽的小兴安岭》第二课时(完美版)课件
- 《湘夫人》课件36张
- 混凝土建筑结构设计顾祥林混凝土结构设计概论
- 动物疫病防治员(高级)理论考试题库大全-下(单选、判断600题)
- 初中一年级学生家长会课件
- 相机检定报告-5d2参数
- 第九章-化工装置运行安全技术课件
- 关于货运代理有限公司的物流服务方案设计毕业设计
- 2023年6月英语四级真题(第一套)
- 典范英语7-4中英文对照翻译Oh,otto!Oh,otto
评论
0/150
提交评论