IPC project
Posted: Thu Sep 25, 2014 11:19 am
is there any sample project that makes use of binary semaphores, counting semaphores? everything that concerns the inter-process communication. thanks
Code: Select all
/*
* Synchronization semaphore.
*/
binary_semaphore_t uart_bsem;
/*
* ISR serving the UART RX FIFO interrupt.
*/
CH_IRQ_HANDLER(UART_RX_IRQ) {
CH_IRQ_PROLOGUE();
/* If there is data available in the UART RX FIFO.*/
if ((UART->SR & UART_SR_DATA_AVAILABLE) != 0) {
/* Entering I-Locked state and signaling the semaphore.*/
chSysLockFromISR();
chBSemSignalI(&uart_thread_ref);
chSysUnlockFromISR();
/* Resetting interrupt source.*/
UART->SR &= ~UART_SR_DATA_AVAILABLE;
}
CH_IRQ_EPILOGUE();
}
/*
* IRQ serving thread, communication timeouts are handled.
*/
static THD_WORKING_AREA(waUartReceiveThread, 128);
static THD_FUNCTION(UartReceiveThread, arg) {
while (true) {
/* Waiting for an interrupt. If the interrupt has already occurred
then the thread will not stop into chBSemWaitTimeout() because
the binary semaphore would be in the "not taken" state.
A 500mS timeout is programmed.*/
msg_t msg = chBSemWaitTimeout(&uart_bsem, MS2ST(500));
/* If a communication timeout occurred then some special handling
is required.*/
if (msg == MSG_TIMEOUT) {
handle_comm_timeout();
continue;
}
/* Empties the UART RX FIFO and processes all data before attempting
taking the semaphore again.*/
while ((UART->SR & UART_SR_RXFIFO_CNT) > 0) {
process_data(UART->DR);
}
}
}
/*
* Initialization.
*/
void main(void) {
/*
* System initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
chSysInit();
/* Initializing the UART semaphore in the "taken" state then starting
the communication.*/
chBSemObjectInit(&uart_bsem, true);
uart_init();
/* Starting the UART thread.*/
chThdCreateStatic(waUartReceiveThread, sizeof(waUartReceiveThread),
NORMALPRIO + 1, UartReceiveThread, NULL);
/* Continuing.*/
...;
}
Code: Select all
#define NUM_BUFFERS 16
#define BUFFERS_SIZE 256
static char buffers[NUM_BUFFERS][BUFFERS_SIZE];
static msg_t free_buffers_queue[NUM_BUFFERS];
static mailbox_t free_buffers;
static msg_t filled_buffers_queue[NUM_BUFFERS];
static mailbox_t filled_buffers;
/*
* ISR serving the network interrupt.
*/
CH_IRQ_HANDLER(RX_FRAME_IRQ) {
CH_IRQ_PROLOGUE();
/* If the network is down all the waiting threads are notified.*/
if ((NET->SR & NET_SR_ERROR) != 0 {
/* Entering I-Locked state and waking up all threads with a
mailbox reset notification.*/
chSysLockFromISR();
chMBResetI(&filled_buffers);
chSysUnlockFromISR();
/* Resetting interrupt source.*/
NET->SR &= ~NET_SR_ERROR;
}
/* If there is a frame available in the network interface.*/
if ((NET->SR & NET_SR_FRAME_AVAILABLE) != 0) {
void *pbuf;
/* Entering I-Locked state and waking up one thread, if available,
the frame is lost if there are no available threads.*/
chSysLockFromISR();
/* if a buffer is available then fill and post it to the
processor threads, we know that the post operation will
not fail because the two mailboxes have the same size.*/
if (chMBFetchI(&free_buffers, (msg_t *)&pbuf) == MSG_OK) {
fill_buffer(pbuf);
(void)chMBPostI(&filled_buffers, (msg_t)pbuf);
}
chSysUnlockFromISR();
/* Resetting interrupt source.*/
NET->SR &= ~NET_SR_FRAME_AVAILABLE;
}
CH_IRQ_EPILOGUE();
}
static THD_WORKING_AREA(waProcessFrameThread1, 128);
static THD_WORKING_AREA(waProcessFrameThread2, 128);
static THD_WORKING_AREA(waProcessFrameThread3, 128);
static THD_WORKING_AREA(waProcessFrameThread4, 128);
static THD_FUNCTION(ProcessFrameThread, arg) {
while (true) {
void *pbuf;
/* Waiting for a filled buffer.*/
msg_t msg = chMBFetch(&filled_buffers, (msg_t *)&pbuf);
/* Processing the event.*/
if (msg == MSG_RESET) {
/* The mailbox has been reset, this means network failure.*/
process_failure();
}
else {
/* Processing incoming frame.*/
process_frame(pbuf);
/* Returning the buffer to the free buffers pool.*/
(void)chMBPost(&free_buffers, (msg_t)pbuf);
}
}
}
/*
* Initialization.
*/
void main(void) {
unsigned i;
/*
* System initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
chSysInit();
/* Creating the mailboxes.*/
chMBObjectInit(&filled_buffers, filled_buffers_queue, NUM_BUFFERS);
chMBObjectInit(&free_buffers, free_buffers_queue, NUM_BUFFERS);
/* Pre-filling the free buffers pool with the available buffers, the post
will not stop because the mailbox is large enough.*/
for (i == 0; i < NUM_BUFFERS; i++)
(void)chMBPost(&free_buffers, (msg_t)&buffers[i]);
/* Starting the frames processor threads.*/
chThdCreateStatic(waProcessFrameThread1, sizeof(waProcessFrameThread1),
NORMALPRIO + 1, ProcessFrameThread, NULL);
chThdCreateStatic(waProcessFrameThread2, sizeof(waProcessFrameThread2),
NORMALPRIO + 1, ProcessFrameThread, NULL);
chThdCreateStatic(waProcessFrameThread3, sizeof(waProcessFrameThread3),
NORMALPRIO + 1, ProcessFrameThread, NULL);
chThdCreateStatic(waProcessFrameThread4, sizeof(waProcessFrameThread4),
NORMALPRIO + 1, ProcessFrameThread, NULL);
/* Networking subsystem initialization, processing starts.*/
net_init();
/* Continuing.*/
...;
}