Chapter 1 - 准備工作 (Windows環境)
1.1 程序包下載
1. Doxygen
* 源碼: git clone https://github.com/doxygen/doxygen.git
* GUI版本:點擊下載
2. HTML Help Workshop
用於生成CHM文件,便於傳播和查看。
3. Graphviz
用於繪制DOT語言標本描述的圖形。Doxygen 使用 graphviz 自動生成類之間和文件之間的調用關系圖。
* 源碼: graphviz.tar.gz
4. Sublime
+ DoxyDoxygen
插件
* Sublime Text 3 Windows 64 bit 3176.exe
1.2 安裝教程
Chapter 2 - 初嘗 Doxygen
2.1 為源代碼生成文檔大致分為兩個步驟:
-
為源代碼編寫符合
doxygen
要求的注釋 -
使用
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 生成文檔
步驟:
- 打開
doxywizard
- 設置工作目錄、項目名稱、源文件目錄、生成文檔的目錄等
- 設置注釋抽取的模式、語言種類
- 設置輸出格式
- 設置如何輸出圖表
- 生成文檔
Chapter 3. Doxygen 書寫規則
此章節參考高明飛博客,原文地址
注釋和文檔的程序的組成部分,使用 Doxygen
可以將程序中特定格式的注釋提取出來,生成參考文檔。這樣只要在編程的時候遵循特定的格式書寫注釋,程序編好后文檔也就自然而成了。這無疑減少了單獨寫文檔所要花費的時間。
Doxygen 支持的語言有很多,常用的有C/C++
、Java
、Python
等,可以生成文檔格式有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_JitterOff
、ADC_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 Functions
、Power 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列表。