资讯详情

DE1-SoC HPS CAN中断方式通信调试过程--WL

DE1-SoC HPS CAN通信(中断)调试

实验目的: 利用Altera Cyclone V SoPC HPS集成的CAN总线控制器采用中断法实现裸机下的裸机CAN收发报文数据。 实验环境: 硬件:DE1-SoC开发板, 软件:Quartus II 15.0和DS-5 18.1,Preloader,HPS裸机固件驱动库(18.1)。 实验流程: 1.硬件设计 2.软件设计 a. Preloader部分 b. HPS引导流程 c. CAN裸机中断收发程序流程 1. 主程序框架 2. 关键硬件资源的初始化 3. 实现中断收发服务函数和触发过程

1.硬件设计 HPS 中包含CAN 无需添加总线控制器 IP 核,只需从 HPS 中引出 CAN 的 tx、rx 引脚使其能够通过这两个引脚连接片的外部驱动电路和外部通信。

具体步骤: 在 Qsys 系统组件 HPS 设置参数选项标签页 CAN 的外设引脚 注:CAN pin选择FPGA ,因为 HPS I/O Set 外部无法连接 CAN 通信的引脚 引出双击红色区域 CAN 的引脚 用 verilog 端口声明: 综合分析后, Pin Planner 上述声明将在上述声明中看到。 CAN 端口 双击 Location引脚分配: 从板上分配2个40个引脚pin GPIO随意选择,但需要注意的是,因为 CAN 通信输入差分信号 CAN 所以在总线上选择引脚复用时要选择 DIFFIO_RX DIFFIO_TX 电路连接如下: 需要注意的是,由于需要添加电平转换器,因此需要添加电平转换器 TTL 电平标准和 CAN 的电平标准不同。 最成的最终编译.sof文件经由USB-Blaster下载到开发板。 3.软件设计

硬件设计已经完成,但是HPS 不知道配置信息,软件程序运行环境没有准备好,裸机程序需要加载,所以需要准备一份完成软硬件交互的文件,即preloader部分。

a.Preloader部分 最终需要生成 u-boot-spl 二进制文件初始化相关硬件,引导加载裸机程序 那怎么得到呢?u-boot-spl ? 首先,我们需要知道配置 HPS 外设、管脚重用等信息 对此,可编译上述硬件设计,得到.sof文件(经由USB Blaster下载到板子里)和handoff文件夹,handoff文件夹中包含了这些信息 然后,经由 preloader 也就是生成器bsp(板级支持包) editor 将 handoff 文件夹中的信息转换成源代码, 另外生成 preloader 设置文件、 preloader 调试脚本和编译 preloader 所用的 makefile。 因此,我们得到了源文件,但它与我们最终想要的二进制文件不同,需要帮助 makefile进行编译。 Bsp editor支持多种型号板子的 preloader 生成配置信息 generated文件夹可以看到许多头文件和C语言文件,用于更新uboot系统配置主要涉及相关文件,IO复用,DDR初始化等 Makefile 实施以下步骤: 1.把 generated复制文件夹下的相应文件uboot-socfpga/board/altera/socfpga与下面sdram子目录 2.通过以下变量设置

PRELOADER_UPDATE_DIR := $(PRELOADER_SRC_DIR)/board/altera/socfpga SOCFPGA_BOARD_CONFIG := socfpga_$(DEVICE_FAMILY)_config DEVICE_FAMILY := cyclone5 

以及执行make $(board)_config 配置项目,确定具体在目标板上的子目录和头文件。生成配置文件config.h(知道取用U-Boot源代码中的相应文件是什么? 3.配置完成后,需要编译 spl 得到 u-boot-spl.bin uboot-socfpga顶层文件在目录下Makefile有以下句子

ALL-$(CONFIG_SPL)  = $(obj)spl/u-boot-spl.bin 

打开spl目录下的文件Makefile 在这里我们可以看到编译 spl 以下是需要使用的各种配置文件、汇编文件和链接器文件的一部分

LIBS-$(CONFIG_SPL_FRAMEWORK)  = common/spl/libspl.o LIBS-$(CONFIG_SPL_LIBCOMMON_SUPPORT)  = common/libcommon.o LIBS-$(CONFIG_SPL_LIBDISK_SUPPORT)  = disk/libdisk.o LIBS-$(CONFIG_SPL_I2C_SUPPORT)  = drivers/i2c/libi2c.o LIBS-$(CONFIG_SPL_GPIO_SUPPORT)  = drivers/gpio/libgpio.o LIBS-$(CONFIG_SPL_MMC_SUPPORT)  = drivers/mmc/libmmc.o LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-spl.lds 

链接文件决定了可执行程序各段的存储(加载)地址和运行(链接)地址。

b.HPS引导流程 上电 reset 后,位于 HPS 中的 ROM 运行包装的代码段Boot ROM Boot ROM代码的作用是确定所选代码boot重置后的源、初始化HPS,将 preloade 映像从 flash 加载到OCRAM然后跳转到 preloader 。 所选的 Flash 类型 SDMMC 在 bsp-editor spl boot 选项中设置 OCRAM 由地址 0xFFFF0000知 Preloader 在完成Clock Reconfiguration、初始化SDRAM接口、配置HPS I/O引脚及复用、初始化加载下一阶段程序的接口后,将裸机程序引导映像从引导设备复制到SDRAM。并执行 SDRAM 地址0x00100000–0xC0000000 c. CAN裸机中断收发程序流程 1. 主程序框架 初始化:1.通过协议组寄存器模块(如CCTRL寄存器、CBT寄存器等)进行软件初始化(如设置比特率,设置通信模式等) 2.通过IF接口寄存器初始化Message RAM中的接收邮箱和发送邮箱(分别初始化)。 消息对象结构:掩码位、仲裁位、控制位、数据位 通过IF接口寄存器配置消息对象的掩码位、仲裁位、控制位、数据位,存储到Message RAM对应邮箱中请求发送。 Message Handler(状态机)接收到了请求,处理消息对象发送。 邮箱中的消息对象通过IF寄存器传输到CAN core中的移位寄存器,经过封装然后到达CAN 总线接口,进行数据帧的传送。

中断相关: GIC–中断控制器连接所有能够产生中断的I/O外围设备的IRQ中断信号。CAN0 控制器有4个中断信号连接到全局中断控制器 (GIC), GIC 由分配器和 CPU 接口组成,分配器从I/O外设接收IRQ中断信号 CPU接口将分配器收到的IRQ请求发送给Cortex-A9处理器。 中断信号可以分为3种 1.SPI(shared peripheral interrupts):该中断由中断控制器可以路由到多个内核的外设生成.中断号32-211 2.PPI(private peripherals interrupts):专用于单个CPU .中断号27-30 3.SGI(software generated interrupts):由软件通过写入专用分配器寄存器生成.中断号0-15

中断过程: 当发生中断时,CAN0 控制器发送一个消息中断信号 ALT_INT_INTERRUPT_CAN0_MO_IRQ 给 GIC ,由分配器接收,然后CPU接口将中断请求发送给Cortex-A9处理器让处理器进行处理,进入到中断模式。 在程序中,跳转到中断向量表 irq 入口,通过跳转指令,跳转到中断服务函数。执行完中断服务函数后,回到原程序继续运行

2.关键硬件资源的初始化代码

进行 CAN 通信,先要对 CAN controller 初始化,其中包括比特率的设置,Message Ram的初始化以及接收邮箱和发送邮箱的初始化等

 /* Initialize the can controller*/
     alt_can_init( ALT_CAN_CAN0, candev);
    /*Initialize the can controller rx mailbox for many received messages */
    alt_can_mailbox_init(candev,0x1, 0x16,  0x5,ALT_CAN_TMOD_TX, ALT_CAN_FIFO_MODE_SINGLE_MSG);
    alt_can_mailbox_init(candev,0x2, 0x0101,  0x3,ALT_CAN_TMOD_RX, ALT_CAN_FIFO_MODE_SINGLE_MSG);
    alt_can_mailbox_init(candev,0x3, 0x0102,  0x3,ALT_CAN_TMOD_RX, ALT_CAN_FIFO_MODE_SINGLE_MSG);
    alt_can_mailbox_init(candev,0x4,0x0103,0x3,ALT_CAN_TMOD_RX, ALT_CAN_FIFO_MODE_SINGLE_MSG);

注:当接收多个报文/数据帧时,为避免数据错乱,需设置邮箱的ID 标识符以及掩码位

  1. 中断收发服务函数实现及触发流程

要以中断方式实现数据收发,需要配置 GIC(包括分配器和 CPU 接口),并配置 CAN 控制器使其能发送中断信号 配置 GIC

  ALT_STATUS_CODE status = ALT_E_SUCCESS;
     if (status == ALT_E_SUCCESS)
    { 
        
        status = alt_int_global_init();
    }

    if (status == ALT_E_SUCCESS)
    { 
        
        status = alt_int_cpu_init();
    }

    /* Setup the interrupt specific items */

    if (status == ALT_E_SUCCESS)
    { 
        
        status = alt_int_isr_register(ALT_INT_INTERRUPT_CAN0_MO_IRQ, can_int_callback,NULL);
    }

    if (status == ALT_E_SUCCESS)
       /* Ignore target_set() for non-SPI interrupts. */
    { 
        
        int target = 0x3; /* 1 = CPU0, 2=CPU1 */
        status = alt_int_dist_target_set(ALT_INT_INTERRUPT_CAN0_MO_IRQ, target);
    }

    if (status == ALT_E_SUCCESS)
       { 
        
        status = alt_int_dist_trigger_set(ALT_INT_INTERRUPT_CAN0_MO_IRQ,ALT_INT_TRIGGER_LEVEL);
       }
    /* Enable the distributor, CPU, and global interrupt */

    if (status == ALT_E_SUCCESS)
    { 
        
        status = alt_int_dist_enable(ALT_INT_INTERRUPT_CAN0_MO_IRQ);
    }

    if (status == ALT_E_SUCCESS)
    { 
        
        status = alt_int_cpu_enable();
    }

    if (status == ALT_E_SUCCESS)
    { 
        
        status = alt_int_global_enable();
    }

配置I/O外围设备 CAN 控制器,使其可以发送IRQ中断请求到GIC。

 /* Enable can0 interrupt//CCTRL.MIL */
    alt_can_int_enable(candev, 0xf);

设置消息对象接收中断。消息对象/邮箱的中断是在消息对象的控制位中设置的。设置成功后,一旦接收到报文,就触发中断

 /* Enable rx interrupt */
       ALT_CAN_MSG_IFMCTR_t ctrl0 = { 
        0};
       ctrl0.data_len=0x8;
       ctrl0.block_end=true;
       ctrl2.rx_int=true;
   alt_can_if_msg_ctrl_set( candev, ALT_CAN_INTERFACE_WRITE,&ctrl0);
 ALT_CAN_MSG_PARAM_t  msgparam1 = { 
        0};
	   msgparam1.control=true;
	   alt_can_message_put(candev, ALT_CAN_INTERFACE_WRITE, 0x2,&msgparam1);

触发中断后,跳转指令到中断服务函数 中断服务函数:实现点亮FPGA灯,以及将接收到的数据帧发送出去

void can_int_callback()
	{ 
        
  	  /* light the FPGA led */
	alt_write_word(0xff200000,0x1);}

然后通过读取寄存器 MOIPA 的值判断哪一个消息对象的中断标志位 Inpnd 置1,知道哪个邮箱触发中断

   /* send a message object which receive just now */

    ALT_CAN_MSG_PARAM_t  cmd_params0 = { 
        0};

	cmd_params0.arbitration=true;   
	cmd_params0.control=true;     
    cmd_params0.data_A=true;
    cmd_params0.data_B=true;       // true = transfer Data Bytes 0-3 to IFxDA.

  	 alt_can_message_get(candev,ALT_CAN_INTERFACE_READ, i, &cmd_params0);

  	 uint32_t a = alt_read_word(0xFFC00108);
  	 uint32_t b = alt_read_word(0xFFC00110);
   	uint32_t c = alt_read_word(0xFFC00114);
  	 uint32_t d = a & 0x1fffffff;
  	 arb_param0.direction=true;
  	 arb_param0.id=d;
  	 arb_param0.extended=false;
  	 arb_param0.valid=true;    //MsgVal bit

  	 alt_can_if_arb_set( candev,ALT_CAN_INTERFACE_WRITE, &arb_param0);

   	ALT_CAN_MSG_IFMCTR_t ctrl0 = { 
        0};
  	 ctrl0.data_len=0x8;
  	 ctrl0.block_end=true;
  	 alt_can_if_msg_ctrl_set( candev, ALT_CAN_INTERFACE_WRITE,&ctrl0);

   	/*Sends 8 data bytes to the CAN controller.IF register*/
 	  alt_can_if_data_set( candev, ALT_CAN_INTERFACE_WRITE, b, c);

    ALT_CAN_MSG_PARAM_t  msgparam = { 
        0};
    msgparam.data_B=true;          //true = transfer Data Bytes 0-3 to Message Object.
    msgparam.data_A=true;
    msgparam.tx_rqst_new_dat=true;   // true = set TxRqst and NewDat in Message Object to one
    msgparam.control=true;     //true = transfer Control Bits to Message Object.
    msgparam.arbitration=true;
    alt_can_message_put(candev, ALT_CAN_INTERFACE_WRITE, 0x1,&msgparam);

	 /* clear rx interrupt bit */
    ALT_CAN_MSG_IFMCTR_t ctrl2 = { 
        0};
    ctrl2.int_pending=false;
    ctrl2.data_len=0x8;
    ctrl2.block_end=true;
    ctrl2.rx_int=true;
    alt_can_if_msg_ctrl_set( candev, ALT_CAN_INTERFACE_WRITE,&ctrl2);
    ALT_CAN_MSG_PARAM_t  msgparam4 = { 
        0};
    msgparam4.control=true;
	  alt_can_message_put(candev,ALT_CAN_INTERFACE_WRITE,i,&msgparam4);

为了程序能正常运行而不是一直进入中断,要清除中断位,在对应邮箱/消息对象的 Intpnd 位置0即可。 程序设计完成后,经过编译、汇编、链接最终生成.axf二进制文件

实验结果:

每当USB-CAN Tool 发送一个消息对象,程序触发中断,进入中断服务函数,将接收到的消息对象再返回发送到USB-CAN Tool中,如下图所示。

标签: hps拉绳位稳传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台