TA的每日心情 | 慵懒 2018-3-28 17:24 |
---|
签到天数: 276 天 连续签到: 1 天 [LV.8]以坛为家I
|
通常写PC代码的人都非常注意编程风格和版本管理,大概是由于代码量复杂很多吧。原来我项目组里有个清华的研究生哥们,是我见过写代码最牛的了,经常是在linux下运指如飞,各种开发语言都会,最牛的是不要硬件平台就能写出几乎没有什么bug的代码,经测试人员在硬件平台上测试后运行很正常,令我大为佩服。
而写单片机代码的人大部分都不注意编程风格,通常都是比较自由散漫的风格,究其原因大概与单片机大部分是单兵作战有关,自己写成什么样子自己能看懂就行。其实不然,良好的风格不仅使代码具有良好的可维护性,让人读起来也是赏心悦目,更重要的是在进行多兵联合作战的情况下,良好统一的编程风格可以让调试变得更加简单,减少扯皮现象的发生,加快联调的进度。
由于所使用编译系统的特殊性,本文档包含一些软件设计中建议遵循的约定。本文档仅仅描述***系统软件中的底层接口功能模块,以及这些模块所应该提供的接口函数原型定义。
A. 约定:
1. 建议在所有的软件设计过程中,尽量使用标准C,不要使用汇编/C++等编程规则。
2. 在通常情况下,各类C编译器都没有定义标准的字节型(BYTE)、字型(WORD)、长字型(DWORD)数据类型,并且整型(int)、长整型(long)等数据类型所表示的字节数是不同的。所以,根据我们所使用的C编译器特点,自定义以下简单数据类型:
无符号字节型(UCHAR)、无符号字型(UWORD)、无符号长字型(ULONG)、
有符号字节型(SCHAR)、有符号字型(SWORD)、有符号长字型(SLONG)
建议在软件设计过程中尽量使用自定义数据类型。这些自定义简单数据类型定义如下(包含在DataType.h中):
#ifndef __DATATYPE__
#define __DATATYPE__
typedef unsigned char UCHAR;
typedef char SCHAR;
typedef unsigned short UWORD;
typedef short SWORD;
typedef unsigned long ULONG;
typedef long SLONG;
#endif
3. 变量和宏的命名规则遵循标准C的命名规则。变量的命名用英文单词的全拼表示,各单词之间用下划线分隔,并且每个单词的第1个字母大写;宏的命名也用英文单词的全拼表示,各单词之间不用下划线分隔,并且每个单词的每个字母均大写。例如: UWORD Song_Name ;定义一个无符号短整型变量
#define TOTALNUMBER 20 ;定义一个宏TOTALNUMBER
4. 结构和联合等复合变量的命名规则同变量类似,只是每个单词的每个字母均大写。如:
// 结构定义
typedef struct _STRUCT_DEFINITION
{
UCHAR ch;
} STRUCT_DEFINITION;
// 变量定义
STRUCT_DEFINITION Str_Def;
5. 函数的命名规则同变量。形参的命名同变量类似,只是单词的每个字母均小写。
例如:void Get_Song(UCHAR song_name[11],ULONG *buffer, ULONG length)
6. 一般情况下,所有模块文件内的注释均采用英文书写。
7. 定义函数操作返回值常量:成功:SUCCESS 错误:FAILED
8. 系统定义所有寄存器和寄存器操作宏:
i. 寄存器定义,如:
#define SCR 0xFFFFF000
建议不要直接使用寄存器定义,而是使用以下宏定义
ii. 获取寄存器操作宏,在寄存器名称前加GET_前缀,如:
#define GET_SCR *((UCHAR *) SCR)
使用: UCHAR xx = GET_SCR;
iii. 设置寄存器值操作宏,在寄存器名称前加SET_前缀,如:
#define SET_SCR(rVal) *((UCHAR *) SCR) = (UCHAR) rVal
使用: SET_SCR(0x18);
9. 每个模块文件内书写约定:
i. 文件头:
本部分包含模块简要描述,具体内容如下:
1. 模块名称(Module Name)
2. 模块编制者(Author)
3. 模块版本(Version)
4. 模块编制日期(Create Date)
5. 模块描述(Description)
6. 模块特殊声明(Remark)
7. 模块修改历史(Revision History)
ii. 接口定义:
本部分包含模块内所有函数的接口定义,每个函数具体定义如下:
1. 函数原型(Prototype)
2. 函数功能描述(Description)
3. 函数入口(Input)
4. 函数出口(Output)
5. 函数特殊声明(Remark)
iii. 全局变量和宏定义:
本部分声明本模块使用的全局变量和宏定义
iv. 具体算法描述:
本部分具体实现所有函数的算法
v. 模块测试规划:
本部分描述本模块内所有函数功能的测试方法和注意事项
eg.
Zip控制(ATAPI命令封装接口函数)模块 模块
本模块完成系统使用的Zip控制相关的所有ATAPI接口命令的封装。
1. 本模块常量、数据结构以及特殊约定描述:
2. 接口描述:
a) 传递Zip控制:
函数原型:SWORD Pass_Zip_Control(UCHAR *buf, UWORD len);
功能描述:USB传递控制/数据到Zip
函数入口:buf:传递数据缓冲区
len:传递数据实际字节数
函数出口:FAILED:未知错误
SUCCESS:传递成功
其它非零值:发生错误需要回传的数据字节数,数据存放在
缓冲区buf
特殊声明:无
一个通过ATAPI接口控制磁盘的例子
硬件使用的是motorola的dragonball系列vz328
/*********************************************************************
** Module Name: atapi_oem.c **
** Author: Huozq **
** Version: 1.0 **
** CreateDate: 2001-06-14 **
** Description: Atapi Functions **
** Remark: **
** Revision History: 2001-06-14 **
**********************************************************************/
#include "Atapi_OEM_Data.h"
#include "VZ328_Register_Definition.h"
#include "DataType.h"
//Invoke example
//Before operate(read or write) the drive it should check the status of zip
//{
// while( errno = Packet_Drive_Ready() ) ;
// Packet_Read(i*256,0,buf);
//}
void Zip_Initialize(void)
{
// Port initialization
SET_PCSEL (0xff);
SET_PCDIR (0xff);
SET_PCPUEN(0xff);
SET_PDSEL (0xff);
SET_PDDIR (0xff);
SET_PDPUEN(0xff);
SET_PKSEL (0xfb);
SET_PKDIR (0x7f);
SET_PKPUEN(0xff);
SET_PMSEL (GET_PMSEL | 0x20);
SET_PMDIR (0xff);
SET_PMPUEN(0xff);
// Other initialization
SET_PKDATA(0x7f);
SET_PMDATA(GET_PMDATA | 0x20);
}
//Read the content of registers,Used for test
void Read_Register(void)
{
UWORD i,status,addr;
SET_INPUT_MODE();
for(i=0;i<8;i++)
{
status=Read_ATA_Reg(0x07+i*0x10);
}
status=Read_ATA_Reg(ALTERNATE_STATUS_REG);
status=Read_ATA_Reg(INTERRUPT_REASON_REG);
}
//Request the configuration of the PocketZip
UWORD Packet_Inquiry(UCHAR *buf)
{
PACKET_INQUIRY ptrINQUIRY;
ATAPI_COMMAND ptrATAPI;
Init_Struct( (UCHAR *) &ptrINQUIRY );
ptrINQUIRY.Command=0x12;
ptrINQUIRY.Allocation_Length=122;
ptrATAPI.Packet_Command=(UCHAR *) &ptrINQUIRY;
ptrATAPI.Buffer_Length =ptrINQUIRY.Allocation_Length;
ptrATAPI.Buffer_Pointer=buf;
ptrATAPI.Id=ID_OTHERS;
return Exec_ATAPI_Command(&ptrATAPI);
}
//Request information regarding the capacity of the installed media
UWORD Packet_Read_Capacity(UCHAR *buf)
{
PACKET_RDWR ptrRDWR;
ATAPI_COMMAND ptrATAPI;
Init_Struct( (UCHAR *) &ptrRDWR );
ptrRDWR.Command=0x25;
ptrATAPI.Packet_Command=(UCHAR *) &ptrRDWR;
ptrATAPI.Buffer_Length =8;
ptrATAPI.Buffer_Pointer=buf;
ptrATAPI.Id=ID_OTHERS;
return Exec_ATAPI_Command(&ptrATAPI);
}
//Request the status and sense data from the PocketZip
UWORD Packet_Request_Sense(UCHAR *buf)
{
PACKET_STRUCT ptrSTRUCT;
ATAPI_COMMAND ptrATAPI;
Init_Struct( ptrSTRUCT );
ptrSTRUCT[0]=0x03;
ptrSTRUCT[4]=26;
ptrATAPI.Packet_Command=(UCHAR *) &ptrSTRUCT;
ptrATAPI.Buffer_Length =ptrSTRUCT[4];
ptrATAPI.Buffer_Pointer=buf;
ptrATAPI.Id=ID_OTHERS;
return Exec_ATAPI_Command(&ptrATAPI);
}
//Report vendor specific drive and disk data including current status and diagnostic information
UWORD Packet_Non_Sense(UCHAR *buf)
{
PACKET_STRUCT ptrSTRUCT;
ATAPI_COMMAND ptrATAPI;
Init_Struct( ptrSTRUCT );
ptrSTRUCT[0]=0x06;
ptrSTRUCT[2]=0x00; //Page Code :0 ;1 ;2 ;3
ptrSTRUCT[4]=0xff; //Allocation Length :255 ;88 ;64 ;201
ptrATAPI.Packet_Command=(UCHAR *) &ptrSTRUCT;
ptrATAPI.Buffer_Length =ptrSTRUCT[4];
ptrATAPI.Buffer_Pointer=buf;
ptrATAPI.Id=ID_OTHERS;
return Exec_ATAPI_Command(&ptrATAPI);
}
//Seek to the track
UWORD Packet_Seek(void)
{
PACKET_RDWR ptrRDWR;
ATAPI_COMMAND ptrATAPI;
Init_Struct( (UCHAR *) &ptrRDWR );
ptrRDWR.Command=0x2b;
ptrRDWR.Lba=0x1;
ptrATAPI.Packet_Command=(UCHAR *) &ptrRDWR;
ptrATAPI.Buffer_Length =ptrRDWR.Transfer_Length;
ptrATAPI.Buffer_Pointer=0;
ptrATAPI.Id=ID_OTHERS;
return Exec_ATAPI_Command(&ptrATAPI);
}
UWORD Packet_Start_Stop(void)
{
PACKET_STRUCT ptrSTRUCT;
ATAPI_COMMAND ptrATAPI;
Init_Struct( ptrSTRUCT );
ptrSTRUCT[0]=0x1b;
ptrATAPI.Packet_Command=(UCHAR *) &ptrSTRUCT;
ptrATAPI.Buffer_Length =0;
ptrATAPI.Buffer_Pointer=0;
ptrATAPI.Id=ID_OTHERS;
return Exec_ATAPI_Command(&ptrATAPI);
}
/*********************************************************************
** Prototype: UWORD Packet_Drive_Ready(void); **
** Description: Test the readiness of the drive for disk access **
** Input Parameter:None **
** Return: Error Code **
**********************************************************************/
UWORD Packet_Drive_Ready(void)
{
PACKET_RDWR ptrRDWR;
ATAPI_COMMAND ptrATAPI;
Init_Struct( (UCHAR *) &ptrRDWR );
ptrRDWR.Command=0x00;
ptrATAPI.Packet_Command=(UCHAR *) &ptrRDWR;
ptrATAPI.Buffer_Length =0;
ptrATAPI.Buffer_Pointer=0;
ptrATAPI.Id=ID_OTHERS;
return Exec_ATAPI_Command(&ptrATAPI);
}
/*************************************************************************
** Prototype: UWORD Packet_Read(ULONG lba,UWORD num,UCHAR *buf); **
** Description: Read data from the drive **
** Input Parameter:lba--The sector starting address of the zip **
** num--The sector number of the zip **
** buf--The address to store the data read from the zip**
** Return: Error Code **
**************************************************************************/
UWORD Packet_Read(ULONG lba,UWORD num,UCHAR *buf)
{
PACKET_RDWR ptrRDWR;
ATAPI_COMMAND ptrATAPI;
Init_Struct( (UCHAR *) &ptrRDWR );
ptrRDWR.Command =0x08;
ptrRDWR.Lbah =(UCHAR) (lba / 0x10000);
ptrRDWR.Lba =(UWORD) (lba % 0x10000);
ptrRDWR.Transfer_Length =(UCHAR) num;
ptrATAPI.Packet_Command =(UCHAR *) &ptrRDWR;
ptrATAPI.Buffer_Length =ptrRDWR.Transfer_Length;
ptrATAPI.Buffer_Pointer =(UCHAR *) buf;
ptrATAPI.Id =ID_RD;
return Exec_ATAPI_Command(&ptrATAPI);
}
/*************************************************************************
** Prototype: UWORD Packet_Write(ULONG lba,UWORD num,UCHAR *buf); **
** Description: Write data to the drive **
** Input Parameter:lba--The sector starting address of the zip **
** num--The sector number of the zip **
** buf--The address to store the data wrote to the zip **
** Return: Error Code **
**************************************************************************/
UWORD Packet_Write(ULONG lba,UWORD num,UCHAR *buf)
{
PACKET_RDWR ptrRDWR;
ATAPI_COMMAND ptrATAPI;
Init_Struct( (UCHAR *) &ptrRDWR );
ptrRDWR.Command =0x0a;
ptrRDWR.Lbah =(UCHAR) (lba / 0x10000);
ptrRDWR.Lba =(UWORD) (lba % 0x10000);
ptrRDWR.Transfer_Length =(UCHAR) num;
ptrATAPI.Packet_Command =(UCHAR *) &ptrRDWR;
ptrATAPI.Buffer_Length =ptrRDWR.Transfer_Length;
ptrATAPI.Buffer_Pointer =(UCHAR *) buf;
ptrATAPI.Id =ID_WR;
return Exec_ATAPI_Command(&ptrATAPI);
}
/*************************************************************************
** Prototype: UWORD Exec_ATAPI_Command(ATAPI_COMMAND *ptrATAPI); **
** Description: Achieve the ATAPI command **
** Input Parameter:ptrATAPI--The information about ATAPI command **
** Return: Error Code **
**************************************************************************/
UWORD Exec_ATAPI_Command(ATAPI_COMMAND *ptrATAPI) //MAJOR SUBROUTINE
{
UCHAR status,errno=0;
UWORD i,j,n;
UWORD *buf=(UWORD *)ptrATAPI->Buffer_Pointer;
Packet();
Send_Packet( (UWORD *)ptrATAPI->Packet_Command);
if ( ptrATAPI->Id == ID_WR ) //If write operation
{
if ( (ptrATAPI->Packet_Command[0] = 0x0a) && (ptrATAPI->Buffer_Length == 0) )
ptrATAPI->Buffer_Length=256;
n=ptrATAPI->Buffer_Length;
for (i = 0; i < n; i++)
{
SET_INPUT_MODE();
while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY) ;
if (status & ATA_STATUS_ERR)
{
errno = Read_ATA_Reg(ERROR_REG);
return errno;
} //check the status
SET_OUTPUT_MODE();
SET_ADDR(DATA_REG);
for (j = 0; j < 256; j++)
{
//Write_A_Word( buf[i * 256 + j] );
Write_A_Word( *buf++ );
ASSERT_WR();
NEGATE_WR(); //write
}
}
}
else if ( ptrATAPI->Id == ID_RD ) //If read operation
{
if ( (ptrATAPI->Packet_Command[0] = 0x08) && (ptrATAPI->Buffer_Length == 0) )
ptrATAPI->Buffer_Length=256;
n=ptrATAPI->Buffer_Length;
for (i = 0; i < n; i++)
{
while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY) ;
if (status & ATA_STATUS_ERR)
{
errno = Read_ATA_Reg(ERROR_REG);
return errno;
}
SET_ADDR(DATA_REG);
for (j = 0; j < 256; j++)
{
ASSERT_RD();
*buf++ = Read_A_Word();
//buf[i * 256 + j] = Read_A_Word();
NEGATE_RD();
}
}
}
else if ( ptrATAPI->Id == ID_SET )
{
while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY) ;
if (status & ATA_STATUS_ERR)
{
errno = Read_ATA_Reg(ERROR_REG);
return errno;
}
SET_OUTPUT_MODE();
SET_ADDR(DATA_REG);
for (j = 0; j < (UWORD)( ptrATAPI->Buffer_Length / 2 ); j++)
{
Write_A_Word( buf[j] );
ASSERT_WR();
NEGATE_WR();
}
}
else //If other operation
{
while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY) ;
if (status & ATA_STATUS_ERR)
{
errno = Read_ATA_Reg(ERROR_REG);
return errno;
}
SET_ADDR(DATA_REG);
for (j = 0; j < (UWORD)( ptrATAPI->Buffer_Length / 2 ); j++)
{
ASSERT_RD();
buf[j] = Read_A_Word();
NEGATE_RD();
}
}
SET_INPUT_MODE();
return 0;
}
void Send_Packet(UWORD *command)
{
UWORD i;
SET_OUTPUT_MODE();
for(i=0;i<6;i++)
Write_ATA_Data_Reg(command);
SET_INPUT_MODE();
}
UCHAR Packet(void)
{
UCHAR status, errno = 0,c=0x80;
SET_OUTPUT_MODE();
Write_ATA_Reg(FEATURE_REG, 0x0);
Write_ATA_Reg(BYTE_COUNT_LOW_REG, 0xff);
Write_ATA_Reg(BYTE_COUNT_HIGH_REG, 0xff);
Write_ATA_Reg(DRIVE_HEAD_REG, 0xa0);
Write_ATA_Reg(COMMAND_REG, 0xa0);
SET_INPUT_MODE();
while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY) ;
while (!((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_DRQ)) ;
if (status & ATA_STATUS_ERR)
errno = Read_ATA_Reg(ERROR_REG);
return errno;
}
UCHAR Read_ATA_Reg(UCHAR reg) //read register
{
UCHAR c;
SET_ADDR(reg);
ASSERT_RD();
c=Read_A_Byte();
NEGATE_RD();
return c;
}
void Write_ATA_Reg(UCHAR reg,UCHAR c) //write register
{
SET_ADDR(reg);
Write_A_Byte(c);
ASSERT_WR();
NEGATE_WR();
}
UWORD Read_ATA_Data_Reg(void) //read data register
{
UWORD n;
SET_ADDR(DATA_REG);
ASSERT_RD();
n = Read_A_Word();
NEGATE_RD();
return n;
}
void Write_ATA_Data_Reg(UWORD n) //write data register
{
SET_ADDR(DATA_REG);
Write_A_Word(n);
ASSERT_WR();
NEGATE_WR();
}
UCHAR Read_A_Byte(void) //read low byte
{
return(GET_PLDATA);
}
void Write_A_Byte(UCHAR c) //write a byte to low 8 bit data bus
{
SET_PLDATA(c);
}
UWORD Read_A_Word(void) //read a word from data bus
{
return(GET_PLDATA<<8 | GET_PHDATA); //high is fore
}
void Write_A_Word(UWORD n) //write a word to data bus
{
SET_PHDATA( (UCHAR) n );
SET_PLDATA( (UCHAR) ( n >> 8 ) );
}
void Init_Struct(UCHAR *buf)
{
UWORD i;
for(i=0 ; i<12 ; i++)
*buf++=0;
}
|
评分
-
查看全部评分
|