谈到 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");
谢谢你们!