1

谈到 Xenomai,我真的是一个新手,我想测量两点之间的时间。

我想先发送一个 10µs 的脉冲。在那之后,我等到我有中断。

我想测量脉冲和中断之间的时间。我使用“rtmd_clock_read()”函数。所以它返回的类型是'nanosecs_abs_t'。当我使用它时,我不能再加载模块并在我做'make'时得到它。

WARNING: "__aeabi_uldivmod" [...] undefined!

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

Unknow symbol in module

这是我的 Makefile

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 文件。

#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");

谢谢你们!

4

1 回答 1

1

对 64 位整数进行__aeabi_uldivmod运算需要符号。遇到此类操作时会自动生成对该函数的调用。虽然用户空间库 ( ) 实现了这个功能,但内核并没有为所有架构自动实现它。gcclibgcc

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

于 2016-05-05T10:39:20.793 回答