Doxygen生成美麗注釋文檔(1):初體驗


Chapter 1 - 准備工作 (Windows環境)

1.1 程序包下載

1. Doxygen

  * 源碼: git clone https://github.com/doxygen/doxygen.git

  * GUI版本:點擊下載

  * 便攜壓縮包版本:下載 32位版本 64位版本

2. HTML Help Workshop

  用於生成CHM文件,便於傳播和查看。

  Htmlhelp.ex

3. Graphviz

  用於繪制DOT語言標本描述的圖形。Doxygen 使用 graphviz 自動生成類之間和文件之間的調用關系圖。

  * 源碼: graphviz.tar.gz

  * graphviz-2.38.msi

  * graphviz-2.38.zip

4. Sublime + DoxyDoxygen 插件

  * Sublime Text 3 Windows 64 bit 3176.exe

  * 便攜版 x64 3176.zip

1.2 安裝教程

Chapter 2 - 初嘗 Doxygen

2.1 為源代碼生成文檔大致分為兩個步驟:

  1. 為源代碼編寫符合 doxygen 要求的注釋

  2. 使用 doxygenwizard 生成文檔

2.2 編寫 Doxygen 注釋

/**< 標准輸入輸出頭文件 */
#include <stdio.h>

/** * @brief { Calculate the sum of two doubles } * * This function will return the sum of two doubles * * @param[in] a { the first number } * @param[in] b { the second number } * * @return double { the sum of a and b } */
double add(double a,double b)
{

    return a+b;
}

/** * @brief { Calculate the different of two doubles } * * This function will return the different of two doubles * * @param[in] a { the first number } * @param[in] b { the second number } * * @return double { the different of a and b } */
double subtract(double a,double b)
{
    return a-b;
}

/** * @brief { Calculate the product of two doubles } * * This function will return the product of two doubles * * @param[in] a { the first number } * @param[in] b { the second number } * * @return double { the product of a and b } */
double multiply(double a,double b)
{
    return a*b;
}

/** * @brief { Calculate the quotient of two doubles } * * This function will return the quotient of two doubles * * @param[in] a { the first number } * @param[in] b { the second number } * * @return double { the quotient of a and b } */
double divide(double a,double b)
{
    return a/b;
}

/** * @brief { This is the main function } * * This function is the main function. * It will print something in the screen. * * @return int { The exit code. } */
int main(void)
{
    int a = 5,b = 6;
    printf("%lf\n",add(a,b));
    printf("%lf\n",subtract(a,b));
    printf("%lf\n",multiply(a,b));
    printf("%lf\n",divide(a,b));

    return 0;
}

Doxygen 命令規范文檔:官網

2.3 使用 Doxygen 生成文檔

步驟:

  1. 打開 doxywizard
  2. 設置工作目錄、項目名稱、源文件目錄、生成文檔的目錄等
  3. 設置注釋抽取的模式、語言種類
  4. 設置輸出格式
  5. 設置如何輸出圖表
  6. 生成文檔

Chapter 3. Doxygen 書寫規則

此章節參考高明飛博客,原文地址

注釋和文檔的程序的組成部分,使用 Doxygen 可以將程序中特定格式的注釋提取出來,生成參考文檔。這樣只要在編程的時候遵循特定的格式書寫注釋,程序編好后文檔也就自然而成了。這無疑減少了單獨寫文檔所要花費的時間。

Doxygen 支持的語言有很多,常用的有C/C++JavaPython等,可以生成文檔格式有HTML、CHM和Latex格式等。

上文中我們已經使用了Doxygen做了一下演示。本章節主要以STM32系列單片機的標准庫的程序注釋為例進行分析。

3.1 定義功能模塊

STM32F0xx_StdPeriph_Driver是按照功能模塊進行組織的,每個功能模塊有其對應的頭文件和源文件。功能模塊列表如下:

為了讓Doxygen能正確提前模塊定義,需要添加模塊定義注釋。在文件中加入:

/** * @addtogroup ADC * @brief ADC driver modules * @{ */

// 程序代碼

/** * @} */

使用@brief對本模塊的主要功能進行說明,如需進行更詳細的說明,可使用@details

3.2 定義宏定義子模塊

定義了功能模塊后,一般還將宏定義單獨定義為一個子模塊,宏定義一般放在頭文件中,加入以下注釋:

/** * @defgroup ADC_Exported_Constants * @{ */

/** * @defgroup ADC_JitterOff * @{ */
#define ADC_JitterOff_PCLKDiv2 ADC_CFGR2_JITOFFDIV2
#define ADC_JitterOff_PCLKDiv4 ADC_CFGR2_JITOFFDIV4

#define IS_ADC_JITTEROFF(JITTEROFF) (((JITTEROFF) & 0x3FFFFFFF) == (uint32_t)RESET)

/** * @} */

/** * @defgroup ADC_Resolution * @{ */
#define ADC_Resolution_12b ((uint32_t)0x00000000)
#define ADC_Resolution_10b ADC_CFGR1_RES_0
#define ADC_Resolution_8b ADC_CFGR1_RES_1
#define ADC_Resolution_6b ADC_CFGR1_RES

#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \
                                         ((RESOLUTION) == ADC_Resolution_10b) || \
                                         ((RESOLUTION) == ADC_Resolution_8b) || \
                                         ((RESOLUTION) == ADC_Resolution_6b))

/** * @} */

/** * @} */

以上代碼段中定義了一個名為ADC_Exported_Constants的模塊,此模塊中包含了ADC模塊中所有的宏定義。

ADC_Exported_Constants模塊中,又有若干個子模塊,如ADC_JitterOffADC_Resolution等。

這樣組織代碼可以讓大量的宏定義結構更為清晰,而且有利於在其他地方進行交叉引用。

3.3 定義函數子模塊

與宏定義子模塊類似,也可以將函數定義為一個子模塊,並且按功能進行進一步分組歸類。

函數的定義與注釋說明一般都全部放在源文件中,頭文件中僅簡單的進行函數聲明。在源文件中加入以下注釋:

/** * @defgroup ADC_Private_Functions * @{ */

/** * @defgroup ADC_Group1 Initialization and Configuration functions * @brief Initialization and Configuration functions * * @{ */

void ADC_DeInit(ADC_TypeDef* ADCx){}
void ADC_Init(ADC_TypeDef* ADCx,ADC_InitTypeDef* ADC_InitStruct){}
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct){}
/** * @} */

/** * @defgroup ADC_Group2 Power saving functions * @brief Power saving function * @{ */
void ADC_AutoPowerOffCmd(ADC_TypeDef* ADCx,FunctionalState NewState){}
void ADC_WaitModeCmd(ADC_TypeDef* ADCx,FunctionalState NewState){}
/** * @} */

/** * @} */

以上代碼在實際代碼的基礎上進行了精簡,僅保留了進行模塊定義的基本結構。代碼段中定義了一個名為ADC_Private_Functions的模塊,此模塊中包含了所有的函數定義,並且各函數按用途進行了分組,分為若干個子模塊,如Initialzation and Configuration FunctionsPower saving functions等。

3.4 結構體注釋說明

對於結構體,一般使用如下形式的注釋:

/** * @brief ADC Init structure definition */
typedef struct
{
  /*!< Selects the resolution of the conversion. This parameter can be a value of @ref ADC_Resolution */
  uint32_t ADC_Resolution;                  

  /*!< Specifies whether the conversion is performed in Continuous or Single mode. This parameter can be set to ENABLE or DISABLE. */
  FunctionalState ADC_ContinuousConvMode;   

  /*!< Selects the external trigger Edge and enables the trigger of a regular group. This parameter can be a value of @ref ADC_external_trigger_edge_conversion */
  uint32_t ADC_ExternalTrigConvEdge;        

  /*!< Defines the external trigger used to start the analog to digital conversion of regular channels. This parameter can be a value of @ref ADC_external_trigger_sources_for_channels_conversion */
  uint32_t ADC_ExternalTrigConv;            

  /*!< Specifies whether the ADC data alignment is left or right. This parameter can be a value of @ref ADC_data_align */
  uint32_t ADC_DataAlign;                   

  /*!< Specifies in which direction the channels will be scanned in the sequence. This parameter can be a value of @ref ADC_Scan_Direction */
  uint32_t  ADC_ScanDirection;              
}ADC_InitTypeDef;

此代碼段中對ADC_InitTypeDef這個結構體進行了較為詳盡的注釋,開頭使用@brief說明此結構體的主要功能,之后對結構體中每個成員的意義進行了注釋。使用/*!< Comment */這樣的語法表示此注釋對應的是注釋前面的語句,這樣可以使代碼的排版更為美觀。

另外,注意到其中@ref標簽的使用,這代表交叉應用,如@ref ADC_Resolution,實際會生成一個超鏈接指向之前定義的ADC_Resolution模塊。這里的交叉引用可以是模塊名、函數名、結構體等。

3.5 枚舉注釋說明

枚舉的注釋形式與結構體完全相同,可參考以上示例。

3.6 函數注釋說明

函數的注釋說明一般放在源文件中,頭文件和源文件中最好不要重復添加注釋,否則生成文檔會有重復

函數的注釋一般使用以下的形式:

/** * @brief Enables or disables the ADC DMA request after last transfer (Single-ADC mode) * @param ADCx: where x can be 1 to select the ADC1 peripheral. * @param ADC_DMARequestMode: the ADC channel to configure. * This parameter can be one of the following values: * @arg ADC_DMAMode_OneShot: DMA One Shot Mode * @arg ADC_DMAMode_Circular: DMA Circular Mode * @retval None */
void ADC_DMARequestModeConfig(ADC_TypeDef* ADCx, uint32_t ADC_DMARequestMode){}

/** * @brief Active the Calibration operation for the selected ADC. * @note The Calibration can be initiated only when ADC is still in the * reset configuration (ADEN must be equal to 0). * @param ADCx: where x can be 1 to select the ADC1 peripheral. * @retval ADC Calibration factor */
uint32_t ADC_GetCalibrationFactor(ADC_TypeDef* ADCx){}
  • 使用@brief簡要說明函數的作用;
  • 使用@param說明輸入參數,若輸入參數是有限的幾個值,可用@arg進行列舉;
  • 使用@retval說明函數的返回值,另外,一些需要特別注意的地方可以使用@note@warning進行說明。

3.7 文件頭

每個文件的開頭部分一般都需要添加一個對此文件的說明,可使用如下格式:

/** ************************************************************** * @file Example.c * @author 作者 * @version V1.0 版本號 * @date 2015-11-13 * * @brief 程序的簡要說明 * * @details * @verbatim * 程序的詳細說明。 * * 修改記錄: * 2015-11-13 : * - 修改記錄 * * @endverbatim *************************************************************** */

@verbatim@endverbatim會按原樣逐行輸出,如果不用標簽標注出來的文本內容會被忽略掉。

另外,使用@todo@bug標簽列出待辦事項和BUG,Doxygen會在生成文檔時候自動匯總為Todo與Bug列表。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM