1 编程题:状态查询互斥设计(60分)
1.1 试题考核目的
考核目的:本试题通过设计和实现不同模块对同一硬件状态告警寄存器(读清寄存器)的可靠性处理来考核考生对读清寄存器的理解以及通用性设计和实现。
1.2 试题使用
使用说明:试题中已经明确说明了每个特性的验收标准(试题工程中提供了基本的自动化测试代码,与考生代码直接编译链接后即可自动运行测试),考生需要根据验收标准自行考虑完备的测试思路,考虑各种出错的可能情况。
调试环境:本试题采用Visual Studio 2005集成调测环境,并提供了已经建好的工程,具体使用方法参见“4.5试题提供的可直接使用的VC工程”。
1.3 试题说明
试题简介:某产品单板上硬件逻辑提供了一个状态告警的寄存器,该寄存器是读清寄存器,具体的寄存器定义如下表,其中不同的位表示不同的告警状态:
数据 | 默认值 | 位信号 | 信号定义 | 读写 |
D0 | 0 | 最低位 | 0表示无告警,1表示有告警(读寄存器后会自动清0) | Read Only |
D1 | 0 |
| 0表示无告警,1表示有告警(读寄存器后会自动清0) | Read Only |
D2~D31 | 0 |
| 缺省为0,如果有非零位,则表示逻辑器件已经失效 | Read Only |
该单板上有两个模块,分别为A、B,其中A模块监控上述寄存器的bit0,B模块监控上述寄存器的bit1,当发现故障时需要上报对应的告警(告警上报接口参见“4.4 试题配套API说明”中的API_ReportAlarm)(由于特性划分的需要,不能在一个模块中对上述寄存器的所有状态位进行监控)。由于上述寄存器是读清寄存器,因此在单板运行过程中必然会出现当A模块监控任务读取该寄存器后会导致寄存器信息被清零,从而导致B模块监控任务读取该寄存器时可能的告警状态位信息被清除,反之B模块的读取操作也会影响A模块。
请设计和实现软件方案,以解决A、B两个模块互相影响的问题,并通过代码实现和验证设计方案。
(1)A、B两个模块的监控任务处理入口函数命名如下(请考生自行创建监控任务,且必须使用这里指定的任务函数名称):
/*****************************************************************
函数原型:void DRV_AmonitorTaskEntry(void)
函数功能:A模块的状态告警监控处理任务入口函数
输入说明:无
输出说明:无
返回值:无;
*****************************************************************/
void DRV_AmonitorTaskEntry(void)
/*****************************************************************
函数原型:void DRV_BmonitorTaskEntry(void)
函数功能:B模块的状态告警监控处理任务入口函数
输入说明:无
输出说明:无
返回值:无;
*****************************************************************/
void DRV_BmonitorTaskEntry(void)
(2)为了方便编码,我们约定统一的初始化函数如下:
/*****************************************************************
函数原型:void DRV_Init(void)
函数功能:统一的初始化函数,考生在此函数中增加必须的初始化功能
输入说明:无
输出说明:无
返回值:无;
*****************************************************************/
void DRV_Init(void)
考生可以根据自己的设计在给定的源文件AccessHw.cpp中增加代码和函数,但告警监控和处理必须在DRV_AmonitorTaskEntry()和DRV_BmonitorTaskEntry()函数中实现,考生的初始化函数必须在DRV_Init()中实现,以便自动化阅卷;
【备注】采用API_ReportAlarm上报告警时的告警类型约定如下(参见AccessHw.h)
n A模块告警时告警类型ulAlmType值为0x00000001
n B模块告警时告警类型ulAlmType值为0x00000002
【验收标准】
n 状态告警寄存器指示有告警时能及时上报告警(<2秒);
n 告警寄存器中同时出现多个告警时不会丢失告警;
n 逻辑器件失效时(参见前面状态告警寄存器表格中的说明)不能误告警;
1.4 试题配套API说明
试题提供的配套API文件为AccessHwApi.cpp和AccessHwApi.cpp和对应的头文件(注:考生直接编译链接即可,不能修改其中的任何代码),该源文件提供了试题编码所需要的所有API函数和桩函数供调用,主要的目的是在脱离操作系统和硬件的情况下可以在PC机上进行试题的编写和调试(在PC机上使用VC环境),该部分API函数介绍如下(注:工程源码中未在本文档中说明的API接口函数,考生不得使用,且不得修改这两个API文件,如因修改此API文件或代码写在此API文件中导致编译不过或运行问题,编程题按“0”分计算,谢谢):
(1) 读状态告警寄存器
----------------------------------------------------------------
函数名 : void API_ReadLogicAlarmReg(unsigned int *pulAlarmData)
功能描述 : 读逻辑的状态告警寄存器,该告警寄存器是读清的;
输入参数 : pulAlarmData,读出的告警数据存放指针
输出参数 : *pulAlarmData,读出的告警数据
函数返回 : 无
----------------------------------------------------------------
(2) 告警上报接口
----------------------------------------------------------------
函数名 : void API_ReportAlarm(unsigned int ulAlmType)
功能描述 : 上报告警
输入参数 : ulAlmType,上报的告警类型
输出参数 : 无
函数返回 : 无
----------------------------------------------------------------
(3) 任务创建函数
----------------------------------------------------------------
函数名 : UINT32 API_CreateAndStartTask(void *pTaskEntry)
功能描述 : 创建并启动一个任务
输入参数 : pTaskEntry 任务入口,不支持参数
输出参数 :无
函数返回 : 0表示成功,非零表示失败
----------------------------------------------------------------
(4) 任务删除函数
----------------------------------------------------------------
函数名 : UINT32 API_DeleteTask(void *pTaskEntry)
功能描述 : 删除一个任务
输入参数 : pTaskEntry 任务入口指针
输出参数 :无
函数返回 : 0表示成功,非零表示失败
----------------------------------------------------------------
(5) 任务延时函数
----------------------------------------------------------------
函数名 : void API_TaskDelay (int iTickTime)
功能描述 : 主动释放CPU指定时间Tick数,Tick单位为1ms
输入参数 : int iTickTime: 需要释放CPU时间Tick数,取值必须大于0;
输出参数 : 无
函数返回 : 无
----------------------------------------------------------------
(6) 创建信号量
----------------------------------------------------------------
函数功能:创建信号量
函数原型:HANDLE API_CreateSem(void)
输入说明:无
输出说明:无
返回值:创建的信号量ID,返回NULL表示创建不成功;
----------------------------------------------------------------
(7) 获取信号量
----------------------------------------------------------------
函数功能:获取信号量
函数原型:int API_TakeSem(HANDLE semId,int WaitTime);
输入说明:semId: 需要获取的信号量ID
WaitTime:-1:表示死等,直到事件信号量到达 ;其他值:表示等待时间
输出说明:无
返回值:返回-1表示获取失败,返回0,表示获取成功,或者超时
----------------------------------------------------------------
(8) 释放信号量
----------------------------------------------------------------
函数功能:释放信号量
函数原型:int API_GiveSem(HANDLE semId);
输入说明:semId: 需要释放的信号量ID
输出说明:无
返回值:返回-1表示释放失败,返回0,表示释放成功----------------------------------------------------------------
(9) 删除信号量
----------------------------------------------------------------
函数功能:删除信号量
函数原型:void API_DeleteSem(HANDLE hSemId )
输入说明:hSemId: 需要删除的信号量Handle
输出说明:无
返回值:无
----------------------------------------------------------------
1.5 试题提供的可直接使用的VC工程
1.5.1 VC试题工程及其使用方法
双击“\AccessHw\ AccessHw.sln”程序可以直接打开工程环境,源代码框架(“\AccessHw \source”)已经提前加到工程中了。
1、编写好代码后,选择Rebuild菜单进行编译
2、编译完成后点击Start Debugging(F5)进行调试,如下图所示:
3、编码新增功能或者测试中发现错误修改后重新执行第2步即可。