Nios II的设备驱动:支持下面的设备
把status寄存器内容复制到estatus寄存器中,保存当前处理器状态;
清除status寄存器的PIE位为0,禁止所有的硬件中断;
把异常返回地址写入ea寄存器(r29);
跳转到异常处理地址。如果是内部中断,则跳转向异常地址;如果是外部中断则跳转向设备特定的中断地址。
int alt_ic_isr_register(alt_u32 ic_id,alt_u32 irq,alt_ist_func isr,void *isr_context,void *flags);//注册中断服务程序(现在版本的)
int alt_ic_irq_enable(alt_u32 ic_id,alt_u32 irq);//使能单个中断
int alt_ic_irq_disable(alt_u32 ic_id,alt_u32 irq);//禁止单个中断
alt_irq_disable_all(void);//禁止所有中断
alt_irq_enable_all(alt_irq_context context)//使能所有中断
alt_irq_cpu_enable_interrupts();//允许嵌套
alt_u32 alt_ic__irq_enabled(alt_u32 ic_id , alt_u32 irq);//检测中断的状态
alt_irq_enable(void)//检测中断的状态
alt_irq_pending() //返回当前挂起的中断
//老版本的,现在也可以使用,可以在alt_legacy_irq.h中查看
int alt_irq_register(alt_u32 id,void* context,alt_isr_func handler);//注册中断服务成簇
alt_irq_enable(alt_u32 id)//使能单个中断
alt_irq_disable(alt_u32 id)//禁止单个中断
alt_irq_interruptible(alt_u32 priorty)//允许嵌套,允许中断子程序中调用优先级高的中断来打破优先级低的中断
alt_irq_non_interruptible(alt_u32 mask)//禁止嵌套
void isr_name(void *context,alt_u32 id)
函数原型编写ISR(中断服务程序)。isr_name
为用户给ISR取得函数名;void *context
是指向传递给ISR的信息(通常是寄存器信息)的全局变量的指针;id是硬件中断号,在system.h中声明,比如KEY_IRQ 2;alt_irq_register(alt_u32 id,void * context,alt_isr_func handler)
,以向HAL层传递中断服务程序的信息。id是硬件中断号;void *context是指向传递给ISR的信息(通常是寄存器信息)的全局变量的指针;void ( *isr)(vodi *,alt_u32)是指向ISR的函数指针。alt_irq_register()会调用alt_irq_enable()来使能注册的中断。注意事项:
尽量保持中断服务程序精简(精简就是快速和可靠);
把无关紧要的事情放在中断服务程序之外处理;
尽量避免调用C库函数(如print(),因为可能引起阻塞且运行的时间无法预知);
尽力避免进行浮点操作。
调试中断服务程序的经验
函数升级:
根据英文介绍说,大部分情况下新旧函数都可以使用,但是有一种情况只能使用新的版本,那就是使用外部中断控制器的时候
否则会报错:undefined reference to alt_irq_register
alt_irq_register(PIO_KEY_IRQ,NULL,KeyDown_interrupts)中PIO_KEY_IRO
代表中断号,NULL上下文,可以给中断子程序KeyDown_interrupts传入中断的信息(一般默认null)。新的版本int alt_ic_isr_register(alt_u32 ic_id,alt_u32 irq,alt_ist_func isr,void *isr_context,void *flags)
;//注册中断服务程序(现在版本的),其中ic_id为菊花链中的ic,即外部中断的ID号可以在system.h文件中查看,后面的三个参数和旧的一样的意思,最后一个标志位 *flags一般默认为null,即int alt_ic_isr_register(外部中断号,硬件中断号,中断子程序,上下文,标志位)
什么是Bootloader?
即代码的搬运,程序的运行需要从flash中搬运代码到片上的rom或者ram中,这就需要到Bootloader。如果存在,那么Bootloader就是系统加电启动后运行的第一段代码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oHYTFpay-1667782851737)(https://gitee.com/xzs520xzs/figure_of_typora/raw/master/202211070549870.png)]
注释1:调用alt_load_section函数加载.rwdata,.exception,.rodata节点;调用alt_deche_flush_all函数和alt_icache_flush_all函数同步缓存
注释2:调用alt_irq_init函数初始化中断;调用alt_sys_init函数初始化添加的IP核
.bss(未初始化变量数据段):未初始化变量,比如全局变量定义之后,但未初始化的都放在这里;
.entry(异常处理地址):最终软件代码存储区,程序从此处开始启动
.exceptions(异常处理地址):系统异常处理代码存放的地方
.heap(堆):动态分配内存的存储区,从小地址向大地址方向增长;
.rodata(只读数据段):用于存放程序中的静态全局变量,所有赋了初值的全局变量都放在这里;
.rwdata(可读写数据段):用于存放程序中可读写变量和指针变量;
.stack(栈):函数调用变量与临时数据存储区(如返回地址,现场信息),从大地址方向增长;
.text(正文段,只读):代码执行区,也就是Nios II程序最终运行的地方;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-slydL06A-1667782851738)(https://gitee.com/xzs520xzs/figure_of_typora/raw/master/202211070530666.png)]
每一个Avalon接口的PIO内核可提供32个I/O内核可提供32个I/O端口且端口数量可以设置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K0mC4ukd-1667782851739)(https://gitee.com/xzs520xzs/figure_of_typora/raw/master/202211070831515.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xvJJ6AEV-1667782851739)(https://gitee.com/xzs520xzs/figure_of_typora/raw/master/202211070621306.png)]
--晓凡 2022年11月7日于桂林书