给NIOS II CPU添加一颗澎湃的心——sysclk的使用

给NIOS II CPU添加一颗澎湃的心——系统时钟的使用

?

本实验介绍如何在Qsys中添加一个定时器作为NIOS II的心跳定时器,并在NIOS II中软件编程使用该定时器。

将上一个实验watchdog工程复制、粘贴并重命名为08_sysclk_timer。在Quartus II中打开该工程,然后点击Qsys快捷图标打开Qsys组件,如下图所示:

在Qsys中,打开工程目录(08_sysclk_timer)下的mysystem.qsys工程。

打开后,在左侧的IP列表中输入"timer",然后双击Interval Timer打开参数配置界面:

?

设置Period 为20,单位(Units)为ms,勾选上Fixed period。其他保持不变,点击finish,则Timer被加入到了我们之前的已有的系统中。

?

修改timer的名字为sys_clk按照上一节看门狗的连线内容将所有信号连接到对应总线上。

添加的过程中下面信息栏会有报错,暂时不用理会,等我们后面的操作完成后,报错会自动消失。

然后在菜单栏中点击【System】->【Assign Base Addresses】自动分配基地址。如下图所示:

这个时候,应该所有错误都消失了。接着我们在菜单栏中点击【Generate】->【Generate HDL】来生成Quartus II软件可用的设计文件,如下图所示:

生成完成之后,我们点击finish即可关闭Qsys系统,同时Quartus II软件弹出提示对话框,点击OK以关闭。

因为本实验中我们依然没有添加需要引出到外部引脚的IP,引出在Quartus II中对系统的例化文件不需要进行任何修改,直接点击"Start Compilation"(或者使用Ctrl + L组合键)对工程进行全编译即可。

?

打开NIOS II IDE开发软件。创建NIOS II软件工程和板级支持包工程,选择sopcinfo文件为"E:\easy_sopc\NiosOnlyExp\08_sysclk_timer\mysystem.sopcinfo"(自己根据具体路径修改,注意切换路径)。创建工程名字为sys_clk_test,选择Hello World模版工程,然后点击Finish。如下图所示:

?

选中bsp工程(sys_clk_test_bsp),进入BSP Editor。

  1. 设置sys_clk_timer为"sys_clk",
  2. 设置timestamp_timer为none,
  3. 设置stdin、stdout、stderr、为uart_0。

其他不变,点击generate,然后点击exit退出。

?

复制上一个工程中软件工程中的【hardware】文件夹到本工程下的【sys_clk_test】文件夹下,最好直接在电脑的文件管理器中进行(对Eclipse使用非常熟练的,请尽情使用拖拽添加的方式)。复制完成后,选中【sys_clk_test】工程,单击右键,选择【Refresh】,就可以在工程中看到【hardware】文件夹了。

接着我们添加【hardware】下的【inc】路径到工程头文件包含路径中来。我们选中【sys_clk_test】工程,按下键盘组合键"ATRL + Enter"键打开【Properties】设置界面,选择Nios II Application Properties下的Nios II Application Paths,在右侧的Application include directories下,点击Add按钮,添加hardware/inc到包含路径中。然后在弹出的对话框中点击Yes,即可将此路径添加为我们的头文件包含路径。如果用户之后自己有其他的头文件路径需要添加,也是按照这种方法进行。

接着我们查看下Project References中是否勾选了sys_clk_test_bsp工程,如果没有勾选的话,当工程关闭了重新打开时,工程有可能会报各种无法理解的错误(当一个workspace中有多个应用工程时)。这里我们需要确认这个选项被勾选上了。

然后我们再在C/C++ General下的Indexer下,勾选按照下图中所示进行勾选。通过这样勾选后,一般工程不管怎么折腾,都不会出现xxxx ‘xxxx‘ could not be resolved的报错了。

?

我们可以选择将系统创建时默认的main函数所在文件hello_world.c文件改名为main.c,修改时只需要选中hello_world.c文件,单击右键,选择rename,然后改为main.c即可。

?

最后我们编写main文件函数如下所示:


/******************************************************************

* 文

名:main.c

* 功
能:利用系统时钟服务产生1s的周期性事件,并借此控制LED闪烁,

*

* 说
明:观察LED闪烁效果。

******************************************************************/

#include <stdio.h>

#include "system.h" //包含基本的硬件描述信息

#include "led.h"

#include "sys/alt_alarm.h" //系统时钟服务头文件

#include "altera_avalon_pio_regs.h" //包含基本的IO寄存器信息

#include "alt_types.h" //Altera定义的数据类型

?

?

static alt_alarm alarm;
//按调用API函数规定定义的变量

?

alt_u8 led_data;

?

LED_HANDLE hLED;

?

/******************************************************************

* 名
称:my_alarm_callback

* 功
能:按调用规定系统时钟回调函数,在该函数中实现用户功能

* 入口参数:context,系统传给回调函数的参数

* 出口参数:返回下一次的系统时钟服务的周期值

******************************************************************/

alt_u32 my_alarm_callback(void* context)
{

if
(led_data ==
0x0f)
{

led_data =
0x00;

}
else
{

led_data =
0x0f;

}

LED_WriteData(hLED, led_data);
//一次性控制所有LED的亮灭

return alt_ticks_per_second();

}

?

int main()
{

//初始化LED

hLED = LED_Init(PIO_LED_BASE);

?

if
(!hLED)
{

// printf("Failed to init LED\n");

}

?

//熄灭所有LED

LED_Off(hLED, LED0 | LED1 | LED2 | LED3);

?

printf("test alarm...\n");
//打印提示信息

printf("alt_ticks_per_second() is %ld", alt_ticks_per_second());

?

//启动系统时钟服务

if
(alt_alarm_start(&alarm, alt_ticks_per_second()

, my_alarm_callback,
NULL)
<
0)
{

printf("No system clock available\n");

}

while
(1)

;
//等待时钟事件发生

return
0;

}

这样我们的软件就编写完成了,接着我们点击键盘的组合键"CTRL + B"(或者依次点击【Project】【Build All】)来编译整个工程。

接着我们在Quartus II中打开配置下载窗口将sof文件下载到FPGA中,然后在Eclipse中点击【Run】->【Run Configuration】,在弹出的界面中,双击左侧的【Nios II Hardware】新建一个下载设置,将name更改为sys_clk_test,与工程名保持一致。右侧Project Name选择sys_clk_test,如下图所示:

运行后在芯航线FPGA开发板上可以看到,4个LED每隔1秒闪烁一次。

?

补充阅读:

不常用操作系统的工程师很少碰到alarm这个概念,在他们心目中 alarm实质上就是一个简单的定时器周期中断事件。在操作系统中,alarm却是一个常用的概念,比如,当一个进程需要等待某个事件发生又不想永远等待下去时.该进程会设置一个超时(timeout)值。当这个超时值到达时,操作系统会向进程发送一个alarm(警告信号),提醒进程不要再等待。在Nios II中,alarm也可以同样理解为是打断正在执行的流程,提醒系统不要等待的信号。

?

如何初始化系统时钟服务?按照一般思路,先初始化定时器,再编写定时器中断服务程序。但是,在HAL层上进行应用程序开发不必如此,因为与硬件细节相关的初始化过程都由系统替用户完成了。用户在使用某项服务前,只需要开启该项服务即可。

?

使用HAL提供的系统时钟服务大致分为3个步骤:

  1. 调用alt_alarm_start()开启系统时钟服务,该函数位于BSP工程下的HAL\src 文件夹下的 alt_alarm_start. c 中。
  2. 按照格式要求编写回调函数。该回调函数将实现用户的功能。
  3. 调用alt_alarm_stop()关闭系统时钟服务。该函数位于BSP工程下的HAL\src 文件夹下的 alt_tick. c中。

通过接口函数访问定时器对象中的变量,为了达到隐藏信息的目的,Altera公司提 供了一个接口函数alt_ticks_per_second()供用户获得一个设定alarm服务周期为1 s的变量值。

系统时钟服务API函数分析:

????开启系统时钟服务函数:alt_alarm__start()

函数原型:


int alt_alarm_start (

alt_alarm * alarm,

alt_u32 nticks,

alt_u32 (* callback)
(void* context),

void* context)

函数功能:启动系统时钟服务。

输入参数:

alarm——一个指向alt_alarm结构体类型的指针变量,用户需要为每个系统时钟服务创建一个alt_alarm类型变量。系统由该变量对系统时钟服务进行维护。例如,用户需要两个系统时钟服务,则需要定义alt_alarm alarm_1和alt_alarm alarm_2。

nticks——指示每隔nticks执行一次回调函数。如果定时器预设的中断周期 为1 ms,则每个tick的时间间隔为1 ms。如果用户希望获得1 s—次的服务, 则nticks的输人值为1 s/1 ms=1000。

Callback——用户回调函数指针。

Context—-传给回调函数的参数,一般为寄存器的地址,也可以是其它参数。 如果不需要传递参数则此处填入NULL。

②????用户回调函数:my_alarm_callback()

函数原型:


alt_u32 my_alarm_callback (void
* context)

输人参数:

context —— alt_alarm_start()函数传人的参数,函数名可以自己定义,但是函数原型一定要按上述格式书写。

注意:不要在回调函数中实现复杂的功能,因为回调函数实际是定时器中断服务函数的

一部分。

③停止系统时钟服务函数alt_alarm_stop()

函数原型:


void alt_alarm_stop ( alt_alarm * alarm )

输入参数:

alarm—— —个指向ah_alarm结构体类型的指针变量,用户希望停止哪一个 系统时钟服务,即把该时钟服务对应的alarm变童传给alt_alarm_stop()。 至此,通过HAL API函数使用系统时钟服务的方法已总结完毕,其它API函数本文不再叙述,读者可参阅Altera公司提供的API函数手册。

最后留一个问题供读者思考,如何开启 3个系统时钟服务,使得3个LED分别以2 Hz、l Hz和0.5 Hz的频率闪烁?

?

如有更多问题,欢迎加入芯航线 FPGA 技术支持群交流学习:472607506

小梅哥

芯航线电子工作室

时间: 2024-10-10 09:32:28

给NIOS II CPU添加一颗澎湃的心——sysclk的使用的相关文章

给NIOS II CPU增加看门狗定时器并使用

给NIOS II CPU增加看门狗定时器并使用 ? 配置看门狗定时器: 设置计时溢出时间为1秒 计数器位宽为32位 勾选No Start/Stop control bits 勾选Fixed period 不勾选Readable snapshot 勾选System reset on timeout.(Watchdog) 不勾选Timeout Pulse (1 clock wide) 这部分配置可以参见"Embedded Peripheral IP User Guide.pdf"中Inte

NIOS II CPU复位异常的原因及解决方案

NIOS II CPU复位异常的原因及解决方案 ? 近期在用nios ii做项目时,发现一个奇怪的现象,在NIOS II EDS软件中编写好的代码,烧写到芯片中,第一次能够正常运行,但是当我按下板卡上的复位键之后,系统却卡死了,再也运行不起来,除非重新下载程序.经过分析系统可知,系统的硬件设计和Qsys系统中NIOS II CPU系统的搭建都是没有任何问题的.那么为什么会存在这样的问题呢,这里我先简单介绍下我的系统: 我的系统主要由NIOS II最强板CPU,SDRAM.预留系统定时器.预留时间

【小梅哥SOPC学习笔记】切换NIOS II CPU的主内存后软件中需要注意的几点设置

切换NIOS II CPU的主内存后软件中需要注意的几点设置 有时候,我们可能面对这样一种情况: 1. 我们创建一个SOPC系统,并在QSYS中设置NIOS II的复位地址和异常地址都指向SRAM: 2. 我们创建了正确的NIOS II软件工程并能够正常运行 3. 由于某种需求(如SRAM内存不够用了,需要换成内存更大的SDRAM),我们在面在QSYS中将NIOS II CPU的复位地址和异常地址修改为SDRAM 4. 我们需要继续使用之前创建的NIOS II软件工程. 这里,如果我们更改后直接

NIOS II 例程之Hello CS

1 新建工程 在quartus ii 中新建一个工程(hello.Prj) 2 Qsys硬件系统搭建 在quartus ii中开启Qsys: 打开Qsys界面发现System Contents下已经有了一个clk_0,如下图所示.为搭建一个最小系统还必须添加一些必要组件,比如NIOS II 处理器.JTAG.onchip_ram.systemID等. 添加JTAG: 添加NIOS II 处理器 添加onchip_ram 添加pio 添加system ID 在system contents 的co

nios ii boot过程

目录 1       概述....................................................................... 1 2       几种常见的boot方式......................................................... 1 2.1.................................................................................

关于NIOS ii烧写的几种方式(转)

源:http://www.cnblogs.com/bingoo/p/3450850.html 1. 方法一:.sof和.elf全部保存在FPGA内,程序加载和运行也是在FPGA内部. 把FPGA的配置文件.sof通过JTAG方式下载(其实是在线运行)进入FPGA本身,此时在NIOS II的界面中,点击“RUN”—“Run As Hardware”可实现在线运行.此时在SOPC配置时,需要有片内mem_rom和mem_ram,程序的复位向量为mem_rom,偏移0x00:异常向量为mem_ram,

NIOS II开发备忘录

大概有一年没做NIOS II的开发了,回想上一次做NIOS II还是去年做毕业设计的时候.那时候做的是基于SOPC的频率特性测试仪,我大约花了2个月的时间,从无到有的学习了NIOS II开发.学习过NIOS II的都知道,如果没有人带着学,那么最开始的那一段时间一定是最痛苦的,因为几乎每走一步,总会遇到一堆错误.我当时上手的时候,SOPC Builder已经退出了历史舞台,取而代之的是全新的Qsys环境.虽然说是全新,也不过就是在原来的SOPC Builder上升级了一下,但是,升级后,所有的总

使用华邦的SPI FLASH作为EPCS时固化NIOS II软件报错及解决方案

Altera器件有EPCS系列配置器件,其实,这些配置器件就是我们平时通用的SPIFlash,据AlteraFAE描述:"EPCS器件也是选用某家公司的SPIFlash,只是中间经过Altera公司的严格测试,所以稳定性及耐用性都超过通用的SPIFlash".就本人看来,半导体的稳定性问题绝大部分都是由本身设计缺陷造成的,而成熟的制造工艺不会造成产品的不稳定:并且,现在Altera的器件在读入配置数据发生错误时,可以重新读取SPIFlash里面的数据,所以在工艺的稳定性以及设计的可靠性

Nios II(一)

Using cable "USB-Blaster [USB-0]", device 1, instance 0x00 Pausing target processor: not responding.Resetting and trying again: FAILEDLeaving target processor paused 网上总结三点原因致使这个问题的发生: 1.复位键的管脚没有对应好,导致报错: 2.给sdram的clk,与cpu的clk没有滞后-75的相位: 3.如果用锁相