阅读以下说明和C语言代码,回答问题1至问题3,将答案填入答题纸的对应栏内。
【说明】
计算机系统中以字节为单位存储信息,每个地址单元都对应着一个字节。但是在C程序中除了8bit的char型数据外,还有16bit的 short型、32bit的 int 型及 long型(要看具体的编译器)。另外,对于16位或者32位的处理器,由于寄存器宽度为多个字节,那么必然存在如何安排多个字节的问题,因此就导致了大端(Big-endian)存储模式和小端(Little-endian)存储模式。问题1是关于大端模式和小端模式方面的问题。
在C语言中,可以用指针变量指向整型变量、字符串、数组、结构变量,也可以指向一个函数,对指针的用法非常灵活,也很容易出错。其中,函数指针变量为较高级的用法。问题2是将函数指针变量应用于设备驱动程序中的问题。
飞腾FT2000-4国产处理器的QSPI(Quad Serial Peripheral Interface),是为外接SPI设备所提供的专用接口,问题3是用C语言编写的关于QSPI 设备驱动的部分操作的问题。
【问题1】(4分)
对于一个32bit 的十六进制整数0x12345678,在Little-endian模式以及 Big-endian模式内存中的存储方式(假设从地址0x8000开始存放)如表5-1所示。请完成表5-1的内容,填写由0x8000到0x8003字段中大端模式和小端模式下的值。
【问题2】(6分)
请用C语言的函数指针变量,对manage_device函数进行改造,填写下面C语言代码中的( 1)~(4)处的代码,将解答填入答题纸的对应栏内。
【C语言代码】
#include"stdio.h"
#include " stdlib.h"
extern int sys_status;
extern int Dev_drv1 (int arg1, int arg2) ;
extern int Dev_drv2 (int arg1, int arg2 ) ;
extern int Dev_drv3 (int arg1, int arg2);
extern int Dev_drv4 (int arg1, int arg2);
#define NOERROR 0
typedef struct {
int_fd;
(1);/*函数指针变量说明,变量名用process* /
}TYP_DEV_TAB;
TYP_DEV_TAB dev_tab [50]= { {101,Dev_drv1} , { 99,Dev_drv2},
{ 80,Dev_drv3 },{120, Dev_drv4 } , };
/*程序*/
void manage device(int devid, int arg1, int arg2.)
{
int place;
int ret;
(2) ;/*函数指针变量说明,局部变量,变量名用ProcAction*/
for(place=0; place<50; place++){
if (dev tab [place] ._fd -= devid){
(3);/*语句1,变量名用 ProcAction,得到具体函数的入口地址*/
break;
}
}
if(place>=50)
printf ( "NO DEVICE fd = %d\n" , devid) ;
(4);/*语句2*/
if(ret !=NOERROR)
printf ( "DEVICE %d error ! ", devid) ;
}
【问题3】(5分)
在飞腾FT2000-4国产处理器上,李工利用QSPI (Quad Serial Peripheral Interface)接口外接 SPI Flash 芯片,设计了针对该SPI Flash的擦除操作函数。
SPI Flash的擦除操作函数实现流程分为2步。
第一步:先对QSPI 中的CMD_PORT 寄存器的[31:24]位写入使能命令,并置位bit22;再对QSPI中的LD_PORT寄存器写入0x01。
第二步:先对QSPI中的CMD_PORT寄存器的[31:24]位写入Flash 擦除命令,并置位bit22和 bit15;再对ADDR_PORT寄存器中写入要擦除的地址;最后对 LD_PORT 寄存器写入0x01。
飞腾FT2000-4国产处理器的QSPI中的CMD_PORT、ADDR_PORT、LD_PORT 三个寄存器各个bit位对应含义如下表5-2、表5-3和表5-4所示。
李工设计的QSPI Flash擦除函数代码如下:
#define QSPI_ADDR BASE 0x28014000
#define QSPI_CMD PORT ADDR QSPI_ADDR_BASE+0x10
#define QSPI_ADDR_PORT_ADDR QSPT_ADDR_ BASE+0x14
#define QSPI_LD_ PORT ADDR QSPI_ADDR_ BASE+0x1C
#define QSPI_FLASH_ENABLE_CMD 0x06
#define QSPI_ FLASH ERASE CMD 0xd8
void QSPI_Flash Erase (void)
{
unsigned int *p_cmd_port = (unsigned int * )(QSPT_CMD_PORT_ADDR);
unsigned int *p_addr_port = (unsigned int *)(QSPI_ADDR_PORT_ADDR);
unsigned int *p_ld_port = (unsigned int * )(QSPI_LD_PORT_ADDR);
(1); /*
第一步:利用移位操作和或运算,
对p_cmd_port指针,运用QSPI_FLASH_ENABLE_CMD,
对QSPI中的cMD_PORT寄存器的[31:24]位写入使能命令,并置位bit22 * /
(2); /*
第二步:利用p_ ld port指针,对LD_PORT寄存器写入0x01
*/
(3); /*
利用移位操作和或运算,
对p_cmd port指针,运用QSPI_FLASH_ERASE_CMD,
对QSPI中的CMD_PORT寄存器的[31:24]位写入擦除命令,
并置位bit22和 bit15
*/
(4);/*利用p_addr port指针,对ADDR_PORT寄存器写入0x10000*/
(5);/*利用p_ld_port指针,对LD_PORT寄存器写入0x01*/