导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页
    1. 主页
    2. zznzzn
    3. 最佳
    • 资料
    • 关注 2
    • 粉丝 2
    • 我的积分 3539
    • 主题 44
    • 帖子 61
    • 最佳 4
    • 群组 0

    zznzzn 发布的最佳帖子

    • T113上uart转485功能实现

      sunxi-uart.c
      sunxi-uart.h

      如下是T113在linux下实现uart转485,patch可以参考附件,dts的配置如下:

      uart1: uart@05000400 {
      		status = "okay";
      		uart1_type = <2>;
      		uart1_rs485=<1>;
      		uart1_485fl=<0>;
      		uart1_485oe=<&pio PG 1 1 0xffffffff 0xffffffff 0>;
      	};
      

      patch如下:

      diff --git a/arch/arm/boot/dts/sun8iw20p1.dtsi b/arch/arm/boot/dts/sun8iw20p1.dtsi
      index 6e51b72..4d3fb29 100644
      --- a/arch/arm/boot/dts/sun8iw20p1.dtsi
      +++ b/arch/arm/boot/dts/sun8iw20p1.dtsi
      @@ -613,8 +613,11 @@
       			clock-names = "uart1";
       			resets = <&ccu RST_BUS_UART1>;
       			uart1_port = <1>;
      -			uart1_type = <4>;
      +			uart1_type = <2>;
       			status = "okay";
      +			uart1_rs485=<1>;
      +			uart1_485fl=<0>;
      +			uart1_485oe=<&pio PG 1 1 0xffffffff 0xffffffff 0>;			
       		};
       
       		uart2: uart@2500800 {
      diff --git a/drivers/tty/serial/sunxi-uart.c b/drivers/tty/serial/sunxi-uart.c
      index 395b1bd..f013ad2 100644
      --- a/drivers/tty/serial/sunxi-uart.c
      +++ b/drivers/tty/serial/sunxi-uart.c
      @@ -43,6 +43,10 @@
       #include <linux/of.h>
       #include <linux/of_irq.h>
       #include <linux/of_address.h>
      +
      +#include <linux/delay.h>
      +#include <uapi/linux/sched/types.h>
      +#include <linux/of_gpio.h>
       #include "sunxi-uart.h"
       
       #if defined(CONFIG_SERIAL_SUNXI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
      @@ -191,6 +195,28 @@ static inline void sw_uart_disable_ier_thri(struct uart_port *port)
       	}
       }
       
      +
      +/********************************************************************/
      +/* cet,liudachuan: rs485 delayed rts release control, not used now */
      +# if 0
      +static enum hrtimer_restart uart_set_rs485(struct hrtimer *u_timer)
      +{
      +	struct sw_uart_port *sw_uport = container_of(u_timer, struct sw_uart_port, uart_timer);
      +	if(sw_uport == NULL)
      +	{
      +		SERIAL_DBG("faile to get sw_uport\n", __func__);
      +		return HRTIMER_NORESTART;
      +	}
      +	
      +	if(sw_uport->rs485_en){
      +		gpio_direction_output(sw_uport->rs485oe_io.gpio, sw_uport->rs485_fl);
      +	}
      +
      +	return HRTIMER_NORESTART;
      +}
      +#endif
      +/***********************************************************************************/
      +
       static unsigned int sw_uart_handle_rx(struct sw_uart_port *sw_uport, unsigned int lsr)
       {
       	unsigned char ch = 0;
      @@ -272,23 +298,66 @@ static unsigned int sw_uart_handle_rx(struct sw_uart_port *sw_uport, unsigned in
       	return lsr;
       }
       
      +
      +
      +/******************************************************************************/
      +/* cet,liudachuan: add sw-rs485 support */
      +#define BITS_PER_SERIAL_BYTE	10
      +#define NANOSECOND_PER_USECONDS	1000
      +#define USECONDS_PER_SECOND		1000000
      +static void sw_uart_rs485_cal_tout(struct uart_port *port, unsigned int lcr)
      +{
      +	struct sw_uart_port *sw_uport = UART_TO_SPORT(port);
      +	unsigned int bits_per_byte;
      +	if (lcr & SUNXI_UART_LCR_PARITY) /*有奇偶的时候,byte=start+8+parity=10*/
      +		bits_per_byte = 10;
      +	else    /*无奇偶的时候,byte=start+8=9*/
      +		bits_per_byte = 9;
      +
      +	if (sw_uport->baud != 0) {
      +		sw_uport->tout = 
      +			(bits_per_byte * USECONDS_PER_SECOND) / (sw_uport->baud) * NANOSECOND_PER_USECONDS;
      +	}
      +	else {
      +		sw_uport->tout = 0;
      +	}
      +}
      +
       static void sw_uart_stop_tx(struct uart_port *port)
       {
      -#if IS_ENABLED(CONFIG_SERIAL_SUNXI_DMA)
       	struct sw_uart_port *sw_uport = UART_TO_SPORT(port);
      +
      +#if IS_ENABLED(CONFIG_SERIAL_SUNXI_DMA)
       	struct sw_uart_dma *uart_dma = sw_uport->dma;
       
       	if (uart_dma->use_dma & TX_DMA)
       		sw_uart_stop_dma_tx(sw_uport);
       #endif
       	sw_uart_disable_ier_thri(port);
      +	/* cet,liudachuan: delay 1 byte transmit time then turn off rs485 tx-en */
      +	if (sw_uport->rs485_en) {
      +	   	// hrtimer_start(&sw_uport->uart_timer, sw_uport->tout, HRTIMER_MODE_REL);
      +		unsigned char lsr = 0;
      +		while ((lsr & SUNXI_UART_LSR_BOTH_EMPTY) != SUNXI_UART_LSR_BOTH_EMPTY) {
      +			// cpu_relax();
      +			udelay(10);
      +			lsr = serial_in(port, SUNXI_UART_LSR);
      +		};
      +		gpio_direction_output(sw_uport->rs485oe_io.gpio, sw_uport->rs485_fl);
      +	}
       }
       
       static void sw_uart_start_tx(struct uart_port *port)
       {
      -#if IS_ENABLED(CONFIG_SERIAL_SUNXI_DMA)
       	struct sw_uart_port *sw_uport = UART_TO_SPORT(port);
      +	/* cet,liudachuan: rs485 rts = 1 */
      +	// serial_out(port, sw_uport->mcr & (~SUNXI_UART_MCR_RTS), SUNXI_UART_MCR);
      +	if(sw_uport->rs485_en){
      +		// udelay(20);
      +		gpio_direction_output(sw_uport->rs485oe_io.gpio, !sw_uport->rs485_fl);
      +	}
       
      +#if IS_ENABLED(CONFIG_SERIAL_SUNXI_DMA)
       	if (!((sw_uport->dma->use_dma & TX_DMA) && sw_uport->dma->tx_dma_used))
       #endif
       		sw_uart_enable_ier_thri(port);
      @@ -342,8 +411,14 @@ static void sw_uart_handle_tx(struct sw_uart_port *sw_uport)
       		uart_write_wakeup(&sw_uport->port);
       		spin_lock(&sw_uport->port.lock);
       	}
      -	if (uart_circ_empty(xmit))
      -		sw_uart_stop_tx(&sw_uport->port);
      +
      +	/* cet,liudachuan: add sw-rs485 support */
      +	// if (uart_circ_empty(xmit))
      +	//     sw_uart_stop_tx(&sw_uport->port);
      +	if (!sw_uport->rs485_en) {
      +		if (uart_circ_empty(xmit))
      +			sw_uart_stop_tx(&sw_uport->port);
      +	}
       }
       
       static unsigned int sw_uart_modem_status(struct sw_uart_port *sw_uport)
      @@ -354,7 +429,7 @@ static unsigned int sw_uart_modem_status(struct sw_uart_port *sw_uport)
       	sw_uport->msr_saved_flags = 0;
       
       	if (status & SUNXI_UART_MSR_ANY_DELTA && sw_uport->ier & SUNXI_UART_IER_MSI &&
      -	    sw_uport->port.state != NULL) {
      +		sw_uport->port.state != NULL) {
       		if (status & SUNXI_UART_MSR_TERI)
       			sw_uport->port.icount.rng++;
       		if (status & SUNXI_UART_MSR_DDSR)
      @@ -724,6 +799,25 @@ static enum hrtimer_restart sw_uart_report_dma_rx(struct hrtimer *rx_hrtimer)
       
       #endif
       
      +
      +
      +/**
      + * 串口中断实测14-135us,数据发完后gic_handle_irq两次进入中断,第二次才真正进入串口中断,导致整个延迟变大
      + * 通过提高中断线程优先级为4以上,可以解决,时间缩短到(-5-35us),这里优先级设置为1
      + * cet,ljt 2021.10
      +*/
      +static inline void sw_uart_irq_set_pri(struct sw_uart_port *sw_uport)
      +{
      +    struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO - 2 };
      +	if (sw_uport->irq_pri_promoted)
      +		return;
      +	if (sched_setscheduler(current, SCHED_FIFO, &param) < 0)
      +	{
      +		SERIAL_MSG("sched_setscheduler set error\n");
      +	}
      +	sw_uport->irq_pri_promoted = 1;
      +}
      +
       static irqreturn_t sw_uart_irq(int irq, void *dev_id)
       {
       	struct uart_port *port = dev_id;
      @@ -731,6 +825,9 @@ static irqreturn_t sw_uart_irq(int irq, void *dev_id)
       	unsigned int iir = 0, lsr = 0;
       	unsigned long flags;
       
      +	/* if we hasn't promote the irq priority, set priority to 97 */
      +	//sw_uart_irq_set_pri(sw_uport);
      +
       	spin_lock_irqsave(&port->lock, flags);
       
       	iir = serial_in(port, SUNXI_UART_IIR) & SUNXI_UART_IIR_IID_MASK;
      @@ -1072,7 +1169,7 @@ static void sw_uart_flush_buffer(struct uart_port *port)
       }
       
       static void sw_uart_set_termios(struct uart_port *port, struct ktermios *termios,
      -			    struct ktermios *old)
      +				struct ktermios *old)
       {
       	struct sw_uart_port *sw_uport = UART_TO_SPORT(port);
       	unsigned long flags;
      @@ -1119,6 +1216,12 @@ static void sw_uart_set_termios(struct uart_port *port, struct ktermios *termios
       	dlh = quot >> 8;
       	SERIAL_DBG("set baudrate %d, quot %d\n", baud, quot);
       
      +	/* cet,liudachuan: add sw rs485 support */
      +	sw_uport->baud = baud;
      +	if (sw_uport->rs485_en) {
      +		sw_uart_rs485_cal_tout(port, lcr);
      +	}
      +
       	spin_lock_irqsave(&port->lock, flags);
       	uart_update_timeout(port, termios->c_cflag, baud);
       
      @@ -1379,7 +1482,7 @@ static int sw_uart_ioctl(struct uart_port *port, unsigned int cmd,
       }
       
       static void sw_uart_pm(struct uart_port *port, unsigned int state,
      -		      unsigned int oldstate)
      +			  unsigned int oldstate)
       {
       #if IS_ENABLED(CONFIG_EVB_PLATFORM)
       	int ret;
      @@ -1727,7 +1830,7 @@ static void sw_console_putchar(struct uart_port *port, int c)
       }
       
       static void sw_console_write(struct console *co, const char *s,
      -			      unsigned int count)
      +				  unsigned int count)
       {
       	struct uart_port *port = NULL;
       	struct sw_uart_port *sw_uport;
      @@ -1909,6 +2012,9 @@ static int sw_uart_probe(struct platform_device *pdev)
       	char uart_para[16] = {0};
       	const char *uart_string;
       	int ret = -1;
      +	int rs485_en = 0;         //2020.09.24 2¨??? ¨?¨a?¨?RS485????
      +	int rs485_fl = 0;
      +
       	struct device_node *apk_np = of_find_node_by_name(NULL, "auto_print");
       	const char *apk_sta = NULL;
       #if IS_ENABLED(CONFIG_SERIAL_SUNXI_DMA)
      @@ -2052,6 +2158,45 @@ static int sw_uart_probe(struct platform_device *pdev)
       	else
       		sw_uport->card_print = false;
       
      +	/* cet,liudachuan: add sw-rs485 support */
      +	/************ Modify by wangshunfan @2021.01.11 for this part *************/
      +	/* Get rs485 enable flag */
      +	snprintf(uart_para, sizeof(uart_para), "uart%d_rs485", pdev->id);
      +	ret = of_property_read_u32(np, uart_para, &rs485_en);
      +	if (ret) {
      +		SERIAL_MSG("error to get uart%d_rs485\n", pdev->id);
      +			rs485_en = 0;
      +	}
      +	sw_uport->rs485_en = rs485_en;
      +
      +	//SERIAL_DBG("caid rs485_en = %d port = %d", rs485_en, pdev->id);
      +	if (sw_uport->rs485_en) {
      +		snprintf(uart_para, sizeof(uart_para), "uart%d_485fl", pdev->id);
      +		ret = of_property_read_u32(np, uart_para, &rs485_fl);
      +		if (ret) {
      +			SERIAL_MSG("error to get tuart%d_rs485\n", pdev->id);
      +				rs485_fl = 0;
      +		}
      +		sw_uport->rs485_fl = rs485_fl;
      +
      +		/* Get rs485 enable control pin, request and init gpio */
      +		snprintf(uart_para, sizeof(uart_para), "uart%d_485oe", pdev->id);
      +		sw_uport->rs485oe_io.gpio = of_get_named_gpio_flags(np, uart_para, 0,
      +			(enum of_gpio_flags *)(&(sw_uport->rs485oe_io)));
      +		if (gpio_is_valid(sw_uport->rs485oe_io.gpio)){
      +			gpio_request(sw_uport->rs485oe_io.gpio, NULL);
      +			gpio_direction_output(sw_uport->rs485oe_io.gpio, sw_uport->rs485_fl);
      +		}
      +
      +		/* Init hrtimer for rs485 and set timeout callback function */
      +		// hrtimer_init(&sw_uport->uart_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
      +		// sw_uport->uart_timer.function = uart_set_rs485;
      +
      +		sw_uport->irq_pri_promoted = 0;
      +		SERIAL_MSG("uart%d rs485 enabled\n", pdev->id);
      +	}
      +	/**************** end of modify by wangshunfan for this part ****************/
      +
       	pdata->used = 1;
       	port->iotype = UPIO_MEM;
       	port->type = PORT_SUNXI;
      @@ -2129,7 +2274,14 @@ static int sw_uart_remove(struct platform_device *pdev)
       	struct sw_uart_port *sw_uport = platform_get_drvdata(pdev);
       
       	SERIAL_DBG("release uart%d port\n", sw_uport->id);
      -#if IS_ENABLED(CONFIG_SERIAL_SUNXI_DMA)
      +
      +	/* cet,liudachuan: add sw-rs485 support */
      +	if (sw_uport->rs485_en) {
      +		gpio_free(sw_uport->rs485oe_io.gpio);	/* free gpio of rs485 */
      +		// hrtimer_cancel(&sw_uport->uart_timer);	/* canel hrtimer      */
      +	}
      +
      +#ifdef CONFIG_SERIAL_SUNXI_DMA
       	sw_uart_release_dma_tx(sw_uport);
       	sw_uart_release_dma_rx(sw_uport);
       #endif
      diff --git a/drivers/tty/serial/sunxi-uart.h b/drivers/tty/serial/sunxi-uart.h
      index 565acbf..ab096d6 100644
      --- a/drivers/tty/serial/sunxi-uart.h
      +++ b/drivers/tty/serial/sunxi-uart.h
      @@ -22,6 +22,8 @@
       #include <linux/dmaengine.h>
       #include <linux/reset.h>
       //include <linux/serial_core.h>
      +#include <linux/ktime.h>
      +#include <linux/sunxi-gpio.h>
       
       /* SUNXI UART PORT definition*/
       #define PORT_MAX_USED	PORT_LINFLEXUART  /* see include/uapi/linux/serial_core.h */
      @@ -106,6 +108,16 @@ struct sw_uart_port {
       	struct serial_rs485 rs485conf;
       	bool card_print;
       	bool throttled;
      +
      +    /* cet,liudachuan: add rs485 support(not hardware's rs485) */
      +    struct gpio_config rs485oe_io;
      +    unsigned int rs485_en;
      +    unsigned int rs485_fl;
      +    struct hrtimer uart_timer;
      +    unsigned int baud;
      +    int irq_pri_promoted;
      +    /* Added by wangshunfan @2021.01.11 for hrtimer timeout */
      +	ktime_t tout;
       };
       
       /* register offset define */
      @@ -191,6 +203,8 @@ struct sw_uart_port {
       #define SUNXI_UART_LSR_OE         (BIT(1))
       #define SUNXI_UART_LSR_DR         (BIT(0))
       #define SUNXI_UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */
      +/* cet,liudachuan: add BOTH_EMPTY macro */
      +#define SUNXI_UART_LSR_BOTH_EMPTY   (SUNXI_UART_LSR_TEMT | SUNXI_UART_LSR_THRE)
       /* Modem Status Register */
       #define SUNXI_UART_MSR_DCD        (BIT(7))
       #define SUNXI_UART_MSR_RI         (BIT(6))
      
      发布在 MR Series
      zznzzn
      zznzzn
    • 如何给R128在FreeRTOS下配置/data目录

      在调试音频、usb等模块时,会发现SDK的根目录下没有/data该目录,导致无法存储所需要的文件,这就是因为/data目录没有配置好的原因。

      1、选上配置

      首先需要选上的配置:
      运行mrtos_menuconfig,选上COMPONENT_LITTLEFS

      -> System components
          -> thirdparty components
              [*] LittleFS Filesystem
      

      选上littlefs只是支持了这个功能,另外还需要对分区进行配置。

      2、确认分区表

      通过命令cconfigs,跳转到方案配置目录,找到文件sys_partition.fex

      这里需要注意,目录下可能会有多个分区文件,带着不同后缀的,比如说nor,xip等等的,因此需要确认用的是哪一个分区表,以免修改不生效

      在方案已经编译完成之后,运行

      pack
      

      命令对方案进行打包,通过打包时打印出来的log信息,可以提取到用的是哪一个分区表,如下:

      download1FileByUrl.png

      如图片,可以确认到打包示例中调用的分区表。

      3、修改分区表

      在分区表中加入以下配置代码:

      [partition]
          name         = UDISK
          downloadfile = "data_udisk.fex"
          user_type    = 0x8100
      

      通过上述的代码,在打包固件调用的pack_img.sh脚本中,通过函数

      function make_data_image()
      

      会创建对应的分区。

      4、挂载目录

      分区已经建好的话,剩下就是通过littlefs将区分挂载到目录下了。

      在方案的main.c函数中(这里只是举个例子,在系统启动时挂载目录即可,但是需要注意要在flash初始化完成之后才能挂载)

      在main.c中,添加以下代码:

      littlefs_mount("/dev/UDISK", "/data", true);
      

      /dev/UDISK就是分区名字,由分区表产生的。
      /data则是创建目录的名字及路径。

      通过以上步骤,即可为方案新建一个/data目录,可以用于保存一些程序所需要用到的文件。

      5、保存文件到data目录下

      1.在SDK编译环境中存放文件
      可以在编译时,所需要的文件放到UDISK分区。

      存放文件到UDISK分区方法为:

      直接将文件拷贝到编译环境对应的路径下:

      {root_dir}/board/芯片名/方案名/data/UDISK
      

      在SDK打包时就会将UDISK目录下的文件全部打包生成udisk的镜像,最终打包到image里。

      在烧录时,就会udisk的镜像烧录到对应的分区里。系统启动,挂载分区之后,就直接可以通过/data目录访问到对应的文件了。

      2.通过代码读写文件
      FreeRTOS SDK中,通过fopen fwrite fread等POSIX接口,即可操作UDISK分区(/data目录)的文件。

      以下做个示例:

      static int save_to_file(void *str, void *start, int length)
      {
              FILE *fp = NULL;
      
              fp = fopen(str, "wb+"); //save more frames
              if (!fp) {
                      printf(" Open %s error\n", (char *)str);
      
                      return -1;
              }
      
              if (fwrite(start, length, 1, fp)) {
                      fclose(fp);
      
                      return 0;
              } else {
                      printf(" Write file fail (%s)\n", strerror(errno));
                      fclose(fp);
      
                      return -1;
              }
      
              return 0;
      }
      
      • str: 路径名,若为/data目录的话,比如说写入一个a.txt,str可以定义为 /data/a.txt
      • start:所需要写入的数据起始地址
      • length:所需要写的数据的长度。
      发布在 A Series
      zznzzn
      zznzzn
    • 基于全志T507-H的Linux-RT + Igh EtherCAT主站案例分享

      本文将为各位工程师演示全志T507-H工业评估板(TLT507-EVM)基于IgH EtherCAT控制伺服电机方法,生动说明Linux-RT + Igh EtherCAT的强大之处!

      Linux-RT系统的优势

      • 内核开源、免费、功能完善。

      • RT PREEMPT补丁,使Linux内核成为硬实时操作系统,无需完整的内核重写。

      • 既有实时性,又有相同的开发生态系统(包括相同工具链、文件系统和安装方法,以及相同的POSIX API等),实现产品快速上市的期望。

      Linux-RT实时性测试(Cyclictest工具)

      Cyclictest常用于实时系统的基准测试,是评估实时系统相对性能的最常用工具之一。Cyclictest反复测量并精确统计线程的实际唤醒时间,以提供有关系统的延迟信息。它可测量由硬件、固件和操作系统引起的实时系统的延迟。

      基于全志T507-H(硬件平台:创龙科技TLT507-EVM评估板),按照创龙科技提供的案例用户手册进行操作,使用Cyclictest程序测试系统实时性,得出如下测试结果。

      在这里插入图片描述

      在这里插入图片描述

      对比测试数据,可看到基于Linux-RT-4.9.170内核的系统的延时更加稳定,最大延时更低,系统实时性更佳。

      Linux-RT性能测试

      基于全志T507-H(硬件平台:创龙科技TLT507-EVM评估板),按照创龙科技提供的案例用户手册进行操作,测试分别在CPU空载、满负荷(运行stress压力测试工具)、隔离CPU核心的情况下,得出如下测试结果。

      备注:测试数据与实际测试环境有关,仅供参考。

      在这里插入图片描述

      CPU空载状态测试,CPU0、CPU1核心Max Latencies值最大,为69us,CPU3核心的Max Latencies值最小,为66us。

      在这里插入图片描述

      CPU满负荷状态测试,CPU0核心Max Latencies值最大,为88us,CPU3核心的Max Latencies值最小,为64us。

      在这里插入图片描述

      隔离CPU核心状态测试,CPU0核心Max Latencies值最大,为73us,隔离CPU3核心的Max Latencies值最小,为41us。

      根据CPU空载、CPU满负荷、隔离CPU核心三种状态的测试结果可知:当程序指定至隔离的CPU3核心上运行时,Linux系统延迟最低,可有效提高系统实时性。故推荐对实时性要求较高的程序(功能)指定至T507-H隔离的CPU核心运行。

      基于全志T507-H的Linux-RT + IgH EtherCAT主站演示

      下文主要介绍基于全志T507-H(硬件平台:创龙科技TLT507-EVM评估板)案例,按照创龙科技提供的案例用户手册进行操作得出测试结果。

      本次演示的开发环境:

      • Windows开发环境:Windows 7 64bit、Windows 10 64bit
      • Linux开发环境:Ubuntu18.04.4 64bit
      • 虚拟机:VMware16.2.5
      • U-Boot:U-Boot 2018
      • Kernel:Linux-RT-4.9.170
      • LinuxSDK:LinuxSDK-[版本号].tar.gz(基于全志官方V2.0_20220618)
      • IgH EtherCAT:ethercat-stable-1.5-gcd0d17d-20210723
      • 伺服驱动器:台达ASD-A2-0121-E
      • 伺服电机:台达ECMA-C10401GS
      • 硬件平台:TLT507-EVM评估板(基于全志T507-H)

      IgH EtherCAT简介

      IgH EtherCAT为运行于Linux系统的免费开源EtherCAT主站程序,框架如下所示,

      在这里插入图片描述

      IgH EtherCAT主站通过构建Linux字符设备,应用程序通过对字符设备的访问实现与EtherCAT主站模块的通信。

      IgH EtherCAT开发包提供EtherCAT工具,该工具提供各种可在Linux用户层运行的命令,可直接实现对从站的访问和设置,如设置从站地址、显示总线配置、显示PDO数据、读写SDO参数等。

      案例说明

      案例功能:EtherCAT通讯周期时间为1ms,控制伺服电机正转和反转,并通过串口循环打印EtherCAT通讯周期时间的最大值和最小值。

      (1)正转:伺服电机目标速度从0加速到10000,当达到10000速度后,控制伺服电机减速至0,循环运行。

      (2)反转:伺服电机目标速度从0加速到-10000,当达到-10000速度后,控制伺服电机减速至0,循环运行。

      在这里插入图片描述

      为便于测试,我司提供已验证的基于Linux-RT编译生成的内核镜像文件和内核模块,位于产品资料“4-软件资料\Linux\Kernel\image\linux-4.9.170-[版本号]-[Git系列号]\”目录下。

      请将Linux-RT内核镜像boot-rt.fex和Linux-RT内核配套的内核模块modules-rt目录下4.9.170-[版本号]-[Git系列号].tar.gz压缩包的拷贝至评估板文件系统目录下。

      执行如下命令,将boot-rt.fex重命名为boot.fex,同时将内核模块压缩包解压。

      Target#mv boot-rt.fex boot.fex
      
      Target#tar -zxf 4.9.170-rt129-g4c65c66.tar.gz
      

      在这里插入图片描述

      执行如下命令替换内核镜像和内核模块,评估板重启生效。

      备注:mmcblk1为Micro SD对应的设备节点,如需固化至eMMC,请将设备节点修改为mmcblk0。

      Target#dd if=boot.fex of=/dev/mmcblk1p3 conv=fsync
      
      Target#rm /lib/modules/* -rf
      
      Target#cp $(uname -r) /lib/modules/ -r
      
      Target#sync
      
      Target#reboot
      

      在这里插入图片描述

      在这里插入图片描述

      案例测试

      请按下图所示使用网线连接评估板ETH0 RGMII网口和伺服驱动器A的IN网口,将伺服驱动器A的OUT网口使用网线连接至伺服驱动器B的IN网口。

      在这里插入图片描述
      在这里插入图片描述
      为便于测试,我司提供的经验证的IgH EtherCAT主站程序为案例"igh_ethercat\images"目录下的ethercat-stable-1.5-gcd0d17d.tar.gz压缩包,将其拷贝至评估板文件系统任意目录下。

      执行如下命令,解压ethercat-stable-1.5-gcd0d17d.tar.gz压缩包将会得到_install文件夹。

      Target#tar -zxf ethercat-stable-1.5-gcd0d17d.tar.gz
      

      在这里插入图片描述

      执行如下命令,并查询评估板网卡物理地址。

      Target#ifconfig
      

      在这里插入图片描述

      执行如下命令,加载驱动模块。

      Target#insmod -f /root/_install/modules/ec_master.ko main_devices=46:99:F6:AB:1F:19
      

      在这里插入图片描述
      执行如下命令,拷贝EtherCAT主站相关文件至评估板文件系统。

      Target#mkdir /etc/sysconfig
      
      Target#cp /root/_install/etc/sysconfig/ethercat /etc/sysconfig
      
      Target#ls /lib/modules/$(uname -r)//查看是否已创建modules目录
      
      Target#cp ./_install/modules/ec_master.ko /lib/modules/$(uname -r)
      
      Target#depmod -a //同步模块依赖关系,同步过程中打印警告请忽略
      

      在这里插入图片描述

      执行如下命令,启动EtherCAT主站。

      Target#/root/_install/etc/init.d/ethercat start
      

      在这里插入图片描述

      执行如下命令,加载ec_generic.ko驱动文件。

      Target#insmod -f /root/_install/modules/ec_generic.ko
      

      在这里插入图片描述
      执行如下命令,添加IgH动态链接库路径。

      Target#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/_install/lib
      

      在这里插入图片描述
      将案例bin目录下的igh_ethercat_dc_motor可执行文件拷贝至评估板文件系统,执行如下命令查看参数信息。

      Target#./igh_ethercat_dc_motor --help
      

      在这里插入图片描述
      执行如下命令,控制两台伺服电机同时正转。

      Target#./igh_ethercat_dc_motor -d 0
      

      在这里插入图片描述
      在这里插入图片描述
      按下"Ctrl + C",停止运行程序。
      在这里插入图片描述

      执行如下命令,控制两台伺服电机同时反转。

      Target#./igh_ethercat_dc_motor -d 1
      

      在这里插入图片描述
      按下"Ctrl + C",停止运行程序。

      在这里插入图片描述

      发布在 创龙科技专区
      zznzzn
      zznzzn
    • 【R128经验分享】启用USB ADB以及无线ADB配置方法

      首先在FreeRTOS的环境下,选择r128_c906_pro:

      source envsetup.sh
      lunch_rtos r128s2_pro_c906
      

      USB ADB的配置比较常规,注意以下几个驱动的勾选

      • usb device驱动
      • adb gadget驱动
      • adbd应用

      运行menuconfig,选择对应的驱动以及软件包:

      mrtos_menuconfig
      

      配置好的图片如下图所示

      downloadFileByUrl (3).png

      downloadFileByUrl (1).png

      downloadFileByUrl (4).png

      当选上以上配置时,usb的adb功能已经可以正常使用了。无线adb还需要额外选上以下配置:

      配置是开启无线adb的配置。

      downloadFileByUrl (5).png

      无线adb的端口,默认为5555

      downloadFileByUrl (6).png

      当上面配置全部选上后,编译烧录即可使用无线adb调试功能。

      1、首先让笔记本与板子,都连上共一个wifi,使其处于局域网的状态。

      2、板子串口控制台运行

      ifconfig
      

      查看ip地址。

      3、笔记本首先使用

      ping 板子ip地址
      

      命令确认笔记本是否能连接上板子。

      4、运行

      adb connect 板子ip地址
      

      进行连接。

      downloadFileByUrl (7).png

      5、出现如上图的connect to 板子ip地址的字符,表示已经连接成功。
      6、接下来就可以运行adb的一些调试命令了。

      7、如果更换了无线adb的端口,比如说从5555改成了5556,那么在笔记本中连接adb的命令需要改成:

      adb connect 板子ip地址:5556
      

      相对于原来的命令多了“:5556”,原来的命令是自动省略端口“:5555”。

      发布在 A Series
      zznzzn
      zznzzn
    • 1 / 1