void task1(void *cookie) { while (1) { rtdm_sem_down(&sem1); rtdm_sem_up(&sem2); } }
/** * Read from the device * * This function is called when the device is read in real-time context. * */ static ssize_t mpu9150_rtdm_read_rt(struct rtdm_dev_context *context, rtdm_user_info_t * user_info, void *buf, size_t nbyte) { int ret; if( mpu9150_device ) { /* take the semaphore */ rtdm_sem_down( &sem ); mpu9150_read_accel(); mpu9150_read_gyro(); mpu9150_read_mag(); mpu9150_read_temp(); ret = rtdm_safe_copy_to_user(user_info, buf, buffer.data.alldata, DATA_BUFFER_SIZE); /* if an error has occurred, send it to user */ if( ret ) return ret; /* release the semaphore */ rtdm_sem_up( &sem ); } else return 0; return DATA_BUFFER_SIZE; }
void task1(void *cookie) { long varl; rtdm_mutex_lock(&mutex); rtdm_sem_down(&sem); rtdm_mutex_unlock(&mutex); rtdm_sem_up(&sem); rtdm_sem_down(&sem); while (1) { rtdm_mutex_lock(&mutex); rtdm_mutex_lock(&mutex); varl = ++var; rtdm_mutex_unlock(&mutex); rtdm_mutex_unlock(&mutex); while(varl == var) rt_sleep(nano2count(TIMEOUT)); if ((var - varl) != 1) { rt_printk("WRONG INCREMENT OF VARIABLE IN TASK1\n"); break; } } }
/* ************************************************************************ * This is a RTAI thread. It will be activated (resumed) by the * functions "rtnetproxy_xmit" or "rtnetproxy_kernel_recv" (in linux context) * whenever new frames have to be sent out or if the * "used" rtskb ringbuffer is full. * ************************************************************************ */ static void rtnetproxy_transmit_thread(void *arg) { struct sk_buff *skb; struct rtskb *del; while (1) { /* Free all "used" rtskbs in ringbuffer */ while ((del=read_from_ringbuffer(&ring_rtskb_kernel_rtnet)) != 0) { kfree_rtskb(del); } /* Send out all frames in the ringbuffer that have not been sent yet */ while ((skb = read_from_ringbuffer(&ring_skb_kernel_rtnet)) != 0) { send_data_out(skb); /* Place the "used" skb in the ringbuffer back to kernel */ write_to_ringbuffer(&ring_skb_rtnet_kernel, skb); } /* Will be activated with next frame to send... */ rtdm_sem_down(&rtnetproxy_sem); } }
static ssize_t handleWr( struct rtdm_dev_context * ctx, rtdm_user_info_t * usr, const void * src, size_t bytes) { rtdm_lockctx_t lockCtx; struct devCtx * devCtx; ssize_t write; write = 0; devCtx = getDevCtx( ctx); /*-- Set activity: disable configuration -------------------------------------*/ rtdm_lock_get_irqsave(&devCtx->lock, lockCtx); devCtx->actvCnt++; if (1u == devCtx->actvCnt) { rtdm_lock_put_irqrestore(&devCtx->lock, lockCtx); rtdm_sem_down( &devCtx->actvLock); } else { rtdm_lock_put_irqrestore(&devCtx->lock, lockCtx); } /*-- Reset activity: enable configuration ------------------------------------*/ devCtx->actvCnt--; if (0u == devCtx->actvCnt) { rtdm_sem_up( &devCtx->actvLock); } return (write); }
static int handleIOctl( struct rtdm_dev_context * ctx, rtdm_user_info_t * usr, unsigned int req, void __user * arg) { struct devCtx * devCtx; int retval; retval = 0; devCtx = getDevCtx( ctx); /*-- Set activity: disable communication -------------------------------------*/ rtdm_sem_down( &devCtx->actvLock); switch (req) { /*-- XSPI_IOC_SET_CURRENT_CHN ------------------------------------------------*/ case XSPI_IOC_SET_CURRENT_CHN : { retval = (int)cfgChnSet( ctx, (enum xspiChn)arg); break; } /*-- XSPI_IOC_GET_CURRENT_CHN ------------------------------------------------*/ case XSPI_IOC_GET_CURRENT_CHN : { enum xspiChn chn; cfgChnGet( ctx, &chn); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &chn, sizeof(int)); } else { *(int *)arg = (int)chn; } break; } /*-- XSPI_IOC_SET_FIFO_MODE --------------------------------------------------*/ case XSPI_IOC_SET_FIFO_CHN : { retval = (int)cfgFIFOChnSet( ctx, (enum xspiFifoChn)arg); break; } /*-- XSPI_IOC_GET_FIFO_MODE --------------------------------------------------*/ case XSPI_IOC_GET_FIFO_CHN : { enum xspiFifoChn fifoChn; cfgFIFOChnGet( ctx, &fifoChn); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &fifoChn, sizeof(int)); } else { *(int *)arg = (int)fifoChn; } break; } /*-- XSPI_IOC_SET_CS_MODE ----------------------------------------------------*/ case XSPI_IOC_SET_CS_MODE : { retval = (int)cfgCsModeSet( ctx, (enum xspiCsMode)arg); break; } /*-- XSPI_IOC_GET_CS_MODE ----------------------------------------------------*/ case XSPI_IOC_GET_CS_MODE : { enum xspiCsMode csMode; cfgCsModeGet( ctx, &csMode); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &csMode, sizeof(int)); } else { *(int *)arg = (int)csMode; } break; } /*-- XSPI_IOC_SET_MODE -------------------------------------------------------*/ case XSPI_IOC_SET_MODE : { retval = (int)cfgModeSet( ctx, (enum xspiMode)arg); break; } /*-- XSPI_IOC_GET_MODE -------------------------------------------------------*/ case XSPI_IOC_GET_MODE : { enum xspiMode mode; cfgModeGet( ctx, &mode); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &mode, sizeof(int)); } else { *(int *)arg = (int)mode; } break; } /*-- XSPI_IOC_SET_CHANNEL_MODE -----------------------------------------------*/ case XSPI_IOC_SET_CHANNEL_MODE : { retval = (int)cfgChannelModeSet( ctx, (enum xspiChannelMode)arg); break; } /*-- XSPI_IOC_GET_CHANNEL_MODE -----------------------------------------------*/ case XSPI_IOC_GET_CHANNEL_MODE : { enum xspiChannelMode channelMode; cfgChannelModeGet( ctx, &channelMode); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &channelMode, sizeof(int)); } else { *(int *)arg = (int)channelMode; } break; } /*-- XSPI_IOC_SET_INITIAL_DELAY ----------------------------------------------*/ case XSPI_IOC_SET_INITIAL_DELAY : { retval = (int)cfgInitialDelaySet( ctx, (enum xspiInitialDelay)arg); break; } /*-- XSPI_IOC_GET_INITIAL_DELAY ----------------------------------------------*/ case XSPI_IOC_GET_INITIAL_DELAY : { enum xspiInitialDelay initialDelay; cfgInitialDelayGet( ctx, &initialDelay); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &initialDelay, sizeof(int)); } else { *(int *)arg = (int)initialDelay; } break; } /*-- XSPI_IOC_SET_TRANSFER_MODE ----------------------------------------------*/ case XSPI_IOC_SET_TRANSFER_MODE : { retval = (int)cfgChnTransferModeSet( ctx, (enum xspiTransferMode)arg); break; } /*-- XSPI_IOC_GET_TRANSFER_MODE ----------------------------------------------*/ case XSPI_IOC_GET_TRANSFER_MODE : { enum xspiTransferMode transferMode; cfgChnTransferModeGet( ctx, &transferMode); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &transferMode, sizeof(int)); } else { *(int *)arg = (int)transferMode; } break; } /*-- XSPI_IOC_SET_PIN_LAYOUT -------------------------------------------------*/ case XSPI_IOC_SET_PIN_LAYOUT : { retval = (int)cfgChnPinLayoutSet( ctx, (enum xspiPinLayout)arg); break; } /*-- XSPI_IOC_GET_PIN_LAYOUT -------------------------------------------------*/ case XSPI_IOC_GET_PIN_LAYOUT : { enum xspiPinLayout pinLayout; cfgChnPinLayoutGet( ctx, &pinLayout); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &pinLayout, sizeof(int)); } else { *(int *)arg = (int)pinLayout; } break; } /*-- XSPI_IOC_SET_WORD_LENGTH ------------------------------------------------*/ case XSPI_IOC_SET_WORD_LENGTH : { retval = (int)cfgChnWordLengthSet( ctx, (uint32_t)arg); break; } /*-- XSPI_IOC_GET_WORD_LENGTH ------------------------------------------------*/ case XSPI_IOC_GET_WORD_LENGTH : { uint32_t wordLength; cfgChnWordLengthGet( ctx, &wordLength); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &wordLength, sizeof(int)); } else { *(int *)arg = (int)wordLength; } break; } /*-- XSPI_IOC_SET_CS_DELAY ---------------------------------------------------*/ case XSPI_IOC_SET_CS_DELAY : { retval = (int)cfgChnCsDelaySet( ctx, (enum xspiCsDelay)arg); break; } /*-- XSPI_IOC_GET_CS_DELAY ---------------------------------------------------*/ case XSPI_IOC_GET_CS_DELAY : { enum xspiCsDelay csDelay; cfgChnCsDelayGet( ctx, &csDelay); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &csDelay, sizeof(int)); } else { *(int *)arg = (int)csDelay; } break; } /*-- XSPI_IOC_SET_CS_POLARITY ------------------------------------------------*/ case XSPI_IOC_SET_CS_POLARITY : { retval = (int)cfgChnCsPolaritySet( ctx, (enum xspiCsPolarity)arg); break; } /*-- XSPI_IOC_GET_CS_POLARITY ------------------------------------------------*/ case XSPI_IOC_GET_CS_POLARITY : { enum xspiCsPolarity csPolarity; cfgChnCsPolarityGet( ctx, &csPolarity); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &csPolarity, sizeof(int)); } else { *(int *)arg = (int)csPolarity; } break; } /*-- XSPI_IOC_SET_CS_STATE ---------------------------------------------------*/ case XSPI_IOC_SET_CS_STATE : { retval = (int)cfgChnCsStateSet( ctx, (enum xspiCsState)arg); break; } /*-- XSPI_IOC_GET_CS_STATE ---------------------------------------------------*/ case XSPI_IOC_GET_CS_STATE : { enum xspiCsState csState; cfgChnCsStateGet( ctx, &csState); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &csState, sizeof(int)); } else { *(int *)arg = (int)csState; } break; } /*-- XSPI_IOC_SET_CLOCK_FREQ -------------------------------------------------*/ case XSPI_IOC_SET_CLOCK_FREQ : { } /*-- XSPI_IOC_GET_CLOCK_FREQ -------------------------------------------------*/ case XSPI_IOC_GET_CLOCK_FREQ : { } /*-- Unhandled request -------------------------------------------------------*/ default : { LOG_DBG("IOC: unknown request (%d) received", req); retval = -EINVAL; } } if (0 != retval) { LOG_INFO("IOC: failed to execute IO request, err: %d", -retval); } /*-- Reset activity: enable communication ------------------------------------*/ rtdm_sem_up( &devCtx->actvLock); return (retval); }
void task2(void *cookie) { long i, max; nanosecs_abs_t t, dt; rt_printk("TESTING TIMING OUT TIMEDDOWN ..."); for (max = i = 0; i < LOOPS; i++) { t = rtdm_clock_read(); if (rtdm_sem_timeddown(&sem2, DELAY, NULL) == -ETIMEDOUT) { dt = rtdm_clock_read() - t - DELAY; if (dt > max) { max = dt; } } else { break; } } if (i == LOOPS) { rt_printk(" OK [%lu (ns)].\n", max); } else { rt_printk(" NOT OK [MAXLAT %lu (ns)].\n", max); } rt_printk("TESTING FAILING TRY DOWN ..."); for (i = 0; i < LOOPS; i++) { if (rtdm_sem_timeddown(&sem2, RTDM_TIMEOUT_NONE, NULL) != -EWOULDBLOCK) { break; } } if (i == LOOPS) { rt_printk(" OK.\n"); } else { rt_printk(" NOT OK.\n", max); } rt_printk("TESTING SUCCEEDING TRY DOWN ..."); rtdm_sem_up(&sem2); for (i = 0; i < LOOPS; i++) { if (!rtdm_sem_timeddown(&sem2, RTDM_TIMEOUT_NONE, NULL)) { rtdm_sem_up(&sem2); } else { break; } } if (i == LOOPS) { rt_printk(" OK.\n"); } else { rt_printk(" NOT OK.\n", max); } rt_printk("TESTING DOWN/UP ..."); rtdm_sem_down(&sem2); for (i = 0; i < LOOPS; i++) { rtdm_sem_up(&sem1); if (rtdm_sem_down(&sem2)) { break; } } if (i == LOOPS) { rt_printk(" OK.\n"); } else { rt_printk(" NOT OK.\n", max); } rt_printk("TESTING NOT TIMING OUT TIMEDDOWN ..."); for (i = 0; i < LOOPS; i++) { rtdm_sem_up(&sem1); if (rtdm_sem_timeddown(&sem2, DELAY, NULL)) { break; } } if (i == LOOPS) { rt_printk(" OK.\n"); } else { rt_printk(" NOT OK.\n", max); } }
static int rtdmtest_ioctl(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, unsigned int request, void *arg) { struct rtdmtest_context *ctx; struct rttst_rtdmtest_config config_buf, *config; rtdm_toseq_t toseq_local, *toseq = NULL; int i, err = 0; ctx = (struct rtdmtest_context *)context->dev_private; switch (request) { case RTTST_RTIOC_RTDMTEST_SEM_TIMEDDOWN: case RTTST_RTIOC_RTDMTEST_EVENT_TIMEDWAIT: case RTTST_RTIOC_RTDMTEST_MUTEX_TIMEDTEST: case RTTST_RTIOC_RTDMTEST_MUTEX_TEST: config = arg; if (user_info) { if (rtdm_safe_copy_from_user (user_info, &config_buf, arg, sizeof(struct rttst_rtdmtest_config)) < 0) return -EFAULT; config = &config_buf; } if (!config->seqcount) config->seqcount = 1; if (config->timeout && config->seqcount > 1) { toseq = &toseq_local; rtdm_toseq_init(toseq, config->timeout); } switch(request) { case RTTST_RTIOC_RTDMTEST_SEM_TIMEDDOWN: for (i = 0; i < config->seqcount; i++) { err = rtdm_sem_timeddown(&ctx->sem, config->timeout, toseq); if (err) break; } break; case RTTST_RTIOC_RTDMTEST_EVENT_TIMEDWAIT: for (i = 0; i < config->seqcount; i++) { err = rtdm_event_timedwait(&ctx->event, config->timeout, toseq); if (err) break; } break; case RTTST_RTIOC_RTDMTEST_MUTEX_TIMEDTEST: for (i = 0; i < config->seqcount; i++) { err = rtdm_mutex_timedlock(&ctx->mutex, config->timeout, toseq); if (err) break; if (config->delay_jiffies) { __set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(config->delay_jiffies); } rtdm_lock_count++; rtdm_mutex_unlock(&ctx->mutex); } break; case RTTST_RTIOC_RTDMTEST_MUTEX_TEST: for (i = 0; i < config->seqcount; i++) { if ((err = rtdm_mutex_lock(&ctx->mutex))) break; rtdm_lock_count++; rtdm_mutex_unlock(&ctx->mutex); } break; } break; case RTTST_RTIOC_RTDMTEST_SEM_DOWN: err = rtdm_sem_down(&ctx->sem); break; case RTTST_RTIOC_RTDMTEST_SEM_UP: rtdm_sem_up(&ctx->sem); break; case RTTST_RTIOC_RTDMTEST_SEM_DESTROY: rtdm_sem_destroy(&ctx->sem); break; case RTTST_RTIOC_RTDMTEST_EVENT_WAIT: err = rtdm_event_wait(&ctx->event); break; case RTTST_RTIOC_RTDMTEST_EVENT_SIGNAL: rtdm_event_signal(&ctx->event); break; case RTTST_RTIOC_RTDMTEST_EVENT_DESTROY: rtdm_event_destroy(&ctx->event); break; case RTTST_RTIOC_RTDMTEST_MUTEX_DESTROY: rtdm_mutex_destroy(&ctx->mutex); break; case RTTST_RTIOC_RTDMTEST_MUTEX_GETSTAT: printk("RTTST_RTIOC_RTDMTEST_MUTEX_GETSTAT\n"); if (user_info) config = &config_buf; else config = arg; config->seqcount = rtdm_lock_count; if (user_info) { if (rtdm_safe_copy_to_user (user_info, arg, &config_buf, sizeof(struct rttst_rtdmtest_config)) < 0) return -EFAULT; } break; case RTTST_RTIOC_RTDMTEST_NRTSIG_PEND: rtdm_nrtsig_pend(&ctx->nrtsig); break; case RTTST_RTIOC_RTDMTEST_TASK_CREATE: case RTTST_RTIOC_RTDMTEST_TASK_SET_PRIO: config = arg; if (user_info) { if (rtdm_safe_copy_from_user (user_info, &config_buf, arg, sizeof(struct rttst_rtdmtest_config)) < 0) return -EFAULT; config = &config_buf; } if (request == RTTST_RTIOC_RTDMTEST_TASK_CREATE) { task_period = config->timeout; rtdm_task_init(&task, "RTDMTEST", rtdmtest_task, (void *)config, config->priority, 0); } else { rtdm_task_set_priority(&task, config->priority); } break; case RTTST_RTIOC_RTDMTEST_TASK_DESTROY: rtdm_task_destroy(&task); rtdm_task_join_nrt(&task, 100); break; default: printk("request=%d\n", request); err = -ENOTTY; } return err; }
void task2(void *cookie) { long i, max, varl; nanosecs_abs_t t, dt; rt_printk("TESTING TIMING OUT TIMEDLOCK ..."); for (max = i = 0; i < LOOPS; i++) { t = rtdm_clock_read(); if (rtdm_mutex_timedlock(&mutex, DELAY, NULL) == -ETIMEDOUT) { dt = rtdm_clock_read() - t - DELAY; if (dt > max) { max = dt; } } else { break; } } if (i == LOOPS) { rt_printk(" OK [%lu (ns)].\n", max); } else { rt_printk(" NOT OK [MAXLAT %lu (ns)].\n", max); } rt_printk("TESTING FAILING TRY LOCK ..."); for (i = 0; i < LOOPS; i++) { if (rtdm_mutex_timedlock(&mutex, RTDM_TIMEOUT_NONE, NULL) != -EWOULDBLOCK) { break; } } if (i == LOOPS) { rt_printk(" OK.\n"); } else { rt_printk(" NOT OK.\n", max); } rt_printk("TESTING SUCCEEDING TRY LOCK ..."); rtdm_sem_up(&sem); for (i = 0; i < LOOPS; i++) { if (!rtdm_mutex_timedlock(&mutex, RTDM_TIMEOUT_NONE, NULL)) { rtdm_mutex_unlock(&mutex); } else { break; } } if (i == LOOPS) { rt_printk(" OK.\n"); } else { rt_printk(" NOT OK.\n", max); } rt_printk("TESTING LOCK/UNLOCK ..."); rtdm_sem_up(&sem); rtdm_sem_down(&sem); for (i = 0; i < LOOPS; i++) { if (rtdm_mutex_lock(&mutex)) { break; } varl = ++var; if (rtdm_mutex_lock(&mutex)) { break; } rtdm_mutex_unlock(&mutex); rtdm_mutex_unlock(&mutex); while(varl == var) rt_sleep(nano2count(TIMEOUT)); if ((var - varl) != 1) { rt_printk("WRONG INCREMENT OF VARIABLE IN TASK2\n"); break; } } if (i == LOOPS) { rt_printk(" OK.\n"); } else { rt_printk(" NOT OK.\n", max); } rt_printk("TESTING NOT TIMING OUT TIMEDLOCK ..."); for (i = 0; i < LOOPS; i++) { if (rtdm_mutex_timedlock(&mutex, DELAY, NULL)) { break; } if (rtdm_mutex_lock(&mutex)) { break; } varl = ++var; rtdm_mutex_unlock(&mutex); rtdm_mutex_unlock(&mutex); while(varl == var) rt_sleep(nano2count(TIMEOUT)); if ((var - varl) != 1) { rt_printk("WRONG INCREMENT OF VARIABLE IN TASK2\n"); break; } } if (i == LOOPS) { rt_printk(" OK.\n"); } else { rt_printk(" NOT OK.\n", max); } }