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; }
static msg_t Th2(void *p) { (void)p; chRegSetThreadName("Th2"); while (TRUE) { /////DEVICE 2/////////// if(palReadPad(GPIO1_PORT, GPIO1_PAD) != PAL_HIGH) { palWritePad(GPIO22_PORT,GPIO22_PAD,PAL_HIGH); chSemWait(&mySemaphore); chprintf((BaseSequentialStream *)&SD1, "D2ON\r\n"); chSemSignal(&mySemaphore); }else{ palWritePad(GPIO22_PORT,GPIO22_PAD,PAL_LOW); chSemWait(&mySemaphore); chprintf((BaseSequentialStream *)&SD1, "D2OFF\r\n"); chSemSignal(&mySemaphore); } chThdSleepMilliseconds(1000); } return 0; }
static void rt_test_005_002_execute(void) { /* [5.2.1] Five threads are created with mixed priority levels (not increasing nor decreasing). Threads enqueue on a semaphore initialized to zero.*/ test_set_step(1); { threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread1, "A"); threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+1, thread1, "B"); threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread1, "C"); threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+4, thread1, "D"); threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+2, thread1, "E"); } /* [5.2.2] The semaphore is signaled 5 times. The thread activation sequence is tested.*/ test_set_step(2); { chSemSignal(&sem1); chSemSignal(&sem1); chSemSignal(&sem1); chSemSignal(&sem1); chSemSignal(&sem1); test_wait_threads(); #if CH_CFG_USE_SEMAPHORES_PRIORITY test_assert_sequence("ADCEB", "invalid sequence"); #else test_assert_sequence("ABCDE", "invalid sequence"); #endif } }
static void LowSpeedGTimerCallback(void *param) { (void) param; GADCCallbackFunction fn; void *prm; adcsample_t *buffer; struct lsdev *p; #if ADC_ISR_FULL_CODE_BUG /* Ensure the ADC is running if it needs to be - Bugfix HACK */ StartADC(FALSE); #endif /** * Look for completed low speed timers. * We don't need to take the mutex as we are the only place that things are freed and we * do that atomically. */ for(p=ls; p < &ls[GADC_MAX_LOWSPEED_DEVICES]; p++) { if ((p->flags & (GADC_FLG_ISACTIVE|GADC_FLG_ISDONE)) == (GADC_FLG_ISACTIVE|GADC_FLG_ISDONE)) { /* This item is done - perform its callback */ fn = p->fn; // Save the callback details prm = p->param; buffer = p->lld.buffer; p->fn = 0; // Needed to prevent the compiler removing the local variables p->param = 0; // Needed to prevent the compiler removing the local variables p->lld.buffer = 0; // Needed to prevent the compiler removing the local variables p->flags = 0; // The slot is available (indivisible operation) chSemSignal(&gadcsem); // Tell everyone fn(buffer, prm); // Perform the callback } } }
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; } }
static void rt_test_005_001_execute(void) { /* [5.1.1] The function chSemWait() is invoked, after return the counter and the returned message are tested.*/ test_set_step(1); { msg_t msg; msg = chSemWait(&sem1); test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value"); test_assert(MSG_OK == msg, "wrong returned message"); } /* [5.1.2] The function chSemSignal() is invoked, after return the counter is tested.*/ test_set_step(2); { chSemSignal(&sem1); test_assert_lock(chSemGetCounterI(&sem1) == 1, "wrong counter value"); } /* [5.1.3] The function chSemReset() is invoked, after return the counter is tested.*/ test_set_step(3); { chSemReset(&sem1, 2); test_assert_lock(chSemGetCounterI(&sem1) == 2, "wrong counter value"); } }
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; }
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; }
static msg_t thread3(void *p) { (void)p; chSemWait(&sem1); chSemSignal(&sem1); return 0; }
/** * Uart transmit buffer implementation */ void uart_put_buffer(struct uart_periph *p, long fd, const uint8_t *data, uint16_t len) { struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct); if (fd == 0) { // if fd is zero, assume the driver is not already locked // and available space should be checked chMtxLock(init_struct->tx_mtx); int16_t space = p->tx_extract_idx - p->tx_insert_idx; if (space <= 0) { space += UART_TX_BUFFER_SIZE; } if ((uint16_t)(space - 1) < len) { chMtxUnlock(init_struct->tx_mtx); return; // no room } } // insert data into buffer int i; for (i = 0; i < len; i++) { p->tx_buf[p->tx_insert_idx] = data[i]; p->tx_insert_idx = (p->tx_insert_idx + 1) % UART_TX_BUFFER_SIZE; } // unlock if needed if (fd == 0) { chMtxUnlock(init_struct->tx_mtx); // send signal to start transmission chSemSignal (init_struct->tx_sem); } }
bool usbhmsdLUNDisconnect(USBHMassStorageLUNDriver *lunp) { osalDbgCheck(lunp != NULL); chSemWait(&lunp->sem); osalDbgAssert((lunp->state == BLK_READY) || (lunp->state == BLK_ACTIVE), "invalid state"); if (lunp->state == BLK_ACTIVE) { chSemSignal(&lunp->sem); return HAL_SUCCESS; } lunp->state = BLK_DISCONNECTING; //TODO: complete: sync, etc. lunp->state = BLK_ACTIVE; chSemSignal(&lunp->sem); return HAL_SUCCESS; }
static void _lun_object_deinit(USBHMassStorageLUNDriver *lunp) { osalDbgCheck(lunp != NULL); chSemWait(&lunp->sem); lunp->msdp = NULL; lunp->next = NULL; memset(&lunp->info, 0, sizeof(lunp->info)); lunp->state = BLK_STOP; chSemSignal(&lunp->sem); }
bool usbhmsdLUNWrite(USBHMassStorageLUNDriver *lunp, uint32_t startblk, const uint8_t *buffer, uint32_t n) { osalDbgCheck(lunp != NULL); bool ret = HAL_FAILED; uint16_t blocks; msd_result_t res; uint32_t actual_len; chSemWait(&lunp->sem); if (lunp->state != BLK_READY) { chSemSignal(&lunp->sem); return ret; } lunp->state = BLK_WRITING; while (n) { if (n > 0xffff) { blocks = 0xffff; } else { blocks = (uint16_t)n; } res = scsi_write10(lunp, startblk, blocks, buffer, &actual_len); if (res == MSD_RESULT_DISCONNECTED) { goto exit; } else if (res == MSD_RESULT_TRANSPORT_ERROR) { //retry? goto exit; } else if (res == MSD_RESULT_FAILED) { //retry? goto exit; } n -= blocks; startblk += blocks; buffer += blocks * lunp->info.blk_size; } ret = HAL_SUCCESS; exit: lunp->state = BLK_READY; chSemSignal(&lunp->sem); return ret; }
static void sem1_execute(void) { threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority()+5, thread1, "A"); threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriority()+1, thread1, "B"); threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriority()+3, thread1, "C"); threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriority()+4, thread1, "D"); threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriority()+2, thread1, "E"); chSemSignal(&sem1); chSemSignal(&sem1); chSemSignal(&sem1); chSemSignal(&sem1); chSemSignal(&sem1); test_wait_threads(); #if CH_USE_SEMAPHORES_PRIORITY test_assert_sequence(1, "ADCEB"); #else test_assert_sequence(1, "ABCDE"); #endif }
void uart_send_message(struct uart_periph *p, long fd) { struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct); // unlock driver in case it is not done (fd > 0) if (fd != 0) { chMtxUnlock(init_struct->tx_mtx); } // send signal to start transmission chSemSignal (init_struct->tx_sem); }
/** * @brief Releases exclusive access to the I2C bus. * @pre In order to use this function the option @p I2C_USE_MUTUAL_EXCLUSION * must be enabled. * * @param[in] i2cp pointer to the @p I2CDriver object * * @api */ void i2cReleaseBus(I2CDriver *i2cp) { chDbgCheck(i2cp != NULL, "i2cReleaseBus"); #if CH_USE_MUTEXES chMtxUnlock(); #elif CH_USE_SEMAPHORES chSemSignal(&i2cp->semaphore); #endif }
/** * @brief Releases exclusive access to the SPI bus. * @pre In order to use this function the option @p SPI_USE_MUTUAL_EXCLUSION * must be enabled. * * @param[in] spip pointer to the @p SPIDriver object * * @api */ void spiReleaseBus(SPIDriver *spip) { chDbgCheck(spip != NULL, "spiReleaseBus"); #if CH_USE_MUTEXES (void)spip; chMtxUnlock(); #elif CH_USE_SEMAPHORES chSemSignal(&spip->semaphore); #endif }
void Lcd_t::PrintfInverted(const uint8_t x, const uint8_t y, const char *S, ...) { msg_t msg = chSemWait(&semLcd); if(msg == RDY_OK) { GotoCharXY(x, y); va_list args; va_start(args, S); kl_vsprintf(FLcdPutCharInverted, 16, S, args); va_end(args); chSemSignal(&semLcd); } }
/** * @brief Releases exclusive access to the ADC peripheral. * @pre In order to use this function the option * @p ADC_USE_MUTUAL_EXCLUSION must be enabled. * * @param[in] adcp pointer to the @p ADCDriver object * * @api */ void adcReleaseBus(ADCDriver *adcp) { chDbgCheck(adcp != NULL, "adcReleaseBus"); #if CH_USE_MUTEXES (void)adcp; chMtxUnlock(); #elif CH_USE_SEMAPHORES chSemSignal(&adcp->semaphore); #endif }
/** * @brief Releases exclusive access to the DAC bus. * @pre In order to use this function the option @p DAC_USE_MUTUAL_EXCLUSION * must be enabled. * * @param[in] dacp pointer to the @p DACDriver object * * @api */ void dacReleaseBus(DACDriver *dacp) { chDbgCheck(dacp != NULL, "dacReleaseBus"); #if CH_USE_MUTEXES (void)dacp; chMtxUnlock(); #elif CH_USE_SEMAPHORES chSemSignal(&dacp->semaphore); #endif }
//----------------------------------------------------------------------------- static void return_write_buffer_idx_after_writing(int8_t idx) { chSemWait(&write_buffer_semaphore); // @TODO: optional? Do we really need to memset it? we ARE going to be // overwriting it memset(&write_buffers[idx],0,sizeof(write_buffers[idx])); // if the current idx is -1, then we can assume it's good to go write_buffers[idx].current_idx = -1; chSemSignal(&write_buffer_semaphore); }
//----------------------------------------------------------------------------- // new file scenario / etc. static void flush_write_buffers(void) { chSemWait(&write_buffer_semaphore); memset(&write_buffers, 0, sizeof(write_buffers)); for ( int8_t idx = 0 ; idx < BUFFER_COUNT ; idx++ ) write_buffers[idx].current_idx = -1; flush_counters(); chSemSignal(&write_buffer_semaphore); }
/** * @brief Releases exclusive control of a DMA channel. * @details The channel is released from control and returned to the DMA * engine * pool. Trying to release an unallocated channel is an illegal * operation and is trapped if assertions are enabled. * @pre The channel must have been acquired using @p dmaAcquire(). * @post The channel is returned to the DMA engine pool. */ void dmaRelease(msp430x_dma_ch_t * channel) { osalDbgCheck(channel != NULL); /* Release the channel in an idle mode */ channel->registers->ctl = DMAABORT; /* release the DMA counter */ #if CH_CFG_USE_SEMAPHORES chSemSignal(&dma_lock); #endif }
void geventDetachSource(GListener *pl, GSourceHandle gsh) { if (pl) { chMtxLock(&geventMutex); deleteAssignments(pl, gsh); if (!gsh && chSemGetCounterI(&pl->waitqueue) < 0) { chBSemWait(&pl->eventlock); // Obtain the buffer lock pl->event.type = GEVENT_EXIT; // Set up the EXIT event chSemSignal(&pl->waitqueue); // Wake up the listener chBSemSignal(&pl->eventlock); // Release the buffer lock } chMtxUnlock(); } }
static void bmk11_execute(void) { uint32_t n = 0; test_wait_tick(); test_start_timer(1000); do { chSemWait(&sem1); chSemSignal(&sem1); chSemWait(&sem1); chSemSignal(&sem1); chSemWait(&sem1); chSemSignal(&sem1); chSemWait(&sem1); chSemSignal(&sem1); n++; #if defined(SIMULATOR) ChkIntSources(); #endif } while (!test_timer_done); test_print("--- Score : "); test_printn(n * 4); test_println(" wait+signal/S"); }
void geventSendEvent(GSourceListener *psl) { chMtxLock(&geventMutex); if (psl->pListener->callback) { // This test needs to be taken inside the mutex chMtxUnlock(); // We already know we have the event lock psl->pListener->callback(psl->pListener->param, &psl->pListener->event); } else { // Wake up the listener if (chSemGetCounterI(&psl->pListener->waitqueue) < 0) chSemSignal(&psl->pListener->waitqueue); chMtxUnlock(); } }
void geventRegisterCallback(GListener *pl, GEventCallbackFn fn, void *param) { if (pl) { chMtxLock(&geventMutex); chBSemWait(&pl->eventlock); // Obtain the buffer lock pl->param = param; // Set the param pl->callback = fn; // Set the callback function if (chSemGetCounterI(&pl->waitqueue) < 0) { pl->event.type = GEVENT_EXIT; // Set up the EXIT event chSemSignal(&pl->waitqueue); // Wake up the listener } chBSemSignal(&pl->eventlock); // Release the buffer lock chMtxUnlock(); } }
/* Null is treated as a wildcard. */ static void deleteAssignments(GListener *pl, GSourceHandle gsh) { GSourceListener *psl; for(psl = Assignments; psl < Assignments+GEVENT_MAX_SOURCE_LISTENERS; psl++) { if ((!pl || psl->pListener == pl) && (!gsh || psl->pSource == gsh)) { if (chSemGetCounterI(&psl->pListener->waitqueue) < 0) { chBSemWait(&psl->pListener->eventlock); // Obtain the buffer lock psl->pListener->event.type = GEVENT_EXIT; // Set up the EXIT event chSemSignal(&psl->pListener->waitqueue); // Wake up the listener chBSemSignal(&psl->pListener->eventlock); // Release the buffer lock } psl->pListener = 0; } } }
static msg_t Thread2(void *arg) { pinMode(LED_PIN, OUTPUT); while (TRUE) { // first pulse to get time with no context switch digitalWrite(LED_PIN, HIGH); digitalWrite(LED_PIN, LOW); // start second pulse digitalWrite(LED_PIN, HIGH); // trigger context switch for task that ends pulse chSemSignal(&sem); // sleep until next tick (1024 microseconds tick on Arduino) chThdSleep(1); } return 0; }
static msg_t Thread2(void *arg) { pinMode(LED_PIN, OUTPUT); while (1) { digitalWrite(LED_PIN, HIGH); // Sleep for 200 milliseconds. chThdSleepMilliseconds(200); // Signal thread 1 to turn LED off. chSemSignal(&sem); // Sleep for 200 milliseconds. chThdSleepMilliseconds(200); } return 0; }