bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout) { msg_t msg; //Wait until the semaphore is available or the timeout interval elapses if(timeout == 0) { //Non-blocking call msg = chSemWaitTimeout(semaphore, TIME_IMMEDIATE); } else if(timeout == INFINITE_DELAY) { //Infinite timeout period msg = chSemWaitTimeout(semaphore, TIME_INFINITE); } else { //Wait until the specified semaphore becomes available msg = chSemWaitTimeout(semaphore, OS_MS_TO_SYSTICKS(timeout)); } //Check whether the specified semaphore is available if(msg == RDY_OK) return TRUE; else return FALSE; }
static void test_002_003_execute(void) { systime_t time; msg_t msg; /* The function chSemWaitTimeout() is invoked, after return the system time, the counter and the returned message are tested.*/ test_set_step(1); { time = chVTGetSystemTimeX(); msg = chSemWaitTimeout(&sem1, MS2ST(1000)); test_assert_time_window(time + MS2ST(1000), time + MS2ST(1000) + 1, "out of time window"); test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value"); test_assert(MSG_TIMEOUT == msg, "wrong timeout message"); } /* The function chSemWaitTimeout() is invoked, after return the system time, the counter and the returned message are tested.*/ test_set_step(2); { time = chVTGetSystemTimeX(); msg = chSemWaitTimeout(&sem1, MS2ST(1000)); test_assert_time_window(time + MS2ST(1000), time + MS2ST(1000) + 1, "out of time window"); test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value"); test_assert(MSG_TIMEOUT == msg, "wrong timeout message"); } }
bool_t gadcLowSpeedStart(uint32_t physdev, adcsample_t *buffer, GADCCallbackFunction fn, void *param) { struct lsdev *p; DoInit(); /* Start the Low Speed Timer */ chMtxLock(&gadcmutex); if (!gtimerIsActive(&LowSpeedGTimer)) gtimerStart(&LowSpeedGTimer, LowSpeedGTimerCallback, NULL, TRUE, TIME_INFINITE); /* Find a slot */ for(p = ls; p < &ls[GADC_MAX_LOWSPEED_DEVICES]; p++) { if (!(p->flags & GADC_FLG_ISACTIVE)) { /* We know we have a slot - this should never wait anyway */ chSemWaitTimeout(&gadcsem, TIME_IMMEDIATE); p->lld.physdev = physdev; p->lld.buffer = buffer; p->fn = fn; p->param = param; p->flags = GADC_FLG_ISACTIVE; chMtxUnlock(); StartADC(FALSE); return TRUE; } } chMtxUnlock(); return FALSE; }
uint8_t spiSendI(SPI_TypeDef* SPIx, uint8_t* buffer, uint16_t len) { if (SPIx == SPI1) { if (chSemWaitTimeout(&spi1_semI, TIME_IMMEDIATE) != MSG_OK) { return 1; } /* Stop and re-initialise DMA1 * We don't care if it was running, * we'll restart from the beginning of the buffer */ DMA_CHANNEL_SPI1_TX->CCR &= ~DMA_CCR_EN; /* Stop DMA1_Channel3 */ DMA1->IFCR |= DMA_CTCIF_SPI1_TX; /* Clear transfer complete flag */ DMA_CHANNEL_SPI1_TX->CMAR = (uint32_t)buffer; DMA_CHANNEL_SPI1_TX->CNDTR = len; /* Start DMA1_Channel3 */ DMA_CHANNEL_SPI1_TX->CCR |= DMA_CCR_EN; chSemSignal(&spi1_semI); return 0; } else { return 1; } }
uint8_t usartSendS(USART_TypeDef* USARTx, const char* buffer, uint16_t len) { uint8_t ret = 1; if (USARTx == USART1) { if (chSemWaitTimeout(&usart1_semS, MS2ST(USART_TIMEOUT)) != MSG_OK) { return 1; } /* DMA */ // if((DMA1->ISR & DMA_TCIF_USART1_TX) == RESET) // { // DMA1->IFCR |= DMA_CTCIF_USART1_TX; /* Clear transfer complete flag */ // } // ret = usartSendI(USARTx, buffer, len); // /* Wait for transfer to finish */ // while((DMA1->ISR & DMA_TCIF_USART1_TX) == RESET) {}; // DMA1->IFCR |= DMA_CTCIF_USART1_TX; /* Clear transfer complete flag */ /* Manual */ while (len--) { USARTx->TDR = (*buffer++ & (uint16_t)0x01FF); while ((USARTx->ISR & USART_ISR_TXE) == RESET); } chSemSignal(&usart1_semS); } return ret; }
uint8_t usartSendI(USART_TypeDef* USARTx, const char* buffer, uint16_t len) { uint8_t ret = 1; if (USARTx == USART1) { if (chSemWaitTimeout(&usart1_semI, TIME_IMMEDIATE) != MSG_OK) { return 1; } if (len > USART_TXBUF_SIZE) { len = USART_TXBUF_SIZE; } /* Copy data to usart tx buffer */ memcpy(usart_txbuf, buffer, len); /* Stop and re-initialise DMA1 * We don't care if it was running, * we'll restart from the beginning of the buffer */ DMA_CHANNEL_USART1_TX->CCR &= ~DMA_CCR_EN; /* Stop DMA1_Channel */ DMA1->IFCR |= DMA_CTCIF_USART1_TX; /* Clear transfer complete flag */ DMA_CHANNEL_USART1_TX->CMAR = (uint32_t)usart_txbuf; DMA_CHANNEL_USART1_TX->CNDTR = len; /* Start DMA1_Channel4 */ DMA_CHANNEL_USART1_TX->CCR |= DMA_CCR_EN; chSemSignal(&usart1_semI); } return ret; }
bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) { if (ms == TIME_INFINITE) { chSemWait(&psem->sem); return TRUE; } return chSemWaitTimeout(&psem->sem, MS2ST(ms)) != RDY_TIMEOUT; }
uint8_t i2cReceiveS(I2C_TypeDef* I2Cx, const uint8_t addr, uint8_t *buffer, uint8_t len) { uint8_t timeout; if (chSemWaitTimeout(&i2c1_semS, MS2ST(I2C_TIMEOUT)) != MSG_OK) { return 1; } I2C_TransferHandling(I2Cx, addr, len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); while (len--) { timeout = 100; while(I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET) { chThdSleepMicroseconds(50); if (!timeout--) { chSemSignal(&i2c1_semS); return 1; } }; *buffer++ = I2Cx->RXDR; } chSemSignal(&i2c1_semS); return 0; }
bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) { #if CH_KERNEL_MAJOR == 2 switch(ms) { case TIME_IMMEDIATE: return chSemWaitTimeout(&psem->sem, TIME_IMMEDIATE) != RDY_TIMEOUT; case TIME_INFINITE: chSemWait(&psem->sem); return TRUE; default: return chSemWaitTimeout(&psem->sem, MS2ST(ms)) != RDY_TIMEOUT; } #elif CH_KERNEL_MAJOR == 3 switch(ms) { case TIME_IMMEDIATE: return chSemWaitTimeout(&psem->sem, TIME_IMMEDIATE) != MSG_TIMEOUT; case TIME_INFINITE: chSemWait(&psem->sem); return TRUE; default: return chSemWaitTimeout(&psem->sem, MS2ST(ms)) != MSG_TIMEOUT; } #endif }
static void rt_test_005_003_execute(void) { unsigned i; systime_t target_time; msg_t msg; /* [5.3.1] Testing special case TIME_IMMEDIATE.*/ test_set_step(1); { msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE); test_assert(msg == MSG_TIMEOUT, "wrong wake-up message"); test_assert(queue_isempty(&sem1.queue), "queue not empty"); test_assert(sem1.cnt == 0, "counter not zero"); } /* [5.3.2] Testing non-timeout condition.*/ test_set_step(2); { threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1, thread2, 0); msg = chSemWaitTimeout(&sem1, TIME_MS2I(500)); test_wait_threads(); test_assert(msg == MSG_OK, "wrong wake-up message"); test_assert(queue_isempty(&sem1.queue), "queue not empty"); test_assert(sem1.cnt == 0, "counter not zero"); } /* [5.3.3] Testing timeout condition.*/ test_set_step(3); { target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(5 * 50)); for (i = 0; i < 5; i++) { test_emit_token('A' + i); msg = chSemWaitTimeout(&sem1, TIME_MS2I(50)); test_assert(msg == MSG_TIMEOUT, "wrong wake-up message"); test_assert(queue_isempty(&sem1.queue), "queue not empty"); test_assert(sem1.cnt == 0, "counter not zero"); } test_assert_sequence("ABCDE", "invalid sequence"); test_assert_time_window(target_time, chTimeAddX(target_time, ALLOWED_DELAY), "out of time window"); } }
/** * @brief Allocates a mail object from a mail pool. * @pre The mail pool must be already been initialized. * * @param[in] mlp pointer to a @p MailPool structure * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The mail object. * @retval NULL timeout expired. * * @api */ void *mailCreate(MailPool *mlp, systime_t time) { msg_t msg; void *mailp; msg = chSemWaitTimeout(&mlp->sem, time); if (msg != RDY_OK) return NULL; mailp = chPoolAlloc(&mlp->pool); chDbgAssert(mailp != NULL, "mailCreate(), #1", "empty pool"); return mailp; }
/** * @brief Wait on a semaphore. */ int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec) { msg_t msg = chSemWaitTimeout((semaphore_t *)semaphore_id, (systime_t)millisec); switch (msg) { case MSG_OK: return osOK; case MSG_TIMEOUT: return osErrorTimeoutResource; } return osErrorResource; }
static void sem2_execute(void) { int i; systime_t target_time; msg_t msg; /* * Testing special case TIME_IMMEDIATE. */ msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE); test_assert(1, msg == RDY_TIMEOUT, "wrong wake-up message"); test_assert(2, isempty(&sem1.s_queue), "queue not empty"); test_assert(3, sem1.s_cnt == 0, "counter not zero"); /* * Testing not timeout condition. */ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority() - 1, thread2, 0); msg = chSemWaitTimeout(&sem1, MS2ST(500)); test_wait_threads(); test_assert(4, msg == RDY_OK, "wrong wake-up message"); test_assert(5, isempty(&sem1.s_queue), "queue not empty"); test_assert(6, sem1.s_cnt == 0, "counter not zero"); /* * Testing timeout condition. */ test_wait_tick(); target_time = chTimeNow() + MS2ST(5 * 500); for (i = 0; i < 5; i++) { test_emit_token('A' + i); msg = chSemWaitTimeout(&sem1, MS2ST(500)); test_assert(7, msg == RDY_TIMEOUT, "wrong wake-up message"); test_assert(8, isempty(&sem1.s_queue), "queue not empty"); test_assert(9, sem1.s_cnt == 0, "counter not zero"); } test_assert_sequence(10, "ABCDE"); test_assert_time_window(11, target_time, target_time + ALLOWED_DELAY); }
/** * @brief Wait on a semaphore. */ int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec) { systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ? TIME_INFINITE : MS2ST(millisec); msg_t msg = chSemWaitTimeout((semaphore_t *)semaphore_id, timeout); switch (msg) { case MSG_OK: return osOK; case MSG_TIMEOUT: return osErrorTimeoutResource; } return osErrorResource; }
uint8_t spiSendS(SPI_TypeDef* SPIx, uint8_t* buffer, uint16_t len) { uint8_t ret = 1; if (SPIx == SPI1) { if (chSemWaitTimeout(&spi1_semS, MS2ST(SPI_TIMEOUT)) != MSG_OK) { return 1; } if((DMA1->ISR & DMA_TCIF_SPI1_TX) == RESET) { DMA1->IFCR |= DMA_CTCIF_SPI1_TX; /* Clear transfer complete flag */ } ret = spiSendI(SPIx, buffer, len); /* Wait for transfer to finish */ while((DMA1->ISR & DMA_TCIF_SPI1_TX) == RESET) chThdSleepMilliseconds(10); DMA1->IFCR |= DMA_CTCIF_SPI1_TX; /* Clear transfer complete flag */ chSemSignal(&spi1_semS); } return ret; }
static msg_t vexAudioTask( void *arg ) { uint32_t tmpCounter; (void)arg; chRegSetThreadName("audio"); chEvtInit(&sound_done); while(!chThdShouldTerminate()) { if(VSL_Counter > 0) { tmpCounter = VSL_Counter; VSL_Counter = 0; // wait for semaphore timeout or other thread reseting the semaphore chSemWaitTimeout( &vslSem, tmpCounter ); chSysLock(); if( chEvtIsListeningI(&sound_done) ) chEvtBroadcastI(&sound_done); chSysUnlock(); if( VSL_Counter == 0 ) { if( !vexAudioPlayNextChipTone() ) VSL_Deinit(); } } else chSemWait( &vslSem ); } return (msg_t)0; }
inline bool Semaphore_::wait(const Time &timeout) { return chSemWaitTimeout(&impl, US2ST(timeout.to_us_raw())) == RDY_OK; }
/** * @brief Requests a DMA transfer operation from the DMA engine. * @note The DMA engine uses unclaimed DMA channels to provide DMA services * for one-off or infrequent uses. If all channels are busy, and * semaphores are enabled, the calling thread will sleep until a * channel is available or the request times out. If semaphores are * disabled, the calling thread will busy-wait instead of sleeping. */ bool dmaRequest(msp430x_dma_req_t * request, systime_t timeout) { /* Check if a DMA channel is available */ #if CH_CFG_USE_SEMAPHORES msg_t semresult = chSemWaitTimeout(&dma_lock, timeout); if (semresult != MSG_OK) return true; #endif #if !(CH_CFG_USE_SEMAPHORES) systime_t start = chVTGetSystemTimeX(); do { #endif /* Grab the correct DMA channel to use */ int i = 0; for (i = 0; i < MSP430X_DMA_CHANNELS; i++) { if (!(dma_channels[i].ctl & DMAEN)) { break; } } #if !(CH_CFG_USE_SEMAPHORES) while (chVTTimeElapsedSinceX(start) < timeout) ; #endif #if !(CH_CFG_USE_SEMAPHORES) if (i == MSP430X_DMA_CHANNELS) { return true; } #endif /* Make the request */ init_request(request, i); return false; } /** * @brief Acquires exclusive control of a DMA channel. * @pre The channel must not be already acquired or an error is returned. * @note If the channel is in use by the DMA engine, blocks until acquired. * @post This channel must be interacted with using only the functions * defined in this module. * * @param[out] channel The channel handle. Must be pre-allocated. * @param[in] index The index of the channel (< MSP430X_DMA_CHANNELS). * @return The operation status. * @retval false no error, channel acquired. * @retval true error, channel already acquired. */ bool dmaAcquire(msp430x_dma_ch_t * channel, uint8_t index) { /* Acquire the channel in an idle mode */ /* Is the channel already acquired? */ osalDbgAssert(index < MSP430X_DMA_CHANNELS, "invalid channel index"); if (dma_channels[index].ctl & DMADT_4) { return true; } /* Increment the DMA counter */ #if CH_CFG_USE_SEMAPHORES msg_t semresult = chSemWait(&dma_lock); if (semresult != MSG_OK) return true; #endif while (dma_channels[index].ctl & DMAEN) ; dma_trigger_set(index, DMA_TRIGGER_MNEM(DMAREQ)); dma_channels[index].sz = 0; dma_channels[index].ctl = DMAEN | DMAABORT | DMADT_4; channel->registers = dma_channels + index; channel->index = index; channel->cb = callbacks + index; return false; }
msg_t CounterSemaphore::waitTimeout(systime_t time) { return chSemWaitTimeout(&sem, time); }
msg_t Semaphore::WaitTimeout(systime_t time) { return chSemWaitTimeout(&sem, time); }
GEvent *geventEventWait(GListener *pl, systime_t timeout) { if (pl->callback || chSemGetCounterI(&pl->waitqueue) < 0) return 0; return chSemWaitTimeout(&pl->waitqueue, timeout) == RDY_OK ? &pl->event : 0; }
/*------------------------------------------------------------------------*/ int ff_req_grant(_SYNC_t sobj) { msg_t msg = chSemWaitTimeout(sobj, (systime_t)_FS_TIMEOUT); return msg == MSG_OK; }