设计目的:
IGH平台是完完全全的Linux内核层代码,这样设计的目的是为了保证Ethercat主站的实时性。但是Linux即使加了实时补丁也只能实现软实时效果。所以有很多需求要将IGH移植到硬实时操作系统,要实现IGH跨平台的功能。先将IGH移植到Linux应用层,然后根据对应的操作系统API,做对应的修改封装。(SOEM的确实现了跨平台的功能,但是整个软件架构实在是太太糟糕,协议栈的健壮性太差,最主要的是设计时根本没有考虑过实时性的问题,不建议高实时要求ethercat链路中用SOEM做主站)
设计思路:
1.先解决头文件包含耦合的问题
IGH为了代码整洁性,将各个模块的接口分成了对应模块的.h头文件,但是各个模块又有依赖关系,导致头文件之前互相包涵,在移植到应用层会导致各种报错,解决方案是将各个头文件中的结构体定义全部提取到一个公共的.h文件中
2.借鉴SOEM封装硬件层的思路,构造osal层
将锁,信号量,time时间函数获取,睡眠函数,ethercat帧的收发这些跟系统驱动相关的API,在修改IGH的驱动函数发送层,将主站跟系统隔离开来。
int osal_nsleep (uint32 nsec);
int osal_mutex_init(osal_mutex_t *mutex);
int osal_mutex_lock(osal_mutex_t *mutex);
int osal_mutex_unlock(osal_mutex_t *mutex);
int osal_mutex_destory(osal_mutex_t *mutex);
int osal_sem_init(osal_sem_t *sem);
int osal_sem_wait(osal_sem_t *sem, int cond);
int osal_sem_wait_timeout(osal_sem_t *sem, int timeout);
int osal_sem_post(osal_sem_t *sem);
int osal_sem_post_all(osal_sem_t *sem);
int osal_sem_destory(osal_sem_t *sem);
int osal_socket_int(struct ec_device *dev);
int osal_socket_read(struct ec_device *dev, char *buf, size_t len);
int osal_socket_send(struct ec_device *dev, char *buf, int len);
int osal_socket_destory(struct ec_device *dev);
int osal_socket_link(struct ec_device *dev);
void osal_timer_start(osal_timert * self, uint32 timeout_us);
boolean osal_timer_is_expired(osal_timert * self);
int osal_usleep(uint32 usec);
ec_timet osal_current_time(void);
void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff);
int osal_thread_create(void *thandle, int stacksize, void *func, void *param);
int osal_thread_create_rt(void *thandle, int stacksize, void *func, void *param);
void *osal_malloc(size_t size);
void osal_free(void *ptr);
int osal_thread_stop(void *thandle);
unsigned long osal_gettimeofday(struct timeval *tv, struct timezone *tz);
比如IGH以太网接收层的接口函数变成了
3.解决内核层和应用层差异化的API接口和头文件
设计结果:
linux应用层的实时性不好,抖动太大了,在运行时容易出现收发帧超时的warn信息