180 likes | 611 Views
FPGA 和 SOPC 应用 —— Nios2 进阶. 华中科技大学启明学院电工电子科技创新中心 王贞炎. 内容. 中断 DMA. 中断. Nios2 处理器有两种中断处理方式 Legacy 方式 由处理器直接处理中断,所有的中断由同一个中断信号送入处理器,处理器在软件中读取中断标志,并根据中断向量作跳转。使用简单,但中断效率低。 VIC 方式 由 VIC (Vectored Interrupt Control ,硬件外设 ) 判断中断标志,并处理中断向量给处理器。效率很高。 VIC 支持中断嵌套和可变优先级 这里只讲解 VIC 方式. 中断.
E N D
FPGA和SOPC应用——Nios2进阶 华中科技大学启明学院电工电子科技创新中心 王贞炎
内容 • 中断 • DMA
中断 • Nios2处理器有两种中断处理方式 • Legacy方式由处理器直接处理中断,所有的中断由同一个中断信号送入处理器,处理器在软件中读取中断标志,并根据中断向量作跳转。使用简单,但中断效率低。 • VIC方式由VIC (Vectored Interrupt Control,硬件外设)判断中断标志,并处理中断向量给处理器。效率很高。 • VIC支持中断嵌套和可变优先级 • 这里只讲解VIC方式
中断 • 添加VIC时的设置 可处理的中断源数量,单个VIC可处理的中断源最多32个 RIL,动态中断优先级的位数 是否支持链状级联,当需要多于32个中断时,可以用多个VIC级联
中断 • 处理器核中关于VIC的设置 使用外部中断控制器 “影子”寄存器组的个数。中断到来时,可为不同的中断分配不同的处理器工作寄存器组,进中断时无需保存现场,提高效率
中断 • VIC的连接 csr_access,vic的控制寄存器,应连接至处理器核的数据主端口 中断源输入,连接中断源,在连接点上可设置中断优先级,数值越小优先级越高 dummy_master,应连接至程序运行空间所在的ram interrupt_controller_out,连接至处理器核的interrupt_controller_in
中断 • VIC中断程序的编写 • NiosII的中断程序的注册和编写,由底层API函数控制,几乎无需了解硬件,相关函数有: • alt_ic_isr_register(),为中断源注册中断服务函数 • alt_ic_irq_enable(),使能某个中断源 • alt_ic_irq_disable(),禁能某个中断源 • alt_ic_irq_enabled(),判断某个中断源是否使能 • alt_vic_irq_set_level(),为中断源分配中断优先级 • …… • 强烈建议阅读以下内容: • Quartus II Handbook 第5卷第29章,讲述VIC的原理 • Nios II Software Developer’s Handbook 第14章(API参考)中关于中断的函数的部分,讲述函数的使用
中断 • VIC中断优先级和寄存器组 • 默认优先级 • VIC链中,靠近处理器核的VIC连接的中断源具有高优先级 • 同一VIC中,中断号小的中断源具有较高优先级 • 动态优先级 • 采用alt_vic_irq_set_level()分配RIL(requested interrupt level),分配的数值越大,优先级越高,默认优先级最高的中断源的默认RIL值为2RIL_WIDTH-1,然后依次递减 • 一般只建议设置RIL为0(禁能)或默认RIL值,动态更改为其它值,可能会导致问题 • 寄存器组 • 默认优先级最高的中断源独享编号最大的寄存器组,默认优先级次高的中断源独享编号次大的寄存器组 • 依次类推,直至寄存器组用完,剩余的中断源公用1号寄存器组
中断 • 实例 • 采用定时器作上一讲跑马灯程序中的延迟 • 关于定时器,参考Quartus II Handbook 第5卷第26章 和Nios II Software Developer’s Handbook 第6章中Using Timer Devices节
DMA • DMA(Direct Memory Access) • DMA是高性能处理器中必不可少的组件 • 有了DMA,可有由CPU发起(通过DMA的控制寄存器或位于存储器中的相关描述符)从Memory到外设的批量数据传输,传输过程由DMA控制器控制,不占用CPU运行时间,在数据传输完成时,DMA控制器可提出中断请求,通知CPU • 在Nios处理器中,包含两种主要的DMA控制器 • 普通DMA可完成存储器和MM(Memory Map)外设,存储器和存储器间的数据传输 • SGDMA(Scatter-Gather DMA)除具有普通DMA的功能外,还可完成存储器和ST(Stream)外设间的数据传输 • 这里只简要讲解SGDMA的用法。关于两者的详细信息,参考Quartus II Handbook和Nios II Software Developer’s Handbook中的相关章节
DMA • SGDMA
DMA • SGDMA • 一个SGDMA包含以下接口 • 控制接口MM Slave • 用于读写描述符的MM Master • 对于MM-MM配置,还包含 • 读写源Memory的MM Master • 读写目的Memory的MM Master • 对于MM-ST配置,还包含 • 读源Memory的MM Master • 向ST发送数据的ST Source • 对于ST-MM配置,还包含 • 从ST接收数据的ST Sink • 写目的Memory的MM Master
DMA • SGDMA描述符 • 描述符是一个位于存储器中的结构(C语言描述) • 描述符构成一个链表,连续的描述符可以让SGDMA不间断地一个个处理 typedefstruct { alt_u32 *read_addr; alt_u32 read_addr_pad; alt_u32 *write_addr; alt_u32 write_addr_pad; alt_u32 *next; alt_u32 next_pad; alt_u16 bytes_to_transfer; alt_u8 read_burst; /* Reserved field. Set to 0. */ alt_u8 write_burst;/* Reserved field. Set to 0. */ alt_u16 actual_bytes_transferred; alt_u8 status; alt_u8 control; } alt_avalon_sgdma_packedalt_sgdma_descriptor;
DMA • SGDMA寄存器 • 参考QuartusII Handbook…
DMA • SGDMA API • alt_avalon_sgdma_do_async_transfer() • alt_avalon_sgdma_do_sync_transfer() • alt_avalon_sgdma_construct_mem_to_mem_desc() • alt_avalon_sgdma_construct_stream_to_mem_desc() • alt_avalon_sgdma_construct_mem_to_stream_desc() • alt_avalon_sgdma_check_descriptor_status() • alt_avalon_sgdma_start() • alt_avalon_sgdma_do_async_transfer() • alt_avalon_sgdma_do_sync_transfer() • alt_avalon_sgdma_stop() • alt_avalon_sgdma_do_async_transfer() • alt_avalon_sgdma_do_sync_transfer() • alt_avalon_sgdma_open() • 参考QuartusII Handbook…
DMA • SGDMA程序示例 static void Dma_ISR(void *pContext){ //… } int main(){ //… pDma = alt_avalon_sgdma_open(SGDMA_NAME); // 打开SGDMA alt_avalon_sgdma_register_callback( // 注册中断服务函数 pDma, pDma_ISR, ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK, NULL); pDmaDescrs = (alt_sgdma_descriptor*)malloc(2 * sizeof(alt_sgdma_descriptor)); // 分配描述符 alt_avalon_sgdma_construct_mem_to_stream_desc( // 创建描述符 pDmaDescrs, pDmaDescrs + 1, (alt_u32 *)X, 4096 * 4, 0, 1, 1, 0); alt_dcache_flush_all(); // 刷新缓冲区 control = IORD_ALTERA_AVALON_SGDMA_CONTROL(pDma->base); control |= ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK; IOWR_ALTERA_AVALON_SGDMA_CONTROL(pDma->base, control); alt_avalon_sgdma_do_async_transfer(pDma, pDmaDescrs); // 启动非阻塞传输 //… }
DMA • 示例 • 采用SGDMA和Clocked Video Out做VGA视频输出 • 关于Clocked Video Out,参考Altera官方网站上的相关文档