首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Xenomai rtdm_clock_read测度

Xenomai rtdm_clock_read测度
EN

Stack Overflow用户
提问于 2016-05-05 10:01:08
回答 1查看 331关注 0票数 1

我真的是个新手,当涉及到Xenomai的时候,我想测量两点之间的时间。

我想先发送一个10秒的脉冲,然后,我等待到我有一个中断。

我要测量脉冲和中断之间的时间。我使用'rtmd_clock_read()‘函数。所以它返回的类型是'nanosecs_abs_t‘。当我使用这个模块时,我不能再使用这个模块了,当我做一个'make‘时,我就可以得到这个模块了。

代码语言:javascript
复制
WARNING: "__aeabi_uldivmod" [...] undefined!

如果我想用“insmod”运行它,它会这样说:

代码语言:javascript
复制
Unknow symbol in module

这是我的制作文件

代码语言:javascript
复制
EXTRA_CFLAGS := -I /usr/xenomai/include/

ifneq (${KERNELRELEASE},)
    obj-m += oef1.o

else
    ARCH ?= arm
    CROSS_COMPILE ?= /usr/local/cross/rpi/bin/arm-linux-
    KERNEL_DIR = /usr/src/linux
    MODULE_DIR := $(shell pwd)
    CFLAGS := -Wall -g 

.PHONY: all
all:: modules

.PHONY: modules
modules:
    ${MAKE} -C ${KERNEL_DIR} SUBDIRS=${MODULE_DIR}  modules

XENOCONFIG=/usr/xenomai/bin/xeno-config


.PHONY: clean
clean::
    rm -f  *.o  .*.o  .*.o.* *.ko  .*.ko  *.mod.* .*.mod.* .*.cmd *~
    rm -f Module.symvers Module.markers modules.order 
    rm -rf .tmp_versions
endif

run:    oef1.ko
    insmod oef1.ko

stop:
    rmmod oef1

这是我的.c文件。

代码语言:javascript
复制
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/version.h>

#include <linux/interrupt.h>

#include <asm/uaccess.h>

#include <rtdm/rtdm_driver.h>

//define pins for the ultrasonic sensor
#define TRIGGER 4 //GPIO_0, pin  3 on the pi
#define ECHO 15  //GPIO_1, pin 5 on the pi

//Define the outputs for the leds
///blablabla
//define the time the trigger needs to be high
#define TRIGGER_PERIOD 10000//10us
#define SLEEP_TASK_TRIGGER 1000000000 //1s

//task for sending trigger pulse
static rtdm_task_t trigger_task;
//needed i  n multiple operactions
static rtdm_mutex_t periode_mutex;
//timer to get the distance of the sensor
int end = 0;
nanosecs_abs_t time1=0;
nanosecs_abs_t time2=0;
int centimeter=0;
nanosecs_abs_t difTime=0;
//for GPIO interrupt
static rtdm_irq_t irq_rtdm;
static int numero_interruption;

static void triggertask(void * p)
{
  printk("first time in trigger");
        int value=0;
        while(!end)
        {
        printk("trigger \n");


                gpio_set_value(TRIGGER,1);
              rtdm_task_sleep(TRIGGER_PERIOD);
           gpio_set_value(TRIGGER,0);
    rtdm_task_wait_period();
    rtdm_mutex_lock(&periode_mutex);
    time1 = rtdm_clock_read();
    rtdm_mutex_unlock(&periode_mutex);
    //printk("tijd1 %d\n",time1);   
        rtdm_task_sleep(SLEEP_TASK_TRIGGER);
        }
}

static int handler_interruption(rtdm_irq_t * irq)
{
    printk("irq\n");
        //stop timer, get difference
    rtdm_mutex_lock(&periode_mutex);
        time2 = rtdm_clock_read();  
    //printk("tijd2 %d\n",time2);   
        difTime = time2-time1;
        centimeter = (difTime/1000)/56;
    rtdm_mutex_unlock(&periode_mutex);
        printk("centimer: ");
    printk("%d",centimeter);
        return RTDM_IRQ_HANDLED;
}

static int __init init_sensor(void)
{
        int err;
        rtdm_printk("initsensor");

        //error handling nog toevoegen
    numero_interruption = gpio_to_irq(ECHO); 
     if((err = gpio_request(ECHO, THIS_MODULE->name))!=0)
     {
       return err;
    }
    if((err = gpio_direction_input(ECHO)) !=0)
    {
      gpio_free(ECHO);
      return err;
    }

     irq_set_irq_type(numero_interruption, IRQF_TRIGGER_RISING);
        if((err=rtdm_irq_request(& irq_rtdm, numero_interruption,handler_interruption,RTDM_IRQTYPE_EDGE,THIS_MODULE->name,NULL))!= 0)
       {
                gpio_free(ECHO);
        gpio_free(TRIGGER);
        return err;

        }

        rtdm_irq_enable(& irq_rtdm);
    rtdm_mutex_init(&periode_mutex);
    if((err = gpio_request(TRIGGER,THIS_MODULE->name))!=0)
    {
      return err;
    }
    if((err = gpio_direction_output(TRIGGER,1))!=0)
    {
      gpio_free(TRIGGER);
      return err;
    }
        err = rtdm_task_init(&trigger_task,"send_trigger_task",triggertask,NULL,99,0);
    if(err !=0)
    {
    gpio_free(TRIGGER);
    }
    return err;
}

static void __exit exit_sensor(void)
{
        //stop
        end = 1;
    rtdm_task_join_nrt(&trigger_task,100);

    rtdm_irq_disable(& irq_rtdm);
    rtdm_irq_free(& irq_rtdm);
        gpio_free(TRIGGER);
        gpio_free(ECHO);

}

module_init(init_sensor);
module_exit(exit_sensor);
MODULE_LICENSE("GPL");

谢谢你们!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-05 10:39:20

64位整数的模块化操作需要符号__aeabi_uldivmod .该函数的调用是由gcc在遇到此类操作时自动生成的。虽然用户空间库(libgcc)实现了这一功能,但内核并不能为所有的架构自动实现它.

当除数是预先定义的常数时,可以用幻数和移位乘法代替除法/模运算。这里,您可以为您的情况计算魔术数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37047668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档