static void PIOS_USB_HID_SendReport(struct pios_usb_hid_dev * usb_hid_dev) { uint16_t bytes_to_tx; if (!usb_hid_dev->tx_out_cb) { return; } bool need_yield = false; #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context, &usb_hid_dev->tx_packet_buffer[1], sizeof(usb_hid_dev->tx_packet_buffer)-1, NULL, &need_yield); #else bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context, &usb_hid_dev->tx_packet_buffer[2], sizeof(usb_hid_dev->tx_packet_buffer)-2, NULL, &need_yield); #endif if (bytes_to_tx == 0) { return; } /* Always set type as report ID */ usb_hid_dev->tx_packet_buffer[0] = 1; #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer, GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep), bytes_to_tx + 1); #else usb_hid_dev->tx_packet_buffer[1] = bytes_to_tx; UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer, GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep), bytes_to_tx + 2); #endif /* Is this correct? Why do we always send the whole buffer? */ SetEPTxCount(usb_hid_dev->cfg->data_tx_ep, sizeof(usb_hid_dev->tx_packet_buffer)); SetEPTxValid(usb_hid_dev->cfg->data_tx_ep); #if defined(PIOS_INCLUDE_FREERTOS) if (need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ }
/** * RxThread */ void PIOS_UDP_RxThread(void * udp_dev_n) { /* needed because of FreeRTOS.posix scheduling */ sigset_t set; sigfillset(&set); sigprocmask(SIG_BLOCK, &set, NULL); pios_udp_dev * udp_dev = (pios_udp_dev*) udp_dev_n; /** * com devices never get closed except by application "reboot" * we also never give up our mutex except for waiting */ while(1) { /** * receive */ int received; udp_dev->clientLength=sizeof(udp_dev->client); if ((received = recvfrom(udp_dev->socket, &udp_dev->rx_buffer, PIOS_UDP_RX_BUFFER_SIZE, 0, (struct sockaddr *) &udp_dev->client, (socklen_t*)&udp_dev->clientLength)) >= 0) { /* copy received data to buffer if possible */ /* we do NOT buffer data locally. If the com buffer can't receive, data is discarded! */ /* (thats what the USART driver does too!) */ bool rx_need_yield = false; if (udp_dev->rx_in_cb) { (void) (udp_dev->rx_in_cb)(udp_dev->rx_in_context, udp_dev->rx_buffer, received, NULL, &rx_need_yield); } #if defined(PIOS_INCLUDE_FREERTOS) if (rx_need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ } } }
static void PIOS_USART_generic_irq_handler(uint32_t usart_id) { struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id; bool valid = PIOS_USART_validate(usart_dev); PIOS_Assert(valid); /* Force read of dr after sr to make sure to clear error flags */ volatile uint16_t sr = usart_dev->cfg->regs->SR; volatile uint8_t dr = usart_dev->cfg->regs->DR; /* Check if RXNE flag is set */ bool rx_need_yield = false; if (sr & USART_SR_RXNE) { uint8_t byte = dr; if (usart_dev->rx_in_cb) { (void) (usart_dev->rx_in_cb)(usart_dev->rx_in_context, &byte, 1, NULL, &rx_need_yield); } } /* Check if TXE flag is set */ bool tx_need_yield = false; if (sr & USART_SR_TXE) { if (usart_dev->tx_out_cb) { uint8_t b; uint16_t bytes_to_send; bytes_to_send = (usart_dev->tx_out_cb)(usart_dev->tx_out_context, &b, 1, NULL, &tx_need_yield); if (bytes_to_send > 0) { /* Send the byte we've been given */ usart_dev->cfg->regs->DR = b; } else { /* No bytes to send, disable TXE interrupt */ USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE); } } else { /* No bytes to send, disable TXE interrupt */ USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE); } } #if defined(PIOS_INCLUDE_FREERTOS) if (rx_need_yield || tx_need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ }
void ADCIntHandler(){ ADCIntClear(ADC0_BASE, 0); // Limpia el flag de interrupcion del ADC uint32_t potenciometros[3]; BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; // leemos los datos del secuenciador ADCSequenceDataGet(ADC0_BASE, 0, potenciometros); //Enviamos el dato a la tarea xQueueSendFromISR( potQueue,potenciometros,&xHigherPriorityTaskWoken); if(xHigherPriorityTaskWoken == pdTRUE){ vPortYieldFromISR(); } }
static osa_status_t OSA_MessageQueuePutFromISR(msg_queue_handler_t handler, void* pMessage) { portBASE_TYPE taskToWake = pdFALSE; if (pdTRUE == xQueueSendToBackFromISR(handler, pMessage, &taskToWake)) { if (pdTRUE == taskToWake) { vPortYieldFromISR(); } return kStatus_OSA_Success; } else { return kStatus_OSA_Error; } }
static osa_status_t OSA_SemaphorePostFromISR(semaphore_t *pSem) { portBASE_TYPE taskToWake = pdFALSE; if (pdTRUE==xSemaphoreGiveFromISR(*pSem, &taskToWake)) { if (pdTRUE == taskToWake) { vPortYieldFromISR(); } return kStatus_OSA_Success; } else { return kStatus_OSA_Error; } }
static Void callback_ToHost(VirtQueue_Handle vq) { UInt16 avail; int i; Bool doSwitch[portNUM_PROCESSORS]; unsigned portBASE_TYPE curCpu = portGetCurrentCPU(); taskENTER_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock); if(listLIST_IS_EMPTY(&availBufList) != pdFALSE){ taskEXIT_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock); return; } if((avail = GET_AVAIL_COUNT(vq)) == 0){ taskEXIT_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock); return; } memset(doSwitch, FALSE, sizeof(doSwitch)); do{ signed portBASE_TYPE ret; /* Because this function is not an application code, */ /* there is not the problem with using xTaskRemoveFromEventList. */ ret = xTaskRemoveFromEventList(&availBufList, pdFALSE); if(ret >= 0){ doSwitch[ret] = TRUE; } } while(--avail > 0); taskEXIT_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock); for(i = 0; i < portNUM_PROCESSORS; i++){ if(doSwitch[i]){ if(i == (int)curCpu){ vPortYieldFromISR(); } else{ portINTERRUPT_CORE(i); } } } }
static Void callback_FromHost(VirtQueue_Handle vq) { Int16 token; MessageQCopy_Msg msg; Bool usedBufAdded = FALSE; Int len; portBASE_TYPE switchCpu; Bool doSwitch[portNUM_PROCESSORS]; int i; memset(doSwitch, FALSE, sizeof(doSwitch)); taskENTER_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock); /* Process all available buffers: */ while((token = VirtQueue_getAvailBuf(vq, (Void **)&msg, &len)) >= 0){ if(!MessageQCopy_SendToTask(token, msg, &switchCpu)){ VirtQueue_addUsedBuf(vq, token, RP_MSG_BUF_SIZE); usedBufAdded = TRUE; } else if(switchCpu >= 0){ doSwitch[switchCpu] = TRUE; } } if(usedBufAdded){ /* Tell host we've processed the buffers: */ VirtQueue_kick(vq); } taskEXIT_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock); for(i = 0; i < portNUM_PROCESSORS; i++){ unsigned portBASE_TYPE curCpu = portGetCurrentCPU(); if(doSwitch[i]){ if(i == (Int)curCpu){ vPortYieldFromISR(); } else{ portINTERRUPT_CORE(i); } } } }
/*FUNCTION********************************************************************** * * Function Name : OSA_EventSet * Description : Set one or more event flags of an event object. * Return kStatus_OSA_Success if set successfully, kStatus_OSA_Error if failed. * *END**************************************************************************/ osa_status_t OSA_EventSet(event_t *pEvent, event_flags_t flagsToSet) { assert(pEvent); portBASE_TYPE taskToWake = pdFALSE; if (__get_IPSR()) { xEventGroupSetBitsFromISR(pEvent->eventHandler, flagsToSet, &taskToWake); if (pdTRUE == taskToWake) { vPortYieldFromISR(); } } else { xEventGroupSetBits(pEvent->eventHandler, flagsToSet); } return kStatus_OSA_Success; }
void EXTI0_IRQHandler(void) { long taskWoken = 0; if (EXTI_GetITStatus(EXTI_Line0) != RESET) { bool isRisingEdge = digitalRead(GPIO_PA0); //digitalWrite(GPIO_PD11, isRisingEdge); if (isRisingEdge) { lastMicros = micros(); } else { ultrasound_duration = micros() - lastMicros; if (ultrasound_duration > MAX_ULTRASOUND_DURATION_US) ultrasound_duration = MAX_ULTRASOUND_DURATION_US; xSemaphoreGiveFromISR(sensorReadSignal, &taskWoken); } EXTI_ClearITPendingBit(EXTI_Line0); } if (taskWoken) vPortYieldFromISR(); }
/** * Take data from the PIOS_COM buffer and transfer it to the currently inactive DMA * circular buffer */ static void PIOS_OVERO_WriteData(struct pios_overo_dev *overo_dev) { // TODO: How do we protect against the DMA buffer swapping midway through adding data // to this buffer. If we were writing at the beginning it could cause a weird race. if (overo_dev->tx_out_cb) { int32_t max_bytes = PACKET_SIZE - overo_dev->writing_offset; if (max_bytes > 0) { uint16_t bytes_added; bool tx_need_yield = false; uint8_t *writing_pointer = &overo_dev->tx_buffer[overo_dev->writing_buffer][overo_dev->writing_offset]; bytes_added = (overo_dev->tx_out_cb)(overo_dev->tx_out_context, writing_pointer, max_bytes, NULL, &tx_need_yield); #if defined(OVERO_USES_BLOCKING_WRITE) if (tx_need_yield) { vPortYieldFromISR(); } #endif overo_dev->writing_offset += bytes_added; } } }
void EINT3_IRQHandler(void) { static signed portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; if(LPC_GPIOINT->IO0IntStatF & (1<<4)) { contarTicks = 0; } else if (LPC_GPIOINT->IO0IntStatR & (1<<4)) { contarTicks = contarTicks / portTICK_RATE_MS; xQueueSendFromISR(cola, &contarTicks, &xHigherPriorityTaskWoken); contarTicks = -1; } LPC_GPIOINT->IO0IntClr = 1<<4; // Si la tarea asociada tiene mayor prioridad que la que //se esta ejecutando if(xHigherPriorityTaskWoken == pdTRUE) // se realiza un cambio de contexto manualmente //(no se pasa por el scheduler). vPortYieldFromISR (); }
/** * EP1 OUT Callback Routine */ static void PIOS_USB_HID_EP_OUT_Callback(void) { struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)pios_usb_hid_id; bool valid = PIOS_USB_HID_validate(usb_hid_dev); PIOS_Assert(valid); uint32_t DataLength; /* Read received data (63 bytes) */ /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(usb_hid_dev->cfg->data_rx_ep); if (DataLength > sizeof(usb_hid_dev->rx_packet_buffer)) { DataLength = sizeof(usb_hid_dev->rx_packet_buffer); } /* Use the memory interface function to read from the selected endpoint */ PMAToUserBufferCopy((uint8_t *) usb_hid_dev->rx_packet_buffer, GetEPRxAddr(usb_hid_dev->cfg->data_rx_ep), DataLength); if (!usb_hid_dev->rx_in_cb) { /* No Rx call back registered, disable the receiver */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK); return; } /* The first byte is report ID (not checked), the second byte is the valid data length */ uint16_t headroom; bool need_yield = false; #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context, &usb_hid_dev->rx_packet_buffer[1], sizeof(usb_hid_dev->rx_packet_buffer)-1, &headroom, &need_yield); #else (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context, &usb_hid_dev->rx_packet_buffer[2], usb_hid_dev->rx_packet_buffer[1], &headroom, &need_yield); #endif #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1; #else uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2; #endif if (headroom >= max_payload_length) { /* We have room for a maximum length message */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID); } else { /* Not enough room left for a message, apply backpressure */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK); } #if defined(PIOS_INCLUDE_FREERTOS) if (need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ }
/** * EP1 OUT Callback Routine */ static bool PIOS_USB_HID_EP_OUT_Callback(uint32_t usb_hid_id, uint8_t epnum, uint16_t len) { struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usb_hid_id; if (!PIOS_USB_HID_validate(usb_hid_dev)) { return false; } if (len > sizeof(usb_hid_dev->rx_packet_buffer)) { len = sizeof(usb_hid_dev->rx_packet_buffer); } if (!usb_hid_dev->rx_in_cb) { /* No Rx call back registered, disable the receiver */ usb_hid_dev->rx_active = false; return false; } /* The first byte is report ID (not checked), the second byte is the valid data length */ uint16_t headroom; bool need_yield = false; #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context, &usb_hid_dev->rx_packet_buffer[1], len-1, &headroom, &need_yield); #else (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context, &usb_hid_dev->rx_packet_buffer[2], usb_hid_dev->rx_packet_buffer[1], &headroom, &need_yield); #endif #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1; #else uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2; #endif bool rc; if (headroom >= max_payload_length) { /* We have room for a maximum length message */ PIOS_USBHOOK_EndpointRx(usb_hid_dev->cfg->data_rx_ep, usb_hid_dev->rx_packet_buffer, sizeof(usb_hid_dev->rx_packet_buffer)); rc = true; } else { /* Not enough room left for a message, apply backpressure */ usb_hid_dev->rx_active = false; rc = false; } #if defined(PIOS_INCLUDE_FREERTOS) if (need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ return rc; }
void Task::yieldFromISR() { vPortYieldFromISR(); }