77范文网 - 专业文章范例文档资料分享平台

第6章 软件设计流程和方法 SOPC技术与应用(10)

来源:网络收集 时间:2019-08-03 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

化 的完全控制。独立的环境下,初始化系统的任务由程序员手动完成。例如,在独立的环境下,对printf( ) 的调用不会正确工作,除非alt_main( )首先初始化字符型的设备,并且将stdout重定位到该设备。 基于HAL程序的启动顺序

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

HAL提供的系统的初始化代码按照如下的启动顺序: 刷新指令和数据缓存 配置堆栈指针

配置全局指针寄存器 将BSS段清零

如果系统没有boot loader,将任何运行地址在RAM中的连接器段拷贝到RAM,如读写 数据(.rwdata)、只读数据(rodata)和异常向量表。

调用alt_main( )。 HAL提供一个缺省的alt_main( )函数的实现,该函数执行如下的步骤:

调用ALT_OS_INIT( ) 执行任何必要的操作系统的初始化,如果系统不包含OS调度程 序,这个不起作用。

如果用户的HAL包含操作系统,初始化alt_fd_list_lock信号, 该信号控制对HAL文件系 统的访问。 初始化中断控制器,使能中断。

调用alt_sys_init( )函数,初始化系统中所有设备的驱动程序和软件组件,Nios II IDE为 每一个HAL系统库创建和管理alt_sys_init.c。 重定位C 标准I/O通道(stdin, stdout, and stderr),以使用适当的设备。

使用_do_ctors() 函数调用C++ 构造器。 注册C++ 解构器,以供系统关闭时调用。 调用main( )

调用exit( ) alt_main.c,同Nios II EDS一道安装,提供了缺省的实现,用户可以在

path>/components/altera_hal/HAL/src处找到。 定制启动顺序

通过在用户的Nios II IDE工程中定义alt_main( ),用户可以实现自己定制的启动顺序。 这给了用户对启动顺序完全的控制权。给了用户选择使能HAL服务的能力。如果用户的应用需要alt_main( ) 入口点,用户可以拷贝alt_main的缺省实现,在此基础上根据自己的需要进行修改。

alt_main( )函数调用main( )函数。当main( ) 返回后,缺省的alt_main( )进入一个死循环。 用户的定制alt_main( ) 可以通过调用exit( )而结束。 alt_main( )函数的原型是: alt_main (void)

在生成程序的时候,HAL的所有源文件和包含的文件都位于一个搜索路径。生成系统首 先搜索系统库工程的路径。这使得用户的实现会覆盖缺省的设备驱动和系统代码。例如,用 户可以提供自己的定制的alt_sys_init.c ,把它放到用户的系统工程目录中。 用户的定制文件优先于自动生成的文件。

第6节 异常处理

本节讨论在Nios II处理器体系结构下怎样编写处理异常的程序。 重点放在怎样使用HAL 注册用户定义的中断服务程序(Interrupt Service Routine——ISR)来处理硬件中断请求。

Nios II异常处理是以经典的RISC方式实现的, 即所有的异常类型都由一个异常处理程序 处理。所以,所有的异常(硬件和软件)由位于异常地址(exception address)的程序处理。 Nios II处理器提供如下的异常类型: 硬件中断

软件异常,分成如下三种: 未实现的指令 软件陷阱 其它的异常 6.6.1 异常处理概念

下面列出一些基本的异常处理的概念,还有和其相关的HAL术语:

? ? ? ? ? ? ?

Application context(应用语境)—— 在正常的程序执行过程中Nios II处理器和HAL的 状态,在异常处理程序之外。

ontext switch (语境切换)—— 发生异常时保存Nios II处理器寄存器的过程,在从中 断服务程序返回时进行恢复。

exception (异常)—— 任何的中断正常程序执行的条件或是信号。 exception handler (异常处理程序)—— 完整的软件程序的系统,服务所有的异常, 在必要的情况下将控制权交给ISR。

exception overhead(异常开销)—— 异常处理需要的附加的处理。一个程序的异常开 销是被所有的context switches占用的时间的总和。 hardware interrupt(硬件异常)—— 由硬件设备的信号引起的异常。 implementation-dependent instruction (和处理器实现相关的指令)—— 不被Nios II内核所有实现支持的Nios II处理器指令。例如mul和div指令就是和实现相关的,因为在 Nios II/e 内核中它们不被支持。 interrupt context (中断语境)—— 当异常处理程序执行时Nios II处理器和HAL的状 态。

interrupt request (IRQ:中断请求) —— 来自外设的请求硬件中断的信号。 interrupt service routine (ISR:中断服务程序)—— 处理一个单独的硬件中断的软件 程序。

invalid instruction(无效的指令)——在任何的Nios II处理器的实现中都没有定义的指 令。 software exception(软件异常) —— 由软件条件引起的异常。包括未实现的指令和陷阱指令。

? ? ? ? ?

?

unimplemented instruction(未实现的指令)—— 用户系统的特定的Nios II内核不支持的实现相关的指令。例如,Nios II/e内核中,mul和div是未实现的。

other exception(其它异常)—— 不是硬件中断或陷阱的异常。

?

6.6.2 硬件如何工作

Nios II处理器能够响应软件异常和硬件中断。可支持32个中断源。软件可以对这些中断 信号进行优先级的排序,虽然这些中断信号自身本质上没有优先级的区别。当Nios II处理器 响应一个异常时,做如下的工作: 1. 保存状态寄存器到estatus寄存器。这意味着如果硬件中断被使能了,estatus寄存 器的EPIE 位为有效。 2. 禁止硬件中断。

3. 保存下一个执行地址到ea (r29)寄存器。 4. 将控制权交到Nios II处理器异常地址。

Nios II的异常和中断没有采用中断向量表的处理,所以同一个异常地址接收所有种类的 中断和异常的控制。位于异常地址处的异常处理程序必须决定异常或中断的种类。 软件经常使用中断和外部设备进行通信,当外设发出中断请求IRQ时,会导致处理器的正常的执行出现一个异常。当这样的一个IRQ发生,一个相应的中断服务 程序——ISR必须处理该中断,并且处理完成之后,返回到处理器中断之前的状态。.当使用Nios II IDE创建系统库工程时,IDE包含了所有需要的ISR。用户不必去写HAL ISR,除非用户要和定制的外设通信。作为参考,本节介绍HAL系统库提供的处理硬件中断 程序的框架。用户参考已有的Altera SOPC Builder的组件的中断处理来获得编写HAL ISR的例子。

6.6.2.1HAL 的 ISR API

HAL系统库提供API 来帮助用户简化ISR的创建和维护。API也适用于基于实时操作系 统的程序,因为全部的HAL API对基于RTOS程序都是可用的。HAL API定义了如下的函数来管理硬件中断的处理: alt_irq_register() alt_irq_disable() alt_irq_enable()

alt_irq_disable_all() alt_irq_enable_all() alt_irq_interruptible() alt_irq_non_interruptible() alt_irq_enabled()

使用HAL API来实现ISR需要如下的步骤: 1. 编写处理特定设备中断的ISR。

2. 用户程序必须通过调用alt_irq_register()函数来注册ISR,调用alt_irq_enable_all()函数 来使能中断。

6.6.2.2 编写 ISR

用户编写的ISR必须符合alt_irq_register()函数的原型。 ISR函数的原型必须符合如下的形式:

void isr (void* context, alt_u32 id) context和id参数的定义是和alt_irq_register()函数是相同的。

从HAL异常处理系统的角度来看,ISR最重要的功能是清除相关的外设的中断条件。清除中断条件的步骤是和外设有关的。要获得详细的信息,参考 Quartus? II Handbook, Volume 5: Altera Embedded Peripherals. 当ISR完成中断服务之后,必须返回到HAL异常处理程序。当完成恢复应用程序的现场 之后,HAL异常处理程序发出eret。 受限的环境 ISR在一个受限的环境中运行,许多的HAL API调用是不可用的。例如,访问HAL文件 系统是不允许的。作为一个普遍的规则,当编写用户自己的ISR时,不要包括可能妨碍中断 等待的函数调用。Nios II Software Developer’s Handbook中的HAL API Reference 章节给出了那些在ISR中不可用的API函数。 当在ISR调用ANSI C 标准库函数时,一定要小心。要避免使用C 标准库中的I/O API, 因为调用这些函数会导致系统的死锁,即系统可能会永久地陷入ISR。 特别地,在ISR中不要调用printf(),除非能够确定stdout(标准输出)映射到一个非基于中断的设备驱动程序。否则,printf()可能使 系统死锁,一直等待一个不会发生的中断,因为中断已经被禁止了。

6.6.2.3 注册 ISR

在软件可以使用ISR之前,用户必须先注册该ISR,注册中断服务程序通过调用 alt_irq_register()。alt_irq_register()的原型为: int alt_irq_register (alt_u32 id, void* context,

void (*isr)(void*, alt_u32)); 函数原型具有如下的参数:

?

id 是设备的硬件中断号, 在system.h中定义。 中断优先级和IRQ号成反比, 中断号越低,优先级越高。因此,IRQ0 代表最高的优先级中断,而IRQ31 为最低优先级的中断。

context 是一个用来向ISR传递语境(context)相关信息的指针,可以指向任意ISR相关 的信息。 context的值对HAL是不透明的。 context完全是为了用户定义ISR方便而提供的。

isr 是响应IRQ id而被调用的函数指针。提供给该函数两个参数context指针和id。注册isr 为null指针,导致中断被禁止。

?

?

HAL注册ISR通过存储函数指针isr在一个查找表中。如果注册成功则alt_irq_register()返 回0值,如失败,则返回非零值。如果HAL注册用户注册ISR成功,在alt_irq_register()返回时, 相关的Nios II 中断则被使能。当特定的IRQ发生时,HAL在查找表中查找IRQ,然后指派注册的ISR。 6.6.2.4 使能和禁止 ISR

HAL提供函数alt_irq_disable()、alt_irq_enable()、

alt_irq_disable_all()、 alt_irq_enable_all()和alt_irq_enabled(),允许程序来禁止中断和重新使能中断。 alt_irq_disable()和alt_irq_enable() 运行用户禁止和使能单独的中断。alt_irq_disable_all()禁止所有的中断,并且返回一个context 值。要重新使能中断,调用 alt_irq_enable_all(),传递给函数context参数。这样,中断被返回到调用alt_irq_disable_all() 之前的状态。如果中断被使能,则alt_irq_enabled()返回非零值,程序能够检查中断的状态。禁止中断在尽可能短的时间里完成。中断的最大延 迟随着中断被禁止需要的时间量的增大而增大。

6.6.2.5 C语言例子

下面的代码为按键PIO中断服务程序的例子。本例是基于具有4位的PIO外设的Nios II系 统, 4位的PIO同按键相连。 IRQ当按键被按下即产生。 ISR代码读PIO外设的边沿捕获寄存器,将读到的值存储到一个全局变量。全局变量的地址通过context的指针传递给ISR。 例:按键PIO IRQ的ISR

#include \

#include \#include \

static void handle_button_interrupts(void* context, alt_u32 id) {

/* cast the context pointer to an integer pointer. */ volatile int* edge_capture_ptr = (volatile int*) context; /*

* Read the edge capture register on the button PIO. * Store value. */

*edge_capture_ptr =

IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE); /* Write to the edge capture register to reset it. */ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0); /* reset interrupt capability for the Button PIO. */ IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf); }

下面的代码显示的是在主程序中使用HAL注册ISR的例子。 例:使用HAL注册按键PIO ISR #include \

#include \...

/* Declare a global variable to hold the edge capture value. */ volatile int edge_capture; ...

/* Initialize the button_pio. */

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库第6章 软件设计流程和方法 SOPC技术与应用(10)在线全文阅读。

第6章 软件设计流程和方法 SOPC技术与应用(10).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/jiaoyu/676075.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: