查看: 2418|回复: 0

编程风格

[复制链接]
  • TA的每日心情
    慵懒
    2018-3-28 17:24
  • 签到天数: 276 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2015-8-6 14:17:07 | 显示全部楼层 |阅读模式
    分享到:

    通常写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;
    }

    点评

    点个赞  发表于 2015-8-10 02:05

    评分

    参与人数 1与非币 +5 收起 理由
    loveeeboard + 5 三周年铜板双倍!

    查看全部评分

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条



    手机版|小黑屋|与非网

    GMT+8, 2025-1-27 09:44 , Processed in 0.124505 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.