static int test_empty() { Queue* queue = Queue_new(0); nu_assert(Queue_empty(queue)); int array[] = {1}; Queue_enqueue(queue, &array[0]); nu_assert(!Queue_empty(queue)); Queue_dequeue(queue); nu_assert(Queue_empty(queue)); Queue_free(queue); return 0; }
/******************************************************************************* * @fn SensorTagOad_processEvent * * @brief Process the write events to the OAD characteristics * * @param a0, a1 (not used) * * @return none */ void SensorTagOad_processEvent(void) { while (!Queue_empty(hOadQ)) { oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ); // Identify new image. if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ) { // Request image identification OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData); } // Write a next block request. else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ) { OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData); } // Free buffer. ICall_free(oadWriteEvt); } }
/* * ======== Power_notify ======== * * Note: When this function is called Task scheduling is disabled. */ Power_Status Power_notify(Power_Event eventType) { Power_Status returnStatus = Power_SOK; Power_NotifyResponse notifyStatus; Queue_Handle notifyQ; notifyQ = Power_Module_State_notifyQ(); /* if notification queue is not empty, service the queue */ if (!Queue_empty(notifyQ)) { /* service the notification queue... */ notifyStatus = Power_serviceNotifyQ(eventType); /* if notifications did not complete successfully ... */ if (notifyStatus != Power_NOTIFYDONE) { /* call the configured notify trap function */ (*(Power_FuncPtr)Power_notifyTrapFunc)(); returnStatus = Power_EFAIL; } } return (returnStatus); }
void Serial_writeByte(uint8_t data) { CRITICAL_VAL(); CRITICAL_ENTER(); if( (UCSR0A & (1U << UDRE0)) && Queue_empty(&TxBuff)) { UDR0 = data; } else { UCSR0B |= (1U << UDRIE0); while(!Queue_write(&TxBuff, &data)) { CRITICAL_EXIT(); WAIT_INT(); CRITICAL_ENTER(); } } CRITICAL_EXIT(); }
/********************************************************************* * @fn SimpleBLEBroadcaster_processEvent * * @brief Application task entry point for the Simple BLE Broadcaster. * * @param none * * @return none */ static void SimpleBLEBroadcaster_taskFxn(UArg a0, UArg a1) { // Initialize application SimpleBLEBroadcaster_init(); // Application main loop for (;;) { // Get the ticks since startup uint32_t tickStart = Clock_getTicks(); // Waits for a signal to the semaphore associated with the calling thread. // Note that the semaphore associated with a thread is signaled when a // message is queued to the message receive queue of the thread or when // ICall_signal() function is called onto the semaphore. ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); if (errno == ICALL_ERRNO_SUCCESS) { ICall_EntityID dest; ICall_ServiceEnum src; ICall_HciExtEvt *pMsg = NULL; if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS) { if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { // Process inter-task message SimpleBLEBroadcaster_processStackMsg((ICall_Hdr *)pMsg); } if (pMsg) { ICall_freeMsg(pMsg); } } // If RTOS queue is not empty, process app message. while (!Queue_empty(appMsgQueue)) { sbbEvt_t *pMsg = (sbbEvt_t *)Util_dequeueMsg(appMsgQueue); if (pMsg) { // Process message. SimpleBLEBroadcaster_processAppMsg(pMsg); // Free the space from the message. ICall_free(pMsg); } } } } }
/* * ======== Event_post ======== */ Void Event_post(Event_Object *event, UInt eventId) { UInt tskKey, hwiKey; Event_PendElem *elem; Queue_Handle pendQ; Assert_isTrue((eventId != 0), Event_A_nullEventId); Log_write3(Event_LM_post, (UArg)event, (UArg)event->postedEvents, (UArg)eventId); pendQ = Event_Instance_State_pendQ(event); /* atomically post this event */ hwiKey = Hwi_disable(); /* or in this eventId */ event->postedEvents |= eventId; /* confirm that ANY tasks are pending on this event */ if (Queue_empty(pendQ)) { Hwi_restore(hwiKey); return; } tskKey = Task_disable(); /* examine pendElem on pendQ */ elem = (Event_PendElem *)Queue_head(pendQ); /* check for match, consume matching eventIds if so. */ elem->matchingEvents = Event_checkEvents(event, elem->andMask, elem->orMask); if (elem->matchingEvents != 0) { /* remove event elem from elem queue */ Queue_remove((Queue_Elem *)elem); /* mark the Event as having been posted */ elem->pendState = Event_PendState_POSTED; /* disable Clock object */ if (BIOS_clockEnabled && (elem->tpElem.clock != NULL)) { Clock_stop(elem->tpElem.clock); } /* put task back into readyQ */ Task_unblockI(elem->tpElem.task, hwiKey); } Hwi_restore(hwiKey); /* context switch may occur here */ Task_restore(tskKey); }
/* * ======== Power_rebuildConstraint ======== */ Void Power_rebuildConstraint(Power_Constraint type) { Queue_Handle constraintsQ; Queue_Elem * elem; UInt value; UInt key; /* disable scheduling */ key = Swi_disable(); /* first, re-initialize the aggregate constraint */ if (type == Power_DISALLOWED_CPU_SETPOINT_MASK) { Power_module->disallowedSetpointsCPU = 0; } else if (type == Power_DISALLOWED_PER_SETPOINT_MASK) { Power_module->disallowedSetpointsPER = 0; } else if (type == Power_DISALLOWEDSLEEPSTATE_MASK) { Power_module->disallowedSleepModes = 0; } constraintsQ = Power_Module_State_constraintsQ(); if (!Queue_empty(constraintsQ)) { elem = Queue_head(constraintsQ); do { /* only if constraint 'type' matches... */ if (((Power_ConstraintObj *)elem)->type == type) { /* get the constraint value */ value = (UInt) ((Power_ConstraintObj *)elem)->value; /* update the agregate constraint */ if (type == Power_DISALLOWED_CPU_SETPOINT_MASK) { Power_module->disallowedSetpointsCPU |= value; } else if (type == Power_DISALLOWED_PER_SETPOINT_MASK) { Power_module->disallowedSetpointsPER |= value; } else if (type == Power_DISALLOWEDSLEEPSTATE_MASK) { Power_module->disallowedSleepModes |= value; } } elem = Queue_next(elem); } while (elem != (Queue_Elem *) constraintsQ); } /* re-enable scheduling */ Swi_restore(key); }
/* * ======== pthread_setschedparam ======== */ int pthread_setschedparam(pthread_t pthread, int policy, const struct sched_param *param) { pthread_Obj *thread = (pthread_Obj *)pthread; Task_Handle task = thread->task; UInt oldPri; int priority = param->sched_priority; UInt key; #if ti_sysbios_posix_Settings_supportsMutexPriority__D int maxPri; #endif if ((priority >= Task_numPriorities) || ((priority == 0)) || (priority < -1)) { /* Bad priority value */ return (EINVAL); } key = Task_disable(); oldPri = Task_getPri(task); thread->priority = priority; #if ti_sysbios_posix_Settings_supportsMutexPriority__D /* * If the thread is holding a PTHREAD_PRIO_PROTECT or * PTHREAD_PRIO_INHERIT mutex and running at its ceiling, we don't * want to set its priority to a lower value. Instead, we save the * new priority to set it to, once the mutexes of higher priority * ceilings are released. */ if (!Queue_empty(Queue_handle(&(thread->mutexList)))) { maxPri = _pthread_getMaxPrioCeiling(thread); if (priority > maxPri) { Task_setPri(task, priority); } } else { /* The thread owns no mutexes */ oldPri = Task_setPri(task, priority); } #else oldPri = Task_setPri(task, priority); #endif Task_restore(key); /* Suppress warning about oldPri not being used. */ (void)oldPri; return (0); }
void Enqueue(queue * q, NODE_TYPE n){ node * tempNode = malloc(sizeof(node*)); tempNode->value = n; tempNode->next = NULL; //if queue is empty if(Queue_empty(q)){ q->head = tempNode; q->tail = tempNode; }else{ q->tail->next = tempNode; q->tail = tempNode; } return; }
/* * ======== Task_deleteTerminatedTasksFunc ======== */ Void Task_deleteTerminatedTasksFunc() { UInt key; Task_Handle tsk; key = Hwi_disable(); if (!Queue_empty(Task_Module_State_terminatedQ())) { tsk = Queue_head(Task_Module_State_terminatedQ()); Hwi_restore(key); Task_delete(&tsk); } else { Hwi_restore(key); } }
// ----------------------------------------------------------------------------- //! \brief Dequeues the message from the RTOS queue. //! //! \param msgQueue - queue handle. //! //! \return pointer to dequeued message, NULL otherwise. // ----------------------------------------------------------------------------- uint8_t *NPIUtil_dequeueMsg(Queue_Handle msgQueue) { if (!Queue_empty(msgQueue)) { queueRec_t *pRec = Queue_dequeue(msgQueue); uint8_t *pData = pRec->pData; // Free the queue node // Note: this does not free space allocated by data within the node. NPIUTIL_FREE(pRec); return pData; } return NULL; }
/* * Dequeue an item from the queue. * Parameters * Queue_T q - queue to dequeue from * Returns * (void*) dequeued item or NULL if no item exists */ void *Queue_dequeue(Queue_T q) { void* item; /* dequeued item */ assert(q != NULL); if (Queue_empty(q)) return NULL; item = *(q->pop++); q->filled--; if (QUEUE_RATIO(q) >= 4) Queue_resize(q, q->size / 2); /* Wrap the pop pointer around. */ else if ((q->pop - q->data) == q->size) q->pop = q->data; return item; }
/* * ======== Semaphore_post ======== */ Void Semaphore_post(Semaphore_Object *sem) { UInt tskKey, hwiKey; Semaphore_PendElem *elem; Queue_Handle pendQ; /* Event_post will do a Log_write, should we do one here too? */ Log_write2(Semaphore_LM_post, (UArg)sem, (UArg)sem->count); pendQ = Semaphore_Instance_State_pendQ(sem); hwiKey = Hwi_disable(); if (Queue_empty(pendQ)) { if (((UInt)sem->mode & 0x1) != 0) { /* if BINARY bit is set */ sem->count = 1; } else { sem->count++; Assert_isTrue((sem->count != 0), Semaphore_A_overflow); } Hwi_restore(hwiKey); if (Semaphore_supportsEvents && (sem->event != NULL)) { Semaphore_eventPost(sem->event, sem->eventId); } return; } /* lock task scheduler */ tskKey = Task_disable(); /* dequeue tsk from semaphore queue */ elem = (Semaphore_PendElem *)Queue_dequeue(pendQ); /* mark the Semaphore as having been posted */ elem->pendState = Semaphore_PendState_POSTED; /* put task back into readyQ */ Task_unblockI(elem->tpElem.task, hwiKey); Hwi_restore(hwiKey); Task_restore(tskKey); }
/** * usage: this method does the work, checkes the queue, writes to the UART and post's * the Event * @method uart_method * @author: patrik.szabo * @param arg0 - not used param for the task * @return *none* */ void uart_method(UArg arg0) { // char input; UART_Handle uart; UART_Params uartParams; /* Create a UART with data processing off. */ UART_Params_init(&uartParams); uartParams.writeDataMode = UART_DATA_BINARY; uartParams.readDataMode = UART_DATA_BINARY; uartParams.readReturnMode = UART_RETURN_FULL; uartParams.readEcho = UART_ECHO_OFF; uartParams.baudRate = 9600; uart = UART_open(Board_UART0, &uartParams); if (uart == NULL) { System_abort("Error opening the UART"); } QueueObject* queueObjectPointer; char altData[22] = ""; char pressData[16] = ""; char tempData[18] = ""; while (1) { while (!Queue_empty(uartQueue)) { queueObjectPointer = Queue_dequeue(uartQueue); sprintf(altData, "Altitude: %d | ", (int) queueObjectPointer->myInformationPointer->alt); System_printf("%s", altData); UART_write(uart, altData, sizeof(altData)); sprintf(pressData, "Pressure: %d | ", queueObjectPointer->myInformationPointer->press); System_printf("%s", pressData); UART_write(uart, pressData, sizeof(pressData)); sprintf(tempData, "Temparature: %d\n\r", queueObjectPointer->myInformationPointer->temp); System_printf("%s", tempData); UART_write(uart, tempData, sizeof(tempData)); Event_post(uartReadyEvent, Event_Id_02); } Task_sleep(500); } }
/********************************************************************* * @fn Util_dequeueMsg * * @brief Dequeues the message from the RTOS queue. * * @param msgQueue - queue handle. * * @return pointer to dequeued message, NULL otherwise. */ uint8_t *Util_dequeueMsg(Queue_Handle msgQueue) { if (!Queue_empty(msgQueue)) { queueRec_t *pRec = Queue_dequeue(msgQueue); uint8_t *pData = pRec->pData; // Free the queue node // Note: this does not free space allocated by data within the node. #ifdef USE_ICALL ICall_free(pRec); #else free(pRec); #endif return pData; } return NULL; }
/* * ======== Task_deleteTerminatedTasksFunc ======== */ Void Task_deleteTerminatedTasksFunc() { UInt hwiKey, taskKey; Task_Handle tsk; taskKey = Task_disable(); hwiKey = Hwi_disable(); if (!Queue_empty(Task_Module_State_terminatedQ())) { tsk = Queue_head(Task_Module_State_terminatedQ()); Hwi_restore(hwiKey); tsk->readyQ = NULL; Task_delete(&tsk); } else { Hwi_restore(hwiKey); } Task_restore(taskKey); }
/* * ======== Task_blockI ======== * Block a task. * * Remove a task from its ready list. * Must be called within Task_disable/Task_restore block * and with interrupts disabled */ Void Task_blockI(Task_Object *tsk) { Queue_Object *readyQ = tsk->readyQ; UInt curset = Task_module->curSet; UInt mask = tsk->mask; Log_write2(Task_LD_block, (UArg)tsk, (UArg)tsk->fxn); Queue_remove((Queue_Elem *)tsk); /* if last task in readyQ, remove corresponding bit in curSet */ if (Queue_empty(readyQ)) { Task_module->curSet = curset & ~mask; } if (Task_module->curTask == tsk) { Task_module->curQ = NULL; /* force a Task_switch() */ } tsk->mode = Task_Mode_BLOCKED; Task_module->workFlag = 1; }
Void Swi_restoreHwi(UInt swiKey) { Queue_Handle curQ, maxQ; Swi_Object *swi; if (swiKey == FALSE) { if (Swi_module->curSet && (Core_getId() == 0)) { /* Remember current Swi priority */ curQ = Swi_module->curQ; /* determine current highest priority Q */ maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); /* Run all Swis of higher priority than the current Swi priority */ /* Will pre-empt any currently running swi. */ while (maxQ > curQ) { swi = (Swi_Object *)Queue_dequeue(maxQ); /* remove from curSet if last one in this ready list */ if (Queue_empty(maxQ)) { Swi_module->curSet &= ~swi->mask; } Swi_run(swi); if (Swi_module->curSet == 0) { break; } maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); } } Swi_module->locked = FALSE; } }
/* * ======== Swi_runLoop ======== */ Void Swi_runLoop() { Queue_Handle curQ, maxQ; Swi_Object *swi; /* Remember current Swi priority */ curQ = Swi_module->curQ; /* refresh maxQ */ maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); /* * Run all Swis of higher priority than * the current Swi priority. * Will pre-empt any currently running swi. */ do { swi = (Swi_Object *)Queue_dequeue(maxQ); /* remove from curSet if last one in this ready list */ if (Queue_empty(maxQ)) { Swi_module->curSet &= ~swi->mask; } Swi_run(swi); if (Swi_module->curSet == 0) { break; } maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); } while (maxQ > curQ); }
/* * ======== Power_notify ======== * * Note: when this function is called, Swi and Task scheduling are disabled, * but interrupts are enabled. */ Power_Status Power_notify(Power_Event eventType, UInt timeout, Power_SigType sigType, UArg extArg1, UArg extArg2) { Power_NotifyResponse clientStatus; UInt32 notifyStartTime; Queue_Handle notifyQ; Queue_Elem * elem; Arg eventArg1; Arg eventArg2; UInt clients = 0; Fxn notifyFxn; Arg clientArg; UInt key; /* determine the appropriate notification queue */ notifyQ = (Queue_Handle)((UInt8 *)(Power_module->notifyQ) + (UInt)(eventType * (2 * sizeof(Ptr)))); /* if queue is empty, return immediately */ if (Queue_empty(notifyQ)) { return (Power_SOK); } /* reset the count of clients doing delayed completion */ ti_sysbios_family_c674_Power_notifyWaitCount[(UInt)eventType] = 0; /* grab notification start time (# ticks) */ notifyStartTime = Clock_getTicks(); /* point to first client notify object */ elem = Queue_head(notifyQ); /* walk the queue and notify each registered client of the event */ do { clients++; /* count each registered client being notified */ /* pull params from notify object */ notifyFxn = ((Power_NotifyObj *)elem)->notifyFxn; clientArg = ((Power_NotifyObj *)elem)->clientArg; /* determine the event arguments... */ /* if event triggered internally then Power determines event args: */ if (sigType == Power_SigType_INTERNAL) { if (eventType == Power_PENDING_CPU_SETPOINTCHANGE) { eventArg1 = (Arg) Power_module->currentSetpointCPU; eventArg2 = (Arg) Power_module->nextSP; } else if (eventType == Power_DONE_CPU_SETPOINTCHANGE) { eventArg1 = (Arg) Power_module->previousSP; eventArg2 = (Arg) Power_module->currentSetpointCPU; } else if (eventType == Power_PENDING_PER_SETPOINTCHANGE) { eventArg1 = (Arg) Power_module->currentSetpointPER; eventArg2 = (Arg) Power_module->nextSPPER; } else if (eventType == Power_DONE_PER_SETPOINTCHANGE) { eventArg1 = (Arg) Power_module->previousSPPER; eventArg2 = (Arg) Power_module->currentSetpointPER; } else { eventArg1 = NULL; eventArg2 = NULL; } } /* else for externally triggered events use client-specified args: */ else { eventArg1 = (Arg) extArg1; eventArg2 = (Arg) extArg2; } asm(" .global _Power_ntfy"); asm("_Power_ntfy:"); clientStatus = (Power_NotifyResponse) (*(Fxn)notifyFxn)(eventType, eventArg1, eventArg2, clientArg); /* if client said not done, increment count of clients to wait for */ if (clientStatus == Power_NOTIFYNOTDONE) { key = Hwi_disable(); ti_sysbios_family_c674_Power_notifyWaitCount[(UInt)eventType] += 1; Hwi_restore(key); } else if (clientStatus == Power_NOTIFYERROR) { return (Power_EFAIL); } /* get next element in this notify queue */ elem = Queue_next(elem); } while (elem != (Queue_Elem *) notifyQ); /* if no timout and a client said not done, return immediately */ if ((timeout == 0) && (ti_sysbios_family_c674_Power_notifyWaitCount[(UInt)eventType] != 0)) { return (Power_ETIMEOUT); } /* if any client said not done: wait until they signal completion */ while (ti_sysbios_family_c674_Power_notifyWaitCount[(UInt)eventType] != 0) { if ((Clock_getTicks() - notifyStartTime) > timeout) { return (Power_ETIMEOUT); } } return (Power_SOK); }
/******************************************************************************* * @fn SensorTag_taskFxn * * @brief Application task entry point for the SensorTag * * @param a0, a1 (not used) * * @return none */ static void SensorTag_taskFxn(UArg a0, UArg a1) { // Initialize application SensorTag_init(); // Application main loop for (;;) { // Waits for a signal to the semaphore associated with the calling thread. // Note that the semaphore associated with a thread is signalled when a // message is queued to the message receive queue of the thread or when // ICall_signal() function is called onto the semaphore. ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); if (errno == ICALL_ERRNO_SUCCESS) { ICall_EntityID dest; ICall_ServiceEnum src; ICall_HciExtEvt *pMsg = NULL; if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS) { if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { // Process inter-task message SensorTag_processStackMsg((ICall_Hdr *)pMsg); } if (pMsg) { ICall_freeMsg(pMsg); } } // If RTOS queue is not empty, process app message. while (!Queue_empty(appMsgQueue)) { stEvt_t *pMsg = (stEvt_t *)Util_dequeueMsg(appMsgQueue); if (pMsg) { // Process message. SensorTag_processAppMsg(pMsg); // Free the space from the message. ICall_free(pMsg); } } // Process new data if available SensorTagKeys_processEvent(); SensorTagOpt_processSensorEvent(); SensorTagMov_processSensorEvent(); } if (!!(events & ST_PERIODIC_EVT)) { events &= ~ST_PERIODIC_EVT; if (gapProfileState == GAPROLE_CONNECTED || gapProfileState == GAPROLE_ADVERTISING) { Util_startClock(&periodicClock); } // Perform periodic application task if (gapProfileState == GAPROLE_CONNECTED) { SensorTag_performPeriodicTask(); } // Blink green LED when advertising if (gapProfileState == GAPROLE_ADVERTISING) { SensorTag_blinkLed(Board_LED2,1); #ifdef FEATURE_LCD SensorTag_displayBatteryVoltage(); #endif } } #ifdef FEATURE_OAD while (!Queue_empty(hOadQ)) { oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ); // Identify new image. if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ) { OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData); } // Write a next block request. else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ) { OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData); } // Free buffer. ICall_free(oadWriteEvt); } #endif //FEATURE_OAD } // task loop }
/******************************************************************************* * @fn userAppPro * * @brief user Application event process * * @param evnet * * @return none */ void userAppPro(void) { if (userEvents & USER_10MS_EVT) { userEvents &= ~USER_10MS_EVT; Util_startClock(&periodicClock_10ms); KEY_Scan_10ms(); ChangeTime10mSec(); Pollint100mSec(); } #ifdef INCLUDE_CLKSTOP while (!Queue_empty(keyMsgQueue)) { KEY_stEvt_t *pMsg = (KEY_stEvt_t *)Util_dequeueMsg(keyMsgQueue); if (pMsg) { // Process message. switch(pMsg->GPIOName) { case KEY_NAME_3V3: if (KEY_HIGH == pMsg->GPIOStatus) { wifiPowerOn(); uartWriteDebug("poweron3v3", 10); OLED_ShowString(40,32, "WiCore"); userAppShowCharge(); // 启动广播 { uint8_t initialAdvertEnable = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } Util_startClock(&periodicClock_10ms); } else { wifiPowerDown(); uartWriteDebug("powerdown3v3", 12); // 清低电闪烁 systemState.lowBatteryFlag = 0; OLED_Clear(); // 这个执行时间较长 打乱了定时周期,所以stopClock是没有用的 //Util_stopClock(&periodicClock_10ms); // 服务器的按键开关机 设置一个按键放开标志位,等待1s后没有放开 // 就清标志位,关闭时钟 systemState.keyUpFlag = 3; // 2 为电源按键 等待按键放开标志,3为 服务器按键 systemState.delayCnt = 10; // 有链接,关闭 GAPRole_TerminateConnection(); } break; case KEY_POWER: if (KEY_IQR == pMsg->GPIOStatus) { KEY_DisableIRQ(); uartWriteDebug("tttt", 4); systemState.powerOffFlag = 1; systemState.delayPowerOffTime = 5; // 延时5s 判断是否是按键长按 Util_startClock(&periodicClock_10ms); } else if (KEY_LONG == pMsg->GPIOStatus) { if (1 == systemState.powerOffFlag) { systemState.powerOffFlag = 0; systemState.delayPowerOffTime = 0; wifiPowerOn(); userAppShowCharge(); OLED_ShowString(40,32, "WiCore"); // 启动广播 { uint8_t initialAdvertEnable = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } uartWriteDebug("poweron", 7); } else { //系统断电 wifiPowerDown(); uartWriteDebug("powerdown", 9); OLED_Clear(); systemState.lowBatteryFlag = 0; // 清低电闪烁 systemState.keyUpFlag = 2; // 2 为电源按键 等待按键放开标志,3为 服务器按键 // 有链接,关闭 GAPRole_TerminateConnection(); } systemState.keyShortFlag = 0; // 忽略短按事件 } else if (KEY_LOW == pMsg->GPIOStatus)// 松开 { if (2 == systemState.keyUpFlag) // 长按松开,关机 { systemState.keyUpFlag = 0; //开启外部中断 KEY_EnableIRQ(); { // 关闭广播 uint8_t initialAdvertEnable = FALSE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } Util_stopClock(&periodicClock_10ms); } else if (1 == systemState.keyShortFlag)// 短按松开 产生一次短按完整事件 { //短按事件处理 uartWriteDebug("短按", 4); } } else if (KEY_HIGH == pMsg->GPIOStatus) // 短按 { if (1 == systemState.powerOffFlag) // 等待长按事件 忽略此时的短按事件 { systemState.delayPowerOffTime = 5; // 防止timout 剩2s时又产生长按事件 } else { systemState.keyShortFlag = 1; } } break; default: break; } // Free the space from the message. ICall_free(pMsg); } } #else while (!Queue_empty(keyMsgQueue)) { KEY_stEvt_t *pMsg = (KEY_stEvt_t *)Util_dequeueMsg(keyMsgQueue); if (pMsg) { // Process message. switch(pMsg->GPIOName) { case KEY_NAME_3V3: if (KEY_HIGH == pMsg->GPIOStatus) { wifiPowerOn(); uartWriteDebug("poweron3v3", 10); OLED_ShowString(40,32, "WiCore"); userAppShowCharge(); // 启动广播 { uint8_t initialAdvertEnable = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } systemState.powerOffFlag = 0; } else { wifiPowerDown(); uartWriteDebug("powerdown3v3", 12); // 清低电闪烁 systemState.lowBatteryFlag = 0; OLED_Clear(); // 这个执行时间较长 打乱了定时周期,所以stopClock是没有用的 // 有链接,关闭 GAPRole_TerminateConnection(); systemState.powerOffFlag = 1; } break; case KEY_POWER: if (KEY_LONG == pMsg->GPIOStatus) { if (1 == systemState.powerOffFlag) { systemState.powerOffFlag = 0; systemState.delayPowerOffTime = 0; systemState.keyUpFlag=0; wifiPowerOn(); userAppShowCharge(); OLED_ShowString(40,32, "WiCore"); // 启动广播 { uint8_t initialAdvertEnable = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } uartWriteDebug("poweron", 7); } else { //系统断电 systemState.keyUpFlag=0; systemState.powerOffFlag = 1; wifiPowerDown(); uartWriteDebug("powerdown", 9); OLED_Clear(); systemState.lowBatteryFlag = 0; // 清低电闪烁 // 有链接,关闭 GAPRole_TerminateConnection(); } systemState.keyShortFlag = 0; // 忽略短按事件 } else if (KEY_LOW == pMsg->GPIOStatus)// 松开 { if (1 == systemState.keyShortFlag)// 短按松开 产生一次短按完整事件 { //短按事件处理 uartWriteDebug("短按", 4); systemState.keyShortFlag = 0; } } else if (KEY_HIGH == pMsg->GPIOStatus) // 短按 { if (1 == systemState.powerOffFlag) // 等待长按事件 忽略此时的短按事件 { // 关机中 不处理 } else { systemState.keyShortFlag = 1; } } break; default: break; } // Free the space from the message. ICall_free(pMsg); } } #endif }
/********************************************************************* * @fn simpleTopology_taskFxn * * @brief Application task entry point for the Simple BLE Multi. * * @param a0, a1 - not used. * * @return None. */ static void simpleTopology_taskFxn(UArg a0, UArg a1) { // Initialize application simpleTopology_init(); // Application main loop for (;;) { // Waits for a signal to the semaphore associated with the calling thread. // Note that the semaphore associated with a thread is signaled when a // message is queued to the message receive queue of the thread or when // ICall_signal() function is called onto the semaphore. ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); if (errno == ICALL_ERRNO_SUCCESS) { ICall_EntityID dest; ICall_ServiceEnum src; ICall_HciExtEvt *pMsg = NULL; if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS) { uint8 safeToDealloc = TRUE; if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { ICall_Event *pEvt = (ICall_Event *)pMsg; // Check for BLE stack events first if (pEvt->signature == 0xffff) { if (pEvt->event_flag & SBT_CONN_EVT_END_EVT) { // Try to retransmit pending ATT Response (if any) simpleTopology_sendAttRsp(); } } else { // Process inter-task message safeToDealloc = simpleTopology_processStackMsg((ICall_Hdr *)pMsg); } } if (pMsg && safeToDealloc) { ICall_freeMsg(pMsg); } } // If RTOS queue is not empty, process app message. while (!Queue_empty(appMsgQueue)) { sbtEvt_t *pMsg = (sbtEvt_t *)Util_dequeueMsg(appMsgQueue); if (pMsg) { // Process message. simpleTopology_processAppMsg(pMsg); // Free the space from the message. ICall_free(pMsg); } } } if (events & SBT_START_DISCOVERY_EVT) { events &= ~SBT_START_DISCOVERY_EVT; simpleTopology_startDiscovery(); } } }
/* * ======== Task_setPri ======== */ UInt Task_setPri(Task_Object *tsk, Int priority) { Int oldPri; UInt newMask, tskKey, hwiKey; Queue_Handle newQ; Assert_isTrue((((priority == -1) || (priority > 0) || ((priority == 0 && Task_module->idleTask == NULL))) && (priority < (Int)Task_numPriorities)), Task_A_badPriority); Log_write4(Task_LM_setPri, (UArg)tsk, (UArg)tsk->fxn, (UArg)tsk->priority, (UArg)priority); tskKey = Task_disable(); hwiKey = Hwi_disable(); oldPri = tsk->priority; if (oldPri == priority) { Hwi_restore(hwiKey); Task_restore(tskKey); return (oldPri); } if (priority < 0) { newMask = 0; newQ = Task_Module_State_inactiveQ(); } else { newMask = 1 << priority; newQ = (Queue_Handle)((UInt8 *)(Task_module->readyQ) + (UInt)(priority*(2*sizeof(Ptr)))); } if (tsk->mode == Task_Mode_READY) { Queue_remove((Queue_Elem *)tsk); /* if last task in readyQ, remove corresponding bit in curSet */ if (Queue_empty(tsk->readyQ)) { Task_module->curSet &= ~tsk->mask; } if (Task_module->curTask == tsk) { Task_module->curQ = newQ; /* force a Task_switch() */ /* if no longer maxQ */ /* Put current task at front of its new readyQ */ Queue_insert(((Queue_Elem *)(newQ))->next, (Queue_Elem *)tsk); } else { /* place task at end of its readyQ */ Queue_enqueue(newQ, (Queue_Elem *)tsk); } Task_module->curSet |= newMask; } tsk->priority = priority; tsk->mask = newMask; tsk->readyQ = newQ; if (priority < 0) { Task_module->curQ = NULL; /* force a Task_switch() */ } Task_module->workFlag = 1; Hwi_restore(hwiKey); Task_restore(tskKey); return oldPri; }
/********************************************************************* * @fn glucCollCentral_taskFxn * * @brief Application task entry point for the Glucose collector. * * @param a0, a1 - not used * * @return none */ static void glucCollCentral_taskFxn(UArg a0, UArg a1) { // Initialize application glucCollCentral_Init(); // Application main loop for (;;) { // Waits for a signal to the semaphore associated with the calling thread. // Note that the semaphore associated with a thread is signaled when a // message is queued to the message receive queue of the thread or when // ICall_signal() function is called onto the semaphore. ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); if (errno == ICALL_ERRNO_SUCCESS) { ICall_EntityID dest; ICall_ServiceEnum src; ICall_HciExtEvt *pMsg = NULL; if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS) { if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { // Process inter-task message glucCollCentral_processStackMsg((ICall_Hdr *)pMsg); } if (pMsg) { ICall_freeMsg(pMsg); } } // If RTOS queue is not empty, process app message. while (!Queue_empty(appMsgQueue)) { glucCollEvt_t *pMsg = (glucCollEvt_t *)Util_dequeueMsg(appMsgQueue); if (pMsg) { // Process message. glucCollCentral_processAppMsg(pMsg); // Free the space from the message. ICall_free(pMsg); } } if (events) { if (events & GLUCOLL_PROCEDURE_TIMEOUT_EVT) { events &= ~GLUCOLL_PROCEDURE_TIMEOUT_EVT; if (glucCollState == BLE_STATE_CONNECTED) { // disconnect glucCollState = BLE_STATE_DISCONNECTING; GAPCentralRole_TerminateLink(glucCollConnHandle); LCD_WRITE_STRING("Timeout", LCD_PAGE0); LCD_WRITE_STRING("", LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); } } if (events & GLUCOLL_START_DISCOVERY_EVT) { events &= ~GLUCOLL_START_DISCOVERY_EVT; if (glucCollPairingStarted) { // Postpone discovery until pairing completes glucCollDiscPostponed = TRUE; } else { glucCollCentral_startDiscovery(); } } } } } }
/* * ======== Event_pend ======== */ UInt Event_pend(Event_Object *event, UInt andMask, UInt orMask, UInt32 timeout) { UInt hwiKey, tskKey; Event_PendElem elem; UInt matchingEvents; Queue_Handle pendQ; Clock_Struct clockStruct; Assert_isTrue(((andMask | orMask) != 0), Event_A_nullEventMasks); Log_write5(Event_LM_pend, (UArg)event, (UArg)event->postedEvents, (UArg)andMask, (UArg)orMask, (IArg)((Int)timeout)); /* * elem is filled in entirely before interrupts are disabled. * This significantly reduces latency at the potential cost of wasted time * if it turns out that there is already an event match. */ /* add Clock event if timeout is not FOREVER nor NO_WAIT */ if (BIOS_clockEnabled && (timeout != BIOS_WAIT_FOREVER) && (timeout != BIOS_NO_WAIT)) { Clock_addI(Clock_handle(&clockStruct), (Clock_FuncPtr)Event_pendTimeout, timeout, (UArg)&elem); elem.tpElem.clock = Clock_handle(&clockStruct); elem.pendState = Event_PendState_CLOCK_WAIT; } else { elem.tpElem.clock = NULL; elem.pendState = Event_PendState_WAIT_FOREVER; } /* fill in this task's Event_PendElem */ elem.andMask = andMask; elem.orMask = orMask; pendQ = Event_Instance_State_pendQ(event); /* get task handle */ elem.tpElem.task = Task_self(); /* Atomically check for a match and block if none */ hwiKey = Hwi_disable(); /* check if events are already available */ matchingEvents = Event_checkEvents(event, andMask, orMask); if (matchingEvents != 0) { /* remove Clock object from Clock Q */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_removeI(elem.tpElem.clock); elem.tpElem.clock = NULL; } Hwi_restore(hwiKey); return (matchingEvents);/* yes, then return with matching bits */ } if (timeout == BIOS_NO_WAIT) { Hwi_restore(hwiKey); return (0); /* No match, no wait */ } Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task), Event_A_badContext); /* * Verify that THIS core hasn't already disabled the scheduler * so that the Task_restore() call below will indeed block */ Assert_isTrue((Task_enabled()), Event_A_pendTaskDisabled); /* lock scheduler */ tskKey = Task_disable(); /* only one Task allowed!!! */ Assert_isTrue(Queue_empty(pendQ), Event_A_eventInUse); /* leave a pointer for Task_delete() */ elem.tpElem.task->pendElem = (Task_PendElem *)&(elem); /* add it to Event_PendElem queue */ Queue_enqueue(pendQ, (Queue_Elem *)&elem); Task_blockI(elem.tpElem.task); if (BIOS_clockEnabled && (elem.pendState == Event_PendState_CLOCK_WAIT)) { Clock_startI(elem.tpElem.clock); } Hwi_restore(hwiKey); /* unlock task scheduler and block */ Task_restore(tskKey); /* the calling task will switch out here */ /* Here on unblock due to Event_post or Event_pendTimeout */ hwiKey = Hwi_disable(); /* remove Clock object from Clock Q */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_removeI(elem.tpElem.clock); elem.tpElem.clock = NULL; } elem.tpElem.task->pendElem = NULL; Hwi_restore(hwiKey); /* event match? */ if (elem.pendState != Event_PendState_TIMEOUT) { return (elem.matchingEvents); } else { return (0); /* timeout */ } }
/********************************************************************* * @fn HeartRate_taskFxn * * @brief Application task entry point for the Heart Rate. * * @param none * * @return none */ static void HeartRate_taskFxn(UArg a0, UArg a1) { // Initialize the application. HeartRate_init(); // Application main loop. for(;;) { // Waits for a signal to the semaphore associated with the calling thread. // Note that the semaphore associated with a thread is signaled when a // message is queued to the message receive queue of the thread or when the // ICall_signal() function is called on the thread's respective semaphore. ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); if (errno == ICALL_ERRNO_SUCCESS) { ICall_EntityID dest; ICall_ServiceEnum src; ICall_HciExtEvt *pMsg = NULL; if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS) { if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { // Process inter-task message. HeartRate_processStackMsg((ICall_Hdr *)pMsg); } if (pMsg) { ICall_freeMsg(pMsg); } } } // If RTOS queue is not empty, process app message. while (!Queue_empty(appMsgQueue)) { heartRateEvt_t *pMsg = (heartRateEvt_t*)Util_dequeueMsg(appMsgQueue); if (pMsg) { // Process message. HeartRate_processAppMsg(pMsg); // Free the space from the message. ICall_free(pMsg); } } // Heart rate service periodic task. if (events & HEARTRATE_MEAS_PERIODIC_EVT) { events &= ~HEARTRATE_MEAS_PERIODIC_EVT; HeartRate_measPerTask(); } // Battery service periodic task. if (events & HEARTRATE_BATT_PERIODIC_EVT) { events &= ~HEARTRATE_BATT_PERIODIC_EVT; HeartRate_battPerTask(); } } }
/* * ======== Task_Instance_finalize ======== */ Void Task_Instance_finalize(Task_Object *tsk, Int status) { #ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS Int i, cnt; #endif UInt taskKey, hwiKey; /* * Task's can only be deleted from main and task threads. * Running Tasks can not be deleted. */ if (status == 0) { taskKey = Task_disable(); /* * Bar users from calling Task_delete() on terminated tasks * if deleteTerminatedTasks is enabled. */ if ((Task_deleteTerminatedTasks == TRUE) && (Task_getMode(tsk) == Task_Mode_TERMINATED) && (tsk->readyQ == Task_Module_State_terminatedQ())) { Error_raise(NULL, Task_E_deleteNotAllowed, tsk, 0); } Assert_isTrue((Task_getMode(tsk) != Task_Mode_RUNNING), Task_A_badTaskState); Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Main) || (BIOS_getThreadType() == BIOS_ThreadType_Task), Task_A_badThreadType); hwiKey = Hwi_disable(); if (tsk->mode == Task_Mode_READY) { /* remove task from its ready list */ Queue_remove((Queue_Elem *)tsk); /* if last task in readyQ, remove corresponding bit in curSet */ if (Queue_empty(tsk->readyQ)) { Task_module->curSet &= ~tsk->mask; } /* * if task was made ready by a pend timeout but hasn't run yet * then its clock object is still on the Clock service Q. */ if (tsk->pendElem != NULL) { if (BIOS_clockEnabled && tsk->pendElem->clock) { Clock_removeI(tsk->pendElem->clock); } } } if (tsk->mode == Task_Mode_BLOCKED) { Assert_isTrue(tsk->pendElem != NULL, Task_A_noPendElem); /* Seemingly redundant test in case Asserts are disabled */ if (tsk->pendElem != NULL) { Queue_remove(&(tsk->pendElem->qElem)); if (BIOS_clockEnabled && tsk->pendElem->clock) { Clock_removeI(tsk->pendElem->clock); } } } if (tsk->mode == Task_Mode_TERMINATED) { /* remove task from terminated task list */ Queue_remove((Queue_Elem *)tsk); } else { Task_processVitalTaskFlag(tsk); } Hwi_restore(hwiKey); Task_restore(taskKey); } /* return if failed before allocating stack */ if (status == 1) { return; } if (BIOS_runtimeCreatesEnabled) { /* free stack if it was allocated dynamically */ if (tsk->stackHeap != (xdc_runtime_IHeap_Handle)(-1)) { Memory_free(tsk->stackHeap, tsk->stack, tsk->stackSize); } } /* return if failed to allocate Hook Env */ if (status == 2) { return; } /* status == 0 or status == 3 - in both cases create hook was called */ #ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS /* free any allocated Hook Envs */ if (Task_hooks.length > 0) { if (status == 0) { cnt = Task_hooks.length; } else { cnt = status - 3; /* # successful createFxn() calls */ } /* * only call deleteFxn() if createFxn() was successful */ for (i = 0; i < cnt; i++) { if (Task_hooks.elem[i].deleteFxn != NULL) { Task_hooks.elem[i].deleteFxn(tsk); } } Memory_free(Task_Object_heap(), tsk->hookEnv, Task_hooks.length * sizeof (Ptr)); } #endif }
/********************************************************************* * @fn simpleTopology_taskFxn * * @brief Application task entry point for the Simple BLE Multi. * * @param a0, a1 - not used. * * @return None. */ static void simpleTopology_taskFxn(UArg a0, UArg a1) { // Initialize application simpleTopology_init(); // Application main loop for (;;) { // Waits for a signal to the semaphore associated with the calling thread. // Note that the semaphore associated with a thread is signaled when a // message is queued to the message receive queue of the thread or when // ICall_signal() function is called onto the semaphore. ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); if (errno == ICALL_ERRNO_SUCCESS) { ICall_EntityID dest; ICall_ServiceEnum src; ICall_HciExtEvt *pMsg = NULL; if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS) { uint8 safeToDealloc = TRUE; if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { // Process inter-task message safeToDealloc = simpleTopology_processStackMsg((ICall_Hdr *)pMsg); } if (pMsg && safeToDealloc) { ICall_freeMsg(pMsg); } } // If RTOS queue is not empty, process app message. while (!Queue_empty(appMsgQueue)) { sbtEvt_t *pMsg = (sbtEvt_t *)Util_dequeueMsg(appMsgQueue); if (pMsg) { // Process message. simpleTopology_processAppMsg(pMsg); // Free the space from the message. ICall_free(pMsg); } } } // the trigger was a periodic event // trigger was the SCAN_EVENT if (!!(events & SCAN_EVENT)) { // effectively mark off the event as "handled" events &= ~SCAN_EVENT; // now start discovery. // CJ: I think that the scan parameters are set in such a way // that it will start and stop itself scanningStarted = true; GAPRole_StartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); } } }
Void Swi_schedule() { Queue_Handle curQ, maxQ; Swi_Object *swi; UInt hwiKey; UInt tskKey; Char *oldTaskSP; volatile Bool taskEnabled; /* Remember current Swi priority */ curQ = Swi_module->curQ; hwiKey = Hwi_disable(); /* required for Swi's posted from Tasks */ /* determine current highest priority Q */ maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); if (maxQ > curQ) { if (BIOS_taskEnabled) { tskKey = TASK_DISABLE(); /* required for Swi's posted from Tasks */ /* Switch to HWI stack if not already on it */ oldTaskSP = ti_sysbios_family_xxx_Hwi_switchToIsrStack(); /* must refresh local variables after stack switch */ /* refresh curQ */ curQ = Swi_module->curQ; /* refresh maxQ */ maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); /* set local variable inited after stack switch */ taskEnabled = TRUE; } else { taskEnabled = FALSE; } /* * Run all Swis of higher priority than * the current Swi priority. * Will pre-empt any currently running swi. */ do { swi = (Swi_Object *)Queue_dequeue(maxQ); /* remove from curSet if last one in this ready list */ if (Queue_empty(maxQ)) { Swi_module->curSet &= ~swi->mask; } Swi_run(swi); if (Swi_module->curSet == 0) { break; } maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); } while (maxQ > curQ); /* check local variable inited after stack switch */ if (taskEnabled) { /* Switch back to Task stack if at bottom of HWI stack */ ti_sysbios_family_xxx_Hwi_switchToTaskStack(oldTaskSP); } /* MUST(!) unlock the scheduler before enabling interrupts */ Swi_module->locked = FALSE; Hwi_restore(hwiKey); if (BIOS_taskEnabled) { TASK_RESTORE(tskKey); } } else { Swi_module->locked = FALSE; Hwi_restore(hwiKey); } }