【二】软核学习

数据类型

image-20221106144838750

Nios II的设备驱动:支持下面的设备

image-20221106145057016

异常处理过程

当中断产生后硬件怎么动作的(内部中断的,外部寄存器通过影子寄存器的切换来保护现场)

  • 把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)//禁止嵌套
    
    

image-20221106154107024

使用HAL API函数编写中断服务程序分两步:

  • 参照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(),因为可能引起阻塞且运行的时间无法预知);

  • 尽力避免进行浮点操作。

    调试中断服务程序的经验

    • 在中断服务程序内设置断点。当中断发生后,处理器会在断点处停下,用户可以单步调试中断服务程序,需要注意的是,在单步调试的过程中,硬件会被忽略其他中断。
    • 使用sprintf()函数把关键数据写到内存中,然后触发外部分析程序,在中断服务程序中,不可以调用print()函数,但是可以调用sprintf()。

函数升级:

image-20221107043955522

根据英文介绍说,大部分情况下新旧函数都可以使用,但是有一种情况只能使用新的版本,那就是使用外部中断控制器的时候

否则会报错: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(外部中断号,硬件中断号,中断子程序,上下文,标志位)

image-20221107050658158

Nios II用户程序上电自启动

什么是Bootloader?

即代码的搬运,程序的运行需要从flash中搬运代码到片上的rom或者ram中,这就需要到Bootloader。如果存在,那么Bootloader就是系统加电启动后运行的第一段代码。

image-20221107053241975

image-20221107053336590

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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核

image-20221107051457081

.bss(未初始化变量数据段):未初始化变量,比如全局变量定义之后,但未初始化的都放在这里;
.entry(异常处理地址):最终软件代码存储区,程序从此处开始启动
.exceptions(异常处理地址):系统异常处理代码存放的地方
.heap(堆):动态分配内存的存储区,从小地址向大地址方向增长;
.rodata(只读数据段):用于存放程序中的静态全局变量,所有赋了初值的全局变量都放在这里;
.rwdata(可读写数据段):用于存放程序中可读写变量和指针变量;
.stack(栈):函数调用变量与临时数据存储区(如返回地址,现场信息),从大地址方向增长;
.text(正文段,只读):代码执行区,也就是Nios II程序最终运行的地方;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-slydL06A-1667782851738)(https://gitee.com/xzs520xzs/figure_of_typora/raw/master/202211070530666.png)]

Qsys丰富多彩的内置IP核

image-20221107055821678

并行输入/输出(PIO)

image-20221107060420244

PIO寄存器描述

image-20221107060808622

image-20221107061840285

每一个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)]

PIO内核配置选项

image-20221107064002173

--晓凡 2022117日于桂林书
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值