IPC project

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
Pask
Posts: 47
Joined: Thu Jun 19, 2014 3:51 pm

IPC project

Post by Pask »

is there any sample project that makes use of binary semaphores, counting semaphores? everything that concerns the inter-process communication. thanks
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: IPC project

Post by Giovanni »

The test suite contains lots of examples.

The following examples are taken from the material I am writing for the book:

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.*/
  ...;
}


The book will be filled of examples like those.

Giovanni
Post Reply