// Handle command event processing. void commandProcessingThread(void const *argument) { UINT8 currentIndex; for (;;) { // Wait for a command message. osEvent commandEvent = osMessageGet(commandQueue, osWaitForever); // Is this a command event? if (commandEvent.status == osEventMessage) { // Point to the message. commandMessage *message = (commandMessage *) commandEvent.value.p; // Execute all the commands currentIndex = 0; while (currentIndex < message->length) { currentIndex += handleCommand(message, currentIndex); } // Free the message. osPoolFree(commandMemPool, message); } } }
/**@brief Thread for handling the Application's BLE Stack events. * * @details This thread is responsible for handling BLE Stack events sent from on_ble_evt(). * * @param[in] arg Pointer used for passing some arbitrary information (context) from the * osThreadCreate() call to the thread. */ void ble_stack_thread(void const * arg) { uint32_t err_code; osEvent evt; ble_evt_t * p_ble_evt; UNUSED_PARAMETER(arg); while (1) { evt = osMessageGet(ble_stack_msg_box, osWaitForever); // wait for message if (evt.status == osEventMessage) { p_ble_evt = evt.value.p; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; default: // No implementation needed. break; } (void)osPoolFree(ble_evt_pool, p_ble_evt); } } }
/** * @brief Free a memory block from a mail * @param queue_id mail queue ID obtained with \ref osMailCreate. * @param mail pointer to the memory block that was obtained with \ref osMailGet. * @retval status code that indicates the execution status of the function. * @note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. */ osStatus osMailFree (osMailQId queue_id, void *mail) { if (queue_id == NULL) { return osErrorParameter; } return osPoolFree(queue_id->pool, mail); }
/* * Free socket and os buffer */ void sockPoolFree(sockPool* SockPool) { if(SockPool == NULL) return; if(SockPool->sockNo > _WIZCHIP_SOCK_NUM_) return; SockStatus &= (unsigned char)(~(1<<SockPool->sockNo)); close(SockPool->sockNo); osPoolFree(NetMemPoolId,SockPool); }
/**@brief Thread for handling the Application's BLE Stack events. * * @details This thread is responsible for handling BLE Stack events sended from on_ble_evt(). * * @param[in] arg Pointer used for passing some arbitrary information (context) from the * osThreadCreate() call to the thread. */ void ble_stack_thread(void const * arg) { uint32_t err_code; osEvent evt; ble_evt_t * p_ble_evt; UNUSED_PARAMETER(arg); while (1) { evt = osMessageGet(ble_stack_msg_box, osWaitForever); // wait for message if (evt.status == osEventMessage) { p_ble_evt = evt.value.p; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // enable buttons to wake-up from power off bsp_buttons_enable( (1 << WAKEUP_BUTTON_ID) | (1 << BOND_DELETE_ALL_BUTTON_ID) ); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } (void)osPoolFree(ble_evt_pool, p_ble_evt); } } }
// Receive the 'data' in the Message 'queue'. Returns 1 if a message was received, 0 otherwise. int receive_message(float * data, osMessageQId queue){ osEvent evt = osMessageGet(queue, 0); if (evt.status == osEventMessage) { Message* msg = ((Message *)evt.value.p); *data = msg->data; osPoolFree(mem_pool, msg); return 1; } return 0; }
/**************************************************************************//** * @brief * Thread 1: Print LCD thread - modified to not use LCD *****************************************************************************/ void PrintLcdThread(void const *argument) { lcdText_t *rptr; osEvent evt; (void) argument; /* Unused parameter. */ while (1) { /* Wait for message */ evt = osMessageGet(msgBox, osWaitForever); if (evt.status == osEventMessage) { rptr = evt.value.p; /* Free memory allocated for message */ osPoolFree(mpool, rptr); } } }
/*---------------------------------------------------------------------------- * Thread 2: Receive thread *---------------------------------------------------------------------------*/ void recv_thread (void const *argument) { T_MEAS *rptr; osEvent evt; for (;;) { evt = osMessageGet(MsgBox, osWaitForever); /* wait for message */ if (evt.status == osEventMessage) { rptr = evt.value.p; printf ("\nVoltage: %.2f V\n",rptr->voltage); printf ("Current: %.2f A\n",rptr->current); printf ("Number of cycles: %d\n",(int)rptr->counter); #ifdef __USE_FFLUSH fflush (stdout); #endif osPoolFree(mpool,rptr); /* free memory allocated for message */ } } }
/** * @brief Wait for a generic message in the queue and copy out the generic message upon arrival * @param msgQ: Message Q to send the message to * @param *messagePtr: Pointer to a generic message struct * @param timeout: How long the operating system must wait until the message is successfully placed in message Q msgQ */ void fetchMessage(osMessageQId msgQ, msg_genericMessage_t *messagePtr, uint32_t timeout) { osEvent messageEvent; msg_genericMessage_t *messageRxPtr; // Wait for a message in the message Q, msgQ messageEvent = osMessageGet(msgQ, timeout); // If the recieved data is a message if (messageEvent.status == osEventMessage) { // Grab the pointer to the generic message and copy it into the externally declared message struct messageRxPtr = messageEvent.value.p; memcpy(messagePtr, messageRxPtr, sizeof(msg_genericMessage_t)); // Then free the message from the global memory pool osPoolFree(genericMPool, messageRxPtr); } else { // If there was no message received after the timeout value, set the type to NULL to indicate this messagePtr->messageType = MSG_TYPE_NO_MESSAGE; } }
/* * Allocate socket and os buffer */ sockPool* sockPoolAlloc(void) { int i; sockPool *eth; osMutexWait(sockMutexId,osWaitForever); eth = (sockPool*)osPoolCAlloc(NetMemPoolId); if(eth != NULL){ for(i = 0 ; i < _WIZCHIP_SOCK_NUM_ ; i++) { if(SockStatus & (1<<i)) continue; else { SockStatus |= (1<<i); eth->sockNo = i; osMutexRelease(sockMutexId); return eth; } } } osPoolFree(NetMemPoolId,eth); osMutexRelease(sockMutexId); return eth; }
/* 过零点触发中断 回调函数 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin != ZERO) return; bool wave_is_rise; // 读Pin,判断是上升沿还是下降沿 if (HAL_GPIO_ReadPin(PORT_ZERO, ZERO) == GPIO_PIN_RESET) { wave_is_rise = true; } else { wave_is_rise = false; } // t 顺序: 1 3 4 6 // 上升沿 if (wave_is_rise) { t4 = __HAL_TIM_GET_COUNTER(&htim3); // 上升沿是否valid? // if (!it_is_valid(t4_prev, t4)) { // t4_prev = t4; // r++; // return; // } //r++; } else { // 下降沿 t6 = __HAL_TIM_GET_COUNTER(&htim3); // 下降沿是否valid? // if (!it_is_valid(t6_prev, t6)) { // t6_prev = t6; // f++; // return; // } //f++; } if (wave_is_rise) // 只在波谷计算,否则退出 return; is_lower_blow = true; // 设置波谷flag is_lower_exchange = true; is_lower_feed = true; /* 下降沿时计算下一个零点 */ // t2 if (t3 < t1) t2 = (0xffff + t1 + t3) / 2; else t2 = (t1 + t3) / 2; // t5 if (t6 < t4) t5 = (0xffff + t4 + t6) / 2; else t5 = (t4 + t6) / 2; // 交流电源周期 if (t5 < t2) T1 = 0xffff + t5 - t2; else T1 = t5 - t2; // 下一个零点 if (t5 < t4) t7 = t5 + 0xffff - t4 + (T1 / 4); /* 计算不对 ! */ else t7 = t5 - t4 + (T1 / 4); // counter++; // if (counter >=299) { // //printf("t4:%d,t5:%d,t6:%d,t7:%d,T1:%d\r\n", t4,t5,t6,t7,T1); // printf("delay:%d\r\n", t7 + TOTAL_TIME - triac_cur.fan_smoke_delay * 100); // counter = 0; // } // 更新数值 t1 = t4; t2 = t5; t3 = t6; // 计数器复位 __HAL_TIM_SET_COUNTER (&htim1, 0); __HAL_TIM_SET_COUNTER (&htim4, 0); // 检查Q_Triac队列,更新输出的控制状态 if (Q_TriacHandle != NULL) { // 读取值 osEvent evt = osMessageGet(Q_TriacHandle, 0); if (evt.status == osEventMessage) { triac_cur = *((Triac *)evt.value.p); // 更新送料duty on_count = triac_cur.feed_duty * 100; off_count = 1000 - on_count; // 10s = 10000ms 10000 / 10 = 1000 // 返还内存 osStatus status = osPoolFree(pool_TriacHandle, evt.value.p); if (status != osOK) printf("Free Triac memory error:%x\r\n", status); } } // 设置period __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, t7 + TOTAL_TIME - triac_cur.fan_smoke_delay * 100); // 80÷100×10×1000 = 80×100 __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, t7 + TOTAL_TIME - triac_cur.fan_exchange_delay * 100); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, t7); /* 输出: 条件判断 */ HAL_StatusTypeDef status; //排烟通道 if (triac_cur.fan_smoke_is_on) { status = HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_1); if (status != HAL_OK) printf("time4 c1 failed at zero:%x\r\n", status); } //循环通道 if (triac_cur.fan_exchange_is_on) { status = HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_2); if (status != HAL_OK) printf("time4 c2 failed:%x\r\n", status); } //送料通道 ON计数 OFF计数 if (triac_cur.feed_is_on) { // 送料 if (running_feed) { if (on_cnt < on_count) { // 输出 送料: On HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_3); on_cnt++; } else { on_cnt = 0; off_cnt = 0; running_feed = false; waiting_feed = true; } } // 不送料 if (waiting_feed) { off_cnt ++; if (off_cnt >= off_count) { on_cnt = 0; off_cnt = 0; running_feed = true; waiting_feed = false; } } } // }
/* 过零点触发中断 回调函数 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin != ZERO) return; bool rising_edge; // 读Pin,判断是上升沿还是下降沿 if (HAL_GPIO_ReadPin(PORT_ZERO, ZERO) == GPIO_PIN_SET) { rising_edge = true; } else { rising_edge = false; } // t 顺序: 1 3 4 6 // 上升沿 if (rising_edge) { t6 = __HAL_TIM_GET_COUNTER(&htim3); } else { // 下降沿 t4 = __HAL_TIM_GET_COUNTER(&htim3); } if (!rising_edge) // 只在波谷计算,否则退出 return; /*----------------------------------------------------------------------------*/ is_lower_blow = true; // 设置波谷flag is_lower_exchange = true; is_lower_feed = true; /* 下降沿时计算下一个零点 */ // t1 t3 t4 t6 if ((t1<t3) && (t3<t4) && (t4<t6)) { t2 = (t1+t3) / 2; t5 = (t4+t6) / 2; } else if(t3<t1) { t2 = (t1+t3+0xffff) / 2; t5 = (t4+t6)/2 + 0xffff; } else if(t4<t3) { t2 = (t1+t3) / 2; t5 = (t4+t6)/2 + 0xffff; } else if(t6<t4) { t2 = (t1+t3) / 2; t5 = (t4+t6+0xffff) / 2; } T1 = t5 - t2; // 下一个零点 if (t6<t5) { t7 = t5 + T1/4 - t6 -0xffff; } else { t7 = t5 + T1/4 - t6; } // debug // counter++; // if (counter >= 149) { // Zero *z; // z = (Zero*)osPoolAlloc(pool_ZeroHandle); // if (z!=NULL) { // z->t1 = t1; // z->t3 = t3; // z->t4 = t4; // z->t6 = t6; // z->t7 = t7; // z->T1 = T1; // osMessagePut(Q_ErrorHandle, (uint32_t)z, 0); // } // // counter = 0; // } // // 更新数值 t1 = t4; t3 = t6; /*--------------------------------------------------------------------------*/ // 只处理下半波 if (t7 == 0) { t7 = 220; } is_lower_blow = true; // 设置波谷flag is_lower_exchange = true; is_lower_feed = true; //uint32_t compare = 0; // 检查Q_Triac队列,更新输出的控制状态 if (Q_TriacHandle != NULL) { // 读取值 osEvent evt = osMessageGet(Q_TriacHandle, 0); if (evt.status == osEventMessage) { Triac *p = (Triac *)evt.value.p; triac_cur.fan_exchange_delay = p->fan_exchange_delay; triac_cur.fan_exchange_is_on = p->fan_exchange_is_on; triac_cur.fan_smoke_is_on = p->fan_smoke_is_on; triac_cur.fan_smoke_power = p->fan_smoke_power; triac_cur.feed_by_manual = p->feed_by_manual; triac_cur.feed_duty = p->feed_duty; triac_cur.feed_full = p->feed_full; triac_cur.feed_is_on = p->feed_is_on; // 更新送料duty if (triac_cur.feed_duty != 0) { // 500×triac_cur.feed_duty÷100 on_count = 5 * triac_cur.feed_duty; off_count = 500 - on_count; // 10s = 10000ms 10000 / 20 = 500 } // 返还内存 osStatus status = osPoolFree(pool_TriacHandle, evt.value.p); if (status != osOK) printf("Free Triac memory error:%x\r\n", status); } } /*----------------------------------------------------------------------------*/ // 设置period if (triac_cur.fan_smoke_power == 0) { triac_cur.fan_smoke_power = 60; } // 最低延时2.5ms,最高延时6ms uint32_t delay = t7 + triac_cur.fan_smoke_power; if (delay>8999) { delay = last_delay; } else { last_delay = delay; } // 计数器复位 __HAL_TIM_SET_COUNTER (&htim2, 0); __HAL_TIM_SET_COUNTER (&htim4, 0); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, delay); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, t7+T1/4); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, t7+T1/4); /* 输出: 条件判断 */ //排烟通道 if (triac_cur.fan_smoke_is_on) { __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC1); } //循环通道 if (triac_cur.fan_exchange_is_on) { __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC2); } //送料通道 if ((triac_cur.feed_by_manual || triac_cur.feed_full) && (!triac_cur.feed_is_on)) { __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC3); } //送料通道 ON计数 OFF计数 if (triac_cur.feed_is_on && (!triac_cur.feed_by_manual)) { // 0 // 送料 if (feed_run) { __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC3); count_feed ++; if (count_feed >= on_count) { count_feed = 0; feed_run = false; } } else { // 不送料 count_feed ++; if (count_feed >= off_count) { count_feed = 0; feed_run = true; } } } // if 0 }