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

2019-08-03 13:30

kill( ) lseek( ) open( ) read( ) sbrk( )

settimeofday( ) stat( ) usleep( ) wait( ) write( )

6.5.5 文件系统

HAL提供支持UNIX风格的文件访问的机制。用户可以在硬件中任何可用的存储设备上建立文件系统。用户能够在基于HAL的文件系统中访问文件,可以使用 newlib C库中的文件I/O 函数,(例如, fopen( ), fclose( )和fread( ))或使用HAL系统库提供的UNIX风格的文件I/O。HAL提供如下的UNIX风格的函数来进行文件的处理: close( ) fstat( ) ioctl( ) isatty( ) lseek( ) open( ) read( ) stat( ) write( )

HAL将一个子文件系统注册为HAL文件系统的一个挂载点(mount point)。要访问一个 挂载点下的文件,则指向该挂载点对应的文件子系统。例如,如果一个只读zip文件子系统(zipfs)被挂载为/mount/zipfs0,zipfs文 件子系统处理对/mount/zipfs0/myfile 进行fopen( )的调 用。

这里没有当前目录的概念,软件访问文件时必须使用绝对路径。HAL文件结构允许用户 通过UNIX风格的路径名来管理字符型的设备。HAL将字符型设备注册为HAL文件系统中的节点。按照约定,system.h中定义设备节点的名字按照 前缀 /dev/加上SOPC Builder中分配给硬件的名字,例如,在system.h 文件中,SOPC Builder中的UART外设uart1的节点名为/dev/uart1。

下面的代码给出了从只读zip文件子系统——ozipfs读字符的操作,这个文件子系统被注 册为HAL文件系统中的一个节点。头文件stdio.hstddef.h和stdlib.h同HAL一起被包含。从文件子系统读字符的例子 #include #include #include #define BUF_SIZE (10)

int main(void) {

FILE* fp;

char buffer[BUF_SIZE];

fp = fopen (“/mount/rozipfs/test”, “r”); if (fp == NULL) {

printf (“Cannot open file.\\n”); exit (1); }

fread (buffer, BUF_SIZE, 1, fp); fclose (fp); return 0; }

6.5.6 使用字符型设备

字符型设备串行地发送和接收字符。常见的如通用异步收发器(UART)。字符型设备在 HAL系统库中注册为节点。通常,程序将一个文件描述符同设备名联系起来,则使用在file.h 中定义的ANSI C文件操作对文件进行读写字符。HAL也支持标准输入、标准输出和标准错误的概念,允许程序调用stdio.h I/O函数。标准输入(Standard Input)、标准输出(Standard Output)和标准错误(Standard Error)使用标准输入(stdin)、 标准输出(stdout)和标准错误(stderr)是实现简单控制台I/O最容易的方法。HAL系统库在后台管理stdin、stdout和 stderr,允许用户通过这些通道发送和接收字符,而不是管理文件描述符。例如,系统库将printf()的输出指向标准输出,将perror() 指向标准错误设备。用户可以通过在系统库属性中的设置将每一个通道同一个特定的硬件设备联系起来。 下面的代码显示的是经典的Hello World程序,该程序发送字符到与stdout相关联的设备。 例子: Hello World #include int main () {

printf (“Hello world!”); return 0; }

当使用UNIX风格的API,用户可以使用在unistd.h中定义的文件描述符stdin、stdout和stderr来分别访问标准输入、标准输出和 标准错误的字符I/O流。unistd.h is 在Nios II EDS中作为newlib C库的一部分安装。 对字符型设备的通用访问

访问字符型设备 (除了stdin, stdout, or stderr方法),就像打开和写一个文件一样简单。下 面的代码演示的写一条信息到名为uart1的UART设备。 例子:写字符到UART

#include #include int main (void) {

char* msg = “hello world”; FILE* fp;

fp = fopen (“/dev/uart1”, “w”); if (fp!=NULL) {

fprintf(fp, “%s”,msg); fclose (fp); }

return 0; }

6.5.7 使用文件子系统

HAL的文件子系统通用设备模型允许使用C标准库的文件I/O函数访问存储在存储设备中的数据。例如,Altera的zip只读文件子系统提供对存储在 flash存储器中的文件子系统的只读访问。一个文件按子系统负责管理一个挂载点下面的所有的文件I/O访问。例如,一个文件子系统注册为挂载点 /mnt/rozipfs ,该目录下的所有的文件访问,如

fopen(“/mnt/rozipfs/myfile”, “r”),定向为该文件子系统。如同字符型设备,用户可以在file.h

中定义的使用C文件I/O函数处理文件子系统中的文件。如,fopen()和fread()。 6.5.8 使用定时器设备

定时器设备是可以计数时钟的硬件设备,并可以产生周期性的中断请求。用户可以使用定时器设备提供一些和时间相关的设备,如HAL系统时钟、报警器、和时间 测量。使用定时器设备,Nios II处理器系统在硬件上必须包含一个定时器外设。HAL API提供两种定时器设备的驱动程序:

系统时钟驱动——这种驱动支持报警(alarms),用户在调度程序会用到。

时间标记驱动程序——该驱动程序支持高精度的时间测量。 一个单独的定时器外设可以作为一个系统时钟或是时间标记,但是不能兼顾。HAL特定 的访问定时器设备的API函数在sys/alt_alarm.h和

sys/alt_timestamp.h中定义。.系统时钟驱动程序HAL系统时钟的驱 动程序提供周期的 “心跳节拍”(“heartbeat”),使得系统时钟按照每 一个节拍进行递增。软件可以使用系统时钟设备来在指定的时间执行函数,并且可以获得时序信息。用户通过在Nios II IDE的系统库属性中设置来选择指定的定时器外设作为系统时钟设备。

HAL提供如下的标准的UNIX函数的实现:gettimeofday()、settimeofday()和times()。这些函数返回的时间是基于 HAL系统时钟的。系统库时钟测量时间是以“ticks”为单位的。对于要和软件、硬件都打交道的嵌入式工程师,不要将HAL系统时钟和驱动Nios II 处理器的时钟信号混淆。HAL

系统时钟的滴答”ticks”是要远大于硬件系统时钟的。system.h d定义了时钟的频率。运行时,用户可以调用alt_nticks()函数来获得系统时钟的当前值。该函数返回自从系统复位之后经历的时间。用户能获得系统 时钟速率,通过调用函数alt_ticks_per_second()。HAL定时器驱动程序在创建系统时钟的实例时初始化其频率。标准的UNIX函数 gettimeofday()可以获得当前的时间。用户必须首先通过调用settimeofday()函数来校正时间。而且,用户可以使用times() 函数来或的已经发生的滴答数目信息。这些函数的原型在times.h中。 报警(Alarm)

用户可以注册在指定的时刻执行的函数使用HAL alarm工具。软件程序注册一个报警通过调用函数alt_alarm_start(): int alt_alarm_start (alt_alarm* alarm, alt_u32 nticks,

alt_u32 (*callback) (void* context), void* context);

在经过了n个ticks之后函数callback调用。当调用发生时,输入参数context作为输入变量传递给callback。 alt_alarm_start()初始化输入变量alarm所指向的结构。用户不必去初始化它。 callback函数能够复位alarm。注册的callback函数的返回值是直到下一个callback函数调用的tick的数目。返回值为0,表示 alarm应该停止。用户可以通过调用alt_alarm_stop()手动取消一 个alarm。Alarm的callback函数是在中断的语境(context)中执行的,这强加了函数的限制,用户必须观察何时写alarm callback。 下面的代码片段演示了为周期为1秒的callback注册一个alarm。 例:使用周期的Alarm Callback函数 #include #include

#include “sys/alt_alarm.h” #include “alt_types.h” /*

* The callback function. */

alt_u32 my_alarm_callback (void* context) {

/* This function will be called once/second */ return alt_ticks_per_second(); } ...

/* The alt_alarm must persist for the duration of the alarm. */ static alt_alarm alarm; ...

if (alt_alarm_start (&alarm, alt_ticks_per_second(), my_alarm_callback,

NULL) < 0) {

printf (“No system clock available\\n”); }

时间标记(timestamp)驱动程序 有些时候,用户想测量时间间隔,精度要求比HAL系统时钟提供的要高。HAL使用时 间标记驱动程序提供高分辨率的定时函数。时间标记驱动函数提供单调的增加的计数器,用 户可以采样来获得定时信息。在系统中,HAL只支持一个定时标记驱动程序。用户可以通过在Nios II IDE中通过设置系统库的属性来选择一个指定的硬件定时器外设作为时间标记设备。

如果有时间标记驱动程序,函数alt_timestamp_start()和

alt_timestamp()可用。Altera提供的时间标记驱动程序使 用用户在系统库属性中选择的定时器。调用函数alt_timestamp_start() 启动计数器,接下来调用alt_timestamp(),则返回时间标记计数器的当前值。再次调用

alt_timestamp_start()则复位计数 器为0。当计数器的值达到232– 1时,时间标记驱动的行为没有定义。调用函数alt_timestamp_freq(),用户可以获得时间标记计数器增加的速率。该速率典型值为Nios II处理器运行的硬件频率,通常是每秒钟几百万次。时间标记驱动程序在alt_timestamp.h头文件中定义。 下面的代码片段展示的是使用时间标记设备来测量代码的执行时间。 例:使用时间标记来测量代码的执行时间 #include

#include “sys/alt_timestamp.h” #include “alt_types.h” int main (void) {

alt_u32 time1; alt_u32 time2; alt_u32 time3;

if (alt_timestamp_start() < 0) {

printf (“No timestamp device available\\n”); } else {

time1 = alt_timestamp();

func1(); /* first function to monitor */ time2 = alt_timestamp();

func2(); /* second function to monitor */ time3 = alt_timestamp();

printf (“time in func1 = %u ticks\\n”, (unsigned int) (time2 – time1));


第6章 软件设计流程和方法 SOPC技术与应用(7).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:煤矿六大系统之人员定位系统

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: