想了一下,还是重来一遍。
tar -vxf ethercat-1.5.2.tar.bz2
cd ethercat-1.5.2/
./configure --enable-8139too=no
make
sudo make modules
目录
1. netdev和sock_create_kern问题
2. init_timer问题
3. eccdev_vma_fault问题
4.(ec_cdev_priv_t *)问题
5.sched_param 问题
6.一次性快速成功的安装方式
就会出现和昨天一样的错误
首先是devices/generic.c
的152行,加 NET_NAME_UNKNOWN
dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, NET_NAME_UNKNOWN, ether_setup);
的210行
ret = sock_create_kern(&init_net, PF_PACKET, SOCK_RAW, htons(ETH_P_ETHERCAT),&dev->socket);
继续sudo make modules
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/examples/mini/mini.c:495:5: error: implicit declaration of function ‘init_timer’; did you mean ‘init_timers’? [-Werror=implicit-function-declaration]
init_timer(&timer);
^~~~~~~~~~
init_timers
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/examples/mini/mini.c:496:20: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
timer.function = cyclic_task;
参考链接:
Linxu内核编程报错 ‘init_timer’
Improving the kernel timers API [LWN.net]
timer.h - include/linux/timer.h - Linux source code (v5.4.154) - Bootlin
将195行左右那一段改成这样
printk(KERN_INFO PFX "Starting cyclic sample thread.\n");
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)
init_timer(&timer);
timer.function = cyclic_task;
timer.expires = jiffies + 10;
add_timer(&timer);
#else
// void timer_setup(struct timer_list *timer, void (*callback)(struct timer_list *),
// unsigned int flags);
timer_setup(&timer,cyclic_task, 0);
然后把310行左右改为
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)
void cyclic_task(unsigned long data)
#else
void cyclic_task(struct timer_list *t)
#endif
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/cdev.c:87:14: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.fault = eccdev_vma_fault
^~~~~~~~~~~~~~~~
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/cdev.c:87:14: note: (near initialization for ‘eccdev_vm_ops.fault’)
In file included from /home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/cdev.c:42:0:
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/cdev.c: In function ‘eccdev_vma_fault’:
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/cdev.c:277:46: error: ‘struct vm_fault’ has no member named ‘virtual_address’
" offset = %lu, page = %p\n", vmf->virtual_address, offset, page);
^
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/master.h:115:38: note: in definition of macro ‘EC_MASTER_DBG’
master->index, ##args); \
将master.cdev文件64开始的那行改为
#define PAGE_FAULT_VERSION KERNEL_VERSION(2, 6, 23)
#if LINUX_VERSION_CODE >= PAGE_FAULT_VERSION
// #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
// static vm_fault_t eccdev_vma_fault(struct vm_fault *);
// #else
// static int eccdev_vma_fault(struct vm_area_struct*, struct vm_fault *);
// #endif
static vm_fault_t eccdev_vma_fault(struct vm_fault *);
#else
static struct page *eccdev_vma_nopage(
struct vm_area_struct *, unsigned long, int *);
#endif
第259行开始的那个函数定义改为
//static int eccdev_vma_fault(
// #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
// vm_area_struct *vma, /**< Virtual memory area. */
// #endif
// struct vm_fault *vmf /**< Fault data. */
// )
//
static vm_fault_t eccdev_vma_fault(struct vm_fault *vmf)
第282行
EC_MASTER_DBG(priv->cdev->master, 1, "Vma fault, virtual_address = %p,"
" offset = %lu, page = %p\n", vmf->virtual_address, offset, page);
改为
EC_MASTER_DBG(priv->cdev->master, 1, "Vma fault, virtual_address = %p,"
" offset = %lu, page = %p\n", vmf->address, offset, page);
mm.h - include/linux/mm.h - Linux source code (v5.4.154) - Bootlin
另外发现, 在5.4的版本中, .fault 的类型已经定义为vm_fault_t ,并且也只有vm_fault这一类型的参数
5.4的版本:
struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
void (*close)(struct vm_area_struct * area);
int (*split)(struct vm_area_struct * area, unsigned long addr);
int (*mremap)(struct vm_area_struct * area);
vm_fault_t (*fault)(struct vm_fault *vmf);
vm_fault_t (*huge_fault)(struct vm_fault *vmf,
enum page_entry_size pe_size);
void (*map_pages)(struct vm_fault *vmf,
pgoff_t start_pgoff, pgoff_t end_pgoff);
unsigned long (*pagesize)(struct vm_area_struct * area);
vm_fault_t (*page_mkwrite)(struct vm_fault *vmf);
vm_fault_t (*pfn_mkwrite)(struct vm_fault *vmf);
int (*access)(struct vm_area_struct *vma, unsigned long addr,
void *buf, int len, int write);
const char *(*name)(struct vm_area_struct *vma);
3.14的版本:
struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
void (*close)(struct vm_area_struct * area);
int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
void (*map_pages)(struct vm_area_struct *vma, struct vm_fault *vmf);
int (*page_mkwrite)(struct vm_area_struct *vma, struct vm_fault *vmf);
int (*access)(struct vm_area_struct *vma, unsigned long addr,
void *buf, int len, int write);
#ifdef CONFIG_NUMA
int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new);
struct mempolicy *(*get_policy)(struct vm_area_struct *vma,
unsigned long addr);
int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
const nodemask_t *to, unsigned long flags);
#endif
/* called by sys_remap_file_pages() to populate non-linear mapping */
int (*remap_pages)(struct vm_area_struct *vma, unsigned long addr,
unsigned long size, pgoff_t pgoff);
};
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/cdev.c:267:47: error: ‘vma’ undeclared (first use in this function); did you mean ‘vmf’?
ec_cdev_priv_t *priv = (ec_cdev_priv_t *) vma->vm_private_data;
将267行改为
ec_cdev_priv_t *priv = (ec_cdev_priv_t *) vma->vm_private_data;
改为
ec_cdev_priv_t *priv = (ec_cdev_priv_t *)vmf->vma->vm_private_data;
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/master.c: In function ‘ec_master_eoe_start’:
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/master.c:1637:12: error: variable ‘param’ has initializer but incomplete type
struct sched_param param = { .sched_priority = 0 };
^~~~~~~~~~~
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/master.c:1637:35: error: ‘struct sched_param’ has no member named ‘sched_priority’
struct sched_param param = { .sched_priority = 0 };
^~~~~~~~~~~~~~
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/master.c:1637:52: warning: excess elements in struct initializer
struct sched_param param = { .sched_priority = 0 };
^
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/master.c:1637:52: note: (near initialization for ‘param’)
/home/robotarm/文档/ethercat_master_file/ethercat-1.5.2/master/master.c:1637:24: error: storage size of ‘param’ isn’t known
struct sched_param param = { .sched_priority = 0 };
昨天就是卡在这个问题这里,然后在目录下找了其他调用sched_param这个的文件,发现是包含
在usr/include/sched.h里是这样开头的
#ifndef _SCHED_H
#define _SCHED_H
在/usr/include/x86_64-linux-gnu/bits/sched.h 里的开头是这样的
#ifndef _BITS_SCHED_H
#define _BITS_SCHED_H 1
#ifndef _SCHED_H
# error "Never include directly; use instead."
#endif
在/usr/include/linux/sched.h 的开头
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_SCHED_H
#define _LINUX_SCHED_H
十分神奇,水平有限,看不太懂
后来开了个会,一个大大大佬用github下载的igh源码一下子就装好了
出于好奇,再比较一下两者区别
在github下载的 对 sched_param 进行go to definition的时候,跳转到的文件是
usr/include/linux/sched/types.h
#ifndef _LINUX_SCHED_TYPES_H
#define _LINUX_SCHED_TYPES_H
#include
struct sched_param {
int sched_priority;
};
而在master.c的头文件里也加入了
#ifdef EC_EOE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#include // struct sched_param
#include // sched_setscheduler
#endif
安装igh_ze3000的博客-CSDN博客
git clone http://gitlab.com/etherlab.org/ethercat.git
cd ethercat/
./bootstrap
./configure --enable-8139too=no
sudo make
sudo make modules
sudo make install
sudo make modules_install
配置
cd /opt/etherlab
将ifconfig查到的根ethercat通信的网卡mac地址复制一下,然后
gedit etc/sysconfig/ethercat
将下面两行按照文件的位置填进去
MASTER0_DEVICE="00:e8:4c:68:30:cd"
DEVICE_MODULES="generic"
配置一下路径,注意这个/etc/init.d这个
sudo cp etc/sysconfig/ethercat /etc/sysconfig/
sudo ln -s /opt/etherlab/etc/init.d/ethercat /etc/init.d/
sudo /etc/init.d/ethercat start
出现
Starting EtherCAT master 1.5.2 done
就代表成功了
。。。后面那些懒得复制粘贴了,反正在另一篇那里有