int run(void) { const char *name = get_instance_name(); printf("%s: Waiting for client init...\n", name); setup_wait(); printf("%s: Initialising lock...\n", name); sync_spinlock_init((sync_spinlock_t*)&outgoing->lock); printf("%s: Notifying receiver...\n", name); init_emit(); printf("%s: Waiting for data...\n", name); int received = 0; while (!received) { sync_spinlock_lock((sync_spinlock_t*)&incoming->lock); if (incoming->full) { sync_spinlock_lock((sync_spinlock_t*)&outgoing->lock); strcpy((char*)outgoing->data, (char*)incoming->data); outgoing->full = 1; sync_spinlock_unlock((sync_spinlock_t*)&outgoing->lock); received = 1; } sync_spinlock_unlock((sync_spinlock_t*)&incoming->lock); } printf("%s: Done.\n", name); return 0; }
/** * Retrieve CAN message from RX queue. * * @frame: CAN message about to fill-in . * * @return: On success, return frame address. * Return NULL if the queue is empty. * * NOTE: Pushing to the queue will block this function. */ struct can_frame *rx_queue_pop(struct can_frame *frame) { struct can_frame *frm = NULL; if (!mq_is_empty(rxq)) { sync_spinlock_lock(&rxq->lock); mq_remove_msg(rxq, frame); sync_spinlock_unlock(&rxq->lock); frm = frame; } return frm; }
/** * Add CAN message to RX queue. * * @frame: CAN message about to add. * * @return: On success, return 0, -1 otherwise. * * NOTE: Popping from the queue will block this function. * This function may block the IRQ handler. */ int rx_queue_push(struct can_frame *frame) { int ret = -1; if (!mq_is_full(rxq)) { sync_spinlock_lock(&rxq->lock); mq_append_msg(rxq, frame); sync_spinlock_unlock(&rxq->lock); ret = 0; } return ret; }
int run(void) { const char *s = "hello world"; const char *name = get_instance_name(); printf("%s: Initialising lock...\n", name); sync_spinlock_init((sync_spinlock_t*)&sock->lock); printf("%s: Notifying transport...\n", name); init_emit(); printf("%s: Writing \"%s\"...\n", name, s); sync_spinlock_lock((sync_spinlock_t*)&sock->lock); strcpy((char*)sock->data, s); sock->full = 1; sync_spinlock_unlock((sync_spinlock_t*)&sock->lock); printf("%s: Done.\n", name); return 0; }
/** * Put message queue into TXB. * * @tx: TXB bits(Bit 0 -- TXB0, Bit 1 -- TXB1, Bit 2 -- TXB2) */ static void transmit_message(uint8_t tx) { struct can_frame frame; uint8_t rts = 0; /* Clear interrupt flags */ mcp2515_bit_modify(CANINTF, tx << TXIF_SHF, 0); /* Load messages into empty TX buffers. */ for (int i = TXB_NUM - 1; i >= 0; i--) { if (tx & BIT(i)) { canid_clear_cache(i); switch (i) { case 0: txb0_ack_emit(); break; case 1: txb1_ack_emit(); break; case 2: txb2_ack_emit(); break; default: break; } if (tx_queue_pop(&frame)) { /* Make sure the previous message is sent. */ while (mcp2515_read_reg(TXBCTRL(i) & TXBCTRL_TXREQ)); load_txb(i, &frame); rts |= BIT(i); } else { /* The TX queue is empty, stop transmission. */ sync_spinlock_lock(&txb_lock); xmit_stopped = 1; sync_spinlock_unlock(&txb_lock); } } } /* Initiating transmission */ mcp2515_rts(rts); }
int run(void) { const char *name = get_instance_name(); printf("%s: Waiting for transport init...\n", name); setup_wait(); printf("%s: Waiting for data...\n", name); int received = 0; while (!received) { sync_spinlock_lock((sync_spinlock_t*)&sock->lock); if (sock->full) { printf("%s: Received \"%s\".\n", name, sock->data); received = 1; } sync_spinlock_unlock((sync_spinlock_t*)&sock->lock); } printf("%s: Done.\n", name); return 0; }