1 | .. comment SPDX-License-Identifier: CC-BY-SA-4.0 |
---|
2 | |
---|
3 | .. Copyright (C) 2018. |
---|
4 | .. COMMENT: RTEMS Foundation, The RTEMS Documentation Project |
---|
5 | |
---|
6 | |
---|
7 | .. COMMENT:TBD - Convert the following to Rest and insert into this file |
---|
8 | .. COMMENT:TBD - https://devel.rtems.org/wiki/Developer/Coding/Doxygen_for_BSPs |
---|
9 | |
---|
10 | |
---|
11 | Doxygen Recommendations for BSPs |
---|
12 | ================================ |
---|
13 | |
---|
14 | RTEMS contains well over a hundred `Board Support Packages (BSPs) |
---|
15 | <wiki:TBR/Website/Board_Support_Packages>`_. , across over 20 different |
---|
16 | `CPU Architectures <wiki:TBR/UserManual/SupportedCPUs>`_. . What this |
---|
17 | means is that there is a lot of hardware dependent code that gets |
---|
18 | written, and that adding Doxygen to properly document it all can be a |
---|
19 | very complicated task. |
---|
20 | |
---|
21 | The goal of this document is to attempt to simplify this process a bit, |
---|
22 | and to get you started on adding Doxygen to the bsps/ directory in a way |
---|
23 | that is logical and has structure. Before we move on to detailing the |
---|
24 | process of actually adding Doxygen to BSPs, you will be greatly served by |
---|
25 | having at least a basic understanding of the purpose of a Board Support |
---|
26 | Package (it always helps to know a bit about what you're documenting), |
---|
27 | as well as of the existing structure of the bsps/ directory. |
---|
28 | |
---|
29 | Feel free to skip around and skim parts of this. |
---|
30 | |
---|
31 | BSP Basics |
---|
32 | ---------- |
---|
33 | |
---|
34 | Embedded development is hard. Different CPUs have different instructions |
---|
35 | for doing the same thing, and different boards will have all sorts of |
---|
36 | different hardware that require unique drivers and interfaces. RTEMS |
---|
37 | handles this by having discrete packages, BSPs, to encapsulate |
---|
38 | code to accommodate for unique hardware. BSPs seek to implement the |
---|
39 | Hardware-Software interface. This, in a nutshell, is one of the `core |
---|
40 | purposes <wiki:Mission_Statement>`_. of RTEMS: To abstract (as much as |
---|
41 | is possible) away from the physical hardware and provide a standards |
---|
42 | compliant real-time environment for the embedded developer. If you think |
---|
43 | about it, the operating system on your normal computer serves a very |
---|
44 | similar purpose. |
---|
45 | |
---|
46 | Common Features Found In BSPs |
---|
47 | ----------------------------- |
---|
48 | |
---|
49 | Although the actual implementation code will differ between BSPs, all |
---|
50 | BSPs will share some degree of common functionality. This is because |
---|
51 | that no matter what exact hardware you have, you need some basic features |
---|
52 | implemented in order to have a real time system you can develop on. Some |
---|
53 | of the most common shared features across most boards include: |
---|
54 | |
---|
55 | * **console**: is technically the serial driver for the BSP rather than |
---|
56 | just a console driver, it deals with the board UART (i.e. serial devices) |
---|
57 | * **clock**: support for the clock tick - a regular time basis for the kernel |
---|
58 | * **timer**: support of timer devices, used for timing tests |
---|
59 | * **rtc** or **tod**: support for the hardware real time clock |
---|
60 | * **network**: the Ethernet driver |
---|
61 | * **shmsupp**: support of shared memory driver MPCI layer in a |
---|
62 | multiprocessor system |
---|
63 | * **gnatsupp**: BSP specific support for the GNU Ada run-time |
---|
64 | * **irq**: support for how the processor handles interrupts (probably |
---|
65 | the most common module shared by all boards) |
---|
66 | * **tm27**: specific routines for the tm27 timing test |
---|
67 | * **start** and **startup**: C and assembly used to initialize the |
---|
68 | board during startups/resets/reboots |
---|
69 | |
---|
70 | These are just some of the things you should be looking for when adding |
---|
71 | Doxygen to a BSP. |
---|
72 | |
---|
73 | Note that there is no guarantee a particular BSP will implement all of |
---|
74 | these features, or even some of them. These are just the most common |
---|
75 | ones to look for. RTEMS follows a standardized naming convention for |
---|
76 | the BSP sub directories, so you should be able to tell in most cases |
---|
77 | what has been implemented on the BSP level and what has not. |
---|
78 | |
---|
79 | Shared Features |
---|
80 | --------------- |
---|
81 | |
---|
82 | Some of the RTEMS executive is hardware independent and can be abstracted |
---|
83 | so that the same piece of code can be shared across multiple CPU |
---|
84 | architectures, or across multiple boards on the same architecture. This |
---|
85 | is done so that chunks of software can be reused, as well as aiding |
---|
86 | in reducing the development and debugging time for implementing new |
---|
87 | BSPs. This greatly aids the developer, but as someone seeking to document |
---|
88 | this code, this can make your life a little bit harder. It is hard to |
---|
89 | tell by looking at the directory of a BSP which features have simply been |
---|
90 | left out and which features are being implemented by using shared code |
---|
91 | from either from the architecture (../shared) or the base bsps/ shared |
---|
92 | directory (../../shared). You may be looking at the BSP headers and notice |
---|
93 | that you have an irq.h, but no irq.c implementing it, or you might even be |
---|
94 | missing both. You know that the processor has interrupt support somehow, |
---|
95 | but where is it? The easiest way to figure this out is by looking at |
---|
96 | the Makefile.am for a BSP. We'll detail this process more in a bit. |
---|
97 | |
---|
98 | Rationale |
---|
99 | --------- |
---|
100 | |
---|
101 | As someone adding documentation and not doing actual development |
---|
102 | work, you might think it is not necessary to know some of the in and |
---|
103 | outs of BSPs. In actuality, this information will prove to be very |
---|
104 | useful. Doxygen documentation works by grouping things and their |
---|
105 | components (i.e. functions and other definitions), and by having |
---|
106 | brief descriptions of what each group does. You can't know what to |
---|
107 | look for or know how to group it or know how to describe it without |
---|
108 | some basic knowledge of what a BSP is. For more information on any |
---|
109 | of the above or BSPs in general, check out the `BSP Development Guide |
---|
110 | <http://rtems.org/onlinedocs/doc-current/share/rtems/html/bsp_howto/index.html>`_. |
---|
111 | . |
---|
112 | |
---|
113 | The Structure of the bsps/ directory |
---|
114 | ------------------------------------ |
---|
115 | |
---|
116 | All BSPs are found within the bsps/ directory, which is itself very |
---|
117 | well ordered. At the first level, we find a directory for each CPU |
---|
118 | architecture RTEMS supports, as well as a directory for code shared by |
---|
119 | all implementations. |
---|
120 | |
---|
121 | .. code-block:: shell |
---|
122 | |
---|
123 | $ cd bsps |
---|
124 | $ ls |
---|
125 | arm bsp.am lm32 m68k mips no_cpu README sparc |
---|
126 | avr h8300 m32c Makefile.am moxie powerpc sh sparc64 |
---|
127 | bfin i386 m32r MERGE.PROCEDURE nios2 preinstall.am shared v850 |
---|
128 | |
---|
129 | |
---|
130 | If we cd into a specific architecture, we see that a similar structure is |
---|
131 | employed. bsps/arm/ contains directories for each Board Support Package |
---|
132 | for boards with an ARM cpu, along with a folder for files and .h's shared |
---|
133 | by all BSPs of that architecture. |
---|
134 | |
---|
135 | .. code-block:: shell |
---|
136 | |
---|
137 | $ cd arm |
---|
138 | $ ls |
---|
139 | acinclude.m4 edb7312 gumstix Makefile.am realview-pbx-a9 stm32f4 |
---|
140 | configure.ac gba lm3s69xx nds rtl22xx xilinx-zynq |
---|
141 | csb336 gdbarmsim lpc24xx preinstall.am shared |
---|
142 | csb337 gp32 lpc32xx raspberrypi smdk2410 |
---|
143 | |
---|
144 | Finally, if we cd into a specific BSP, we see the files and .h's that |
---|
145 | compose the package for that particular board. You may recognize the |
---|
146 | directory names as some of the [common features] we outlined above, |
---|
147 | like '''irq''', '''clock''', '''console''', and '''startup'''. These |
---|
148 | directories contain implementations of these features. |
---|
149 | |
---|
150 | .. code-block:: shell |
---|
151 | |
---|
152 | $ cd raspberrypi |
---|
153 | $ ls |
---|
154 | bsp_specs configure.ac include make misc README |
---|
155 | clock console irq Makefile.am preinstall.am startup |
---|
156 | |
---|
157 | Another way to get an idea of the structure of bsps/ is to navigate |
---|
158 | to a directory and execute the "tree -f" command. This outputs a nice |
---|
159 | graphic that conveys some of the hierarchical properties of a particular |
---|
160 | directory. |
---|
161 | |
---|
162 | .. code-block:: shell |
---|
163 | |
---|
164 | $ pwd |
---|
165 | ~/rtems/bsps/arm/raspberrypi |
---|
166 | $ tree -f |
---|
167 | . |
---|
168 | |-- ./bsp_specs |
---|
169 | |-- ./clock |
---|
170 | | `-- ./clock/clockdrv.c |
---|
171 | |-- ./configure.ac |
---|
172 | |-- ./console |
---|
173 | | |-- ./console/console-config.c |
---|
174 | | `-- ./console/usart.c |
---|
175 | |-- ./include |
---|
176 | | |-- ./include/bsp.h |
---|
177 | | |-- ./include/irq.h |
---|
178 | | |-- ./include/mmu.h |
---|
179 | | |-- ./include/raspberrypi.h |
---|
180 | | `-- ./include/usart.h |
---|
181 | |-- ./irq |
---|
182 | | `-- ./irq/irq.c |
---|
183 | |-- ./make |
---|
184 | | `-- ./make/custom |
---|
185 | | `-- ./make/custom/raspberrypi.cfg |
---|
186 | |-- ./Makefile.am |
---|
187 | |-- ./misc |
---|
188 | | `-- ./misc/timer.c |
---|
189 | |-- ./preinstall.am |
---|
190 | |-- ./README |
---|
191 | `-- ./startup |
---|
192 | |-- ./startup/bspreset.c |
---|
193 | |-- ./startup/bspstart.c |
---|
194 | |-- ./startup/bspstarthooks.c |
---|
195 | |-- ./startup/linkcmds |
---|
196 | `-- ./startup/mm_config_table.c |
---|
197 | |
---|
198 | |
---|
199 | In short, BSPs will use the following directories: |
---|
200 | |
---|
201 | * bsps/**shared** <- code used that is shared by all BSPs |
---|
202 | * bsps/**CPU**/**shared** <- code used shared by all BSPs of a particular CPU architecture |
---|
203 | * bsps/**CPU**/**BSP** <- code unique to this BSP |
---|
204 | |
---|
205 | As you can see, the bsps/ directory has a very logical and easy to |
---|
206 | understand structure to it. The documentation generated by Doxygen |
---|
207 | should attempt to match this structure as closely as possible. We want |
---|
208 | an overarching parent group to serve the same purpose as the bsps/ |
---|
209 | directory. In it, we want groups for each CPU architecture and a group |
---|
210 | for the shared files. We then want groups for each BSP. Breaking our |
---|
211 | documentation up into discrete groups like this will greatly simplify |
---|
212 | the process and make the documentation much easier to go through. By |
---|
213 | learning about the existing structure of the bsps/ directory, we get an |
---|
214 | idea of how we should structure the Doxygen groups we create. More on |
---|
215 | this in the next section. |
---|
216 | |
---|
217 | Doxygen |
---|
218 | ------- |
---|
219 | |
---|
220 | Now that we have covered some of the preliminaries, we can move on to |
---|
221 | what you are actually reading this wiki page for: adding Doxygen to the |
---|
222 | bsps/ directory. Let's start with some Doxygen basics. Skip this if you |
---|
223 | are already comfortable with Doxygen. |
---|
224 | |
---|
225 | In addition to this, check out the page on `Doxygen Recommendations |
---|
226 | <wiki:Developer/Coding/Doxygen >`_. , which also contains a fair amount |
---|
227 | of information that will not be covered here. |
---|
228 | |
---|
229 | Doxygen Basics |
---|
230 | -------------- |
---|
231 | |
---|
232 | Doxygen is a documentation generator. It allows for documentation to be |
---|
233 | written right by the source code, greatly easing the pains of keeping |
---|
234 | documentation relevant and up to date. Doxygen has many commands, |
---|
235 | used for things like annotating functions with descriptions, parameter |
---|
236 | information, or return value information. You can reference other files |
---|
237 | or even other documentation. |
---|
238 | |
---|
239 | The core component of Doxygen (that we care about right now at least) is |
---|
240 | what's called a **group**, or **module**. These are used to add structure |
---|
241 | and associate groups of files that serve a similar purpose or implement |
---|
242 | the same thing. |
---|
243 | |
---|
244 | Doxygen Headers |
---|
245 | --------------- |
---|
246 | Doxygen is always found in a special Doxygen comment block, known as a |
---|
247 | **Doxygen header**. In RTEMS, this block comes in the form of a multiline |
---|
248 | comment with some included Doxygen commands, which are preceded by the '@' |
---|
249 | tag. Take a look at this Doxygen header that declares the arm_raspberrypi |
---|
250 | module, which houses the documentation in the BSP for the Raspberry Pi. |
---|
251 | |
---|
252 | .. code-block:: c |
---|
253 | |
---|
254 | bsps/arm/raspberrypi/include/bsp.h: |
---|
255 | |
---|
256 | /** |
---|
257 | * @defgroup arm_raspberrypi Raspberry Pi Support |
---|
258 | * |
---|
259 | * @ingroup bsp_arm |
---|
260 | * |
---|
261 | * @brief Raspberry Pi support package |
---|
262 | * |
---|
263 | */ |
---|
264 | |
---|
265 | You see a few commands here that we'll cover in the following |
---|
266 | sections. Briefly, the @defgroup command declares a new group, the |
---|
267 | @ingroup command nests this group as a submodule of some other group (in |
---|
268 | this case bsp_arm), and the @brief command provides a brief description |
---|
269 | of what this group is. |
---|
270 | |
---|
271 | The @defgroup Command |
---|
272 | --------------------- |
---|
273 | |
---|
274 | The @defgroup command is used to declare new groups or modules. Think |
---|
275 | "define group". The syntax of this command is as follows: |
---|
276 | |
---|
277 | .. code-block:: c |
---|
278 | |
---|
279 | @defgroup <group name> <group description> |
---|
280 | |
---|
281 | |
---|
282 | The group name is the name used by Doxygen elsewhere to reference this |
---|
283 | group. The group description is what is displayed when the end user |
---|
284 | navigates to this module in the resulting documentation. The group |
---|
285 | description is a couple words formatted as how it would be in a table |
---|
286 | of contents. This part is what actually shows up in the documentation, |
---|
287 | when the user navigates to this group's module, this description will |
---|
288 | be the modules name. |
---|
289 | |
---|
290 | Groups should only be declared (@defgroup) in .h files. This is |
---|
291 | because Doxygen is used primarily to document interfaces, which are |
---|
292 | only found in .h files. Placing @defgroups in .h files is the only real |
---|
293 | restriction. Which .h file you place the group declaration in surprisingly |
---|
294 | doesn't matter. There is no information in the resulting documentation |
---|
295 | that indicates where the group was declared. You will see that we do |
---|
296 | have some rules for where you should place these declarations, but we |
---|
297 | also use this fact that it doesn't matter to our advantage, in order to |
---|
298 | standardize things. |
---|
299 | |
---|
300 | The @defgroup command is used only to define ''structure''. No actual |
---|
301 | documentation is generated as a result of its use. We must @ingroup things |
---|
302 | to the group we declare in order to create documentation. Even though it |
---|
303 | does not generate visible documentation, the @defgroup command is still |
---|
304 | very important. We use it in a way that seeks to emulate the structure |
---|
305 | of the bsps/ directory itself. We do this by creating a hierarchy of |
---|
306 | groups for each CPU architecture and each BSP. |
---|
307 | |
---|
308 | The @ingroup Command |
---|
309 | -------------------- |
---|
310 | |
---|
311 | The @ingroup command is used to add 'things' to already declared |
---|
312 | groups or modules. These 'things' can either be other groups, or files |
---|
313 | themselves. The syntax of the @ingroup command is as follows: |
---|
314 | |
---|
315 | .. code-block:: shell |
---|
316 | |
---|
317 | @ingroup <group name> |
---|
318 | |
---|
319 | |
---|
320 | The group name is the actual name, not description, of the group you |
---|
321 | want to add yourself to. Remember that group name was the second argument |
---|
322 | passed to the @defgroup command. |
---|
323 | |
---|
324 | Using the @ingroup command is how we add ''meaning'' to the ''structure'' |
---|
325 | created by using @defgroup. @ingroup associates the file it is found in |
---|
326 | and all other Doxygen found within (function annotations, prototypes, etc) |
---|
327 | with the group we declared with the @defgroup command. We add related |
---|
328 | files and headers to the same groups to create a logical and cohesive |
---|
329 | body of documentation. If the end user wanted to read documentation |
---|
330 | about how the raspberry pi handles interrupts, all they would have to |
---|
331 | do would be to navigate to the raspberry pi's interrupt support module |
---|
332 | (which we created with a @defgroup command), and read the documentation |
---|
333 | contained within (which we added with @ingroup commands). |
---|
334 | |
---|
335 | @ingroup is found within all Doxygen headers, along with an @brief |
---|
336 | statement. There are two types of Doxygen headers, which we will go over |
---|
337 | after we see a description of the @brief command. |
---|
338 | |
---|
339 | The @brief Command |
---|
340 | ------------------ |
---|
341 | |
---|
342 | The @brief command is used to give either a) a brief description |
---|
343 | in the form of an entry as you would see it in a table of contents |
---|
344 | (i.e. Capitalized, only a couple of words) or b) a brief topic sentence |
---|
345 | giving a basic idea of what the group does. The reason you have two uses |
---|
346 | for the brief command is that it is used differently in the two types of |
---|
347 | Doxygen headers, as we will see shortly. The syntax of the brief command |
---|
348 | is self evident, but included for the sake of completion: |
---|
349 | |
---|
350 | .. code-block:: shell |
---|
351 | |
---|
352 | @brief <Table of Contents entry '''or''' Topic Sentence> |
---|
353 | |
---|
354 | |
---|
355 | The Two Types of Doxygen Headers |
---|
356 | -------------------------------- |
---|
357 | |
---|
358 | There are two types of Doxygen Headers. The first type is found at the |
---|
359 | beginning of a file, and contains an @file command. This type of header |
---|
360 | is used when @ingroup-ing the file into another doxygen group. The form |
---|
361 | of the @brief command in this case is a topic sentence, often very close |
---|
362 | to the file name or one of it's major functions. An example of this type |
---|
363 | of header, found in bsps/arm/raspberrypi/include/bsp.h is as follows: |
---|
364 | |
---|
365 | .. code-block:: c |
---|
366 | |
---|
367 | Header type 1: used to add files to groups, always found at the beginning of a file |
---|
368 | /** |
---|
369 | * @file |
---|
370 | * |
---|
371 | * @ingroup raspberrypi |
---|
372 | * |
---|
373 | * @brief Global BSP definitions. |
---|
374 | */ |
---|
375 | |
---|
376 | /* |
---|
377 | * Copyright (c) YYYY NAME |
---|
378 | * |
---|
379 | * <LICENSE TERMS> |
---|
380 | */ |
---|
381 | |
---|
382 | |
---|
383 | Notice the form and placement of this type of header. It is always found |
---|
384 | at the beginning of a file, and is in its own multiline comment block, |
---|
385 | separated by one line white space from the copyright. If you look at the |
---|
386 | header itself, you see a @file, @ingroup, and @brief command. Consider |
---|
387 | the @file and the @ingroup together, what this says is that we are |
---|
388 | adding this file to the raspberrypi group. There is actually a single |
---|
389 | argument to the @file command, but Doxygen can infer it, so we leave |
---|
390 | it out. Any other Doxygen, function annotations, function prototypes, |
---|
391 | #defines, and other code included in the file will now be visible and |
---|
392 | documented when the end user navigates to the group you added it to in |
---|
393 | the resulting documentation. |
---|
394 | |
---|
395 | Now let's consider the second type of header. This type is syntactically |
---|
396 | very similar, but is used not to add files to groups, but to add groups |
---|
397 | to other groups. We use this type of header to define new groups |
---|
398 | and nest them within old groups. This is how we create hierarchy |
---|
399 | and structure within Doxygen. The following is found, again, in |
---|
400 | bsps/arm/raspberrypi/include/bsp.h: |
---|
401 | |
---|
402 | .. code-block:: c |
---|
403 | |
---|
404 | Header type 2: Used to nest groups, found anywhere within a file |
---|
405 | /** |
---|
406 | * @defgroup arm_raspberrypi Raspberry Pi Support |
---|
407 | * |
---|
408 | * @ingroup bsp_arm |
---|
409 | * |
---|
410 | * @brief Raspberry Pi Support Package |
---|
411 | */ |
---|
412 | |
---|
413 | It looks very similar to the first type of header, but notice that the |
---|
414 | @file command is replaced with the @defgroup command. You can think |
---|
415 | about it in the same way though. Here we are creating a new group, the |
---|
416 | arm_raspberry pi group, and nesting it within the bsp_arm group. The |
---|
417 | @brief in this case should be in the form of how you would see it in a |
---|
418 | table of contents. Words should be capitalized and there should be no |
---|
419 | period. This type of header can be found anywhere in a file, but it is |
---|
420 | typically found either in the middle before the file's main function, |
---|
421 | or at the tail end of a file. Recall that as we are using the @defgroup |
---|
422 | command and creating a new group in this header, the actual .h we place |
---|
423 | this in does not matter. |
---|
424 | |
---|
425 | The second type of header is the **structure** header, it's how we |
---|
426 | create new groups and implement hierarchy. The first type of header |
---|
427 | was the **meaning** header, it's how we added information to the groups |
---|
428 | we created. |
---|
429 | |
---|
430 | For more examples of Doxygen structure and syntax, refer to BSPs found |
---|
431 | within the arm architecture, the lpc32xx and raspberrypi BSPs are |
---|
432 | particularly well documented. A good way to quickly learn more is by |
---|
433 | tweaking some Doxygen in a file, then regenerating the html, and seeing |
---|
434 | what has changed. |
---|
435 | |
---|
436 | Generating Documentation |
---|
437 | ------------------------ |
---|
438 | |
---|
439 | Doxygen is a documentation generator, and as such, we must |
---|
440 | generate the actual html documentation to see the results |
---|
441 | of our work. This is a very good way to check your work, and |
---|
442 | see if the resulting structure and organization was what you had |
---|
443 | intended. The best way to do this is to simply run the `do_doxygen script |
---|
444 | <https://github.com/joelsherrill/gci_tasks/blob/master/2015/doxygen_c_header_tasks/validate/do_doxygen>`_. To use the script: |
---|
445 | |
---|
446 | Make sure Doxygen is installed. Also, the environment needs to have the |
---|
447 | root directory of RTEMS set in the variable `r` so that `$r` prints the |
---|
448 | path to RTEMS, and the script takes as argument a relative directory |
---|
449 | from there to generate the doxygen, for example to generate the doxygen |
---|
450 | for all of bsps/ you would do: |
---|
451 | |
---|
452 | .. code-block:: shell |
---|
453 | |
---|
454 | export r=~/rtems |
---|
455 | ./do_doxygen bsps |
---|
456 | |
---|
457 | Doxygen in bsps/ |
---|
458 | ---------------- |
---|
459 | |
---|
460 | Now that we've covered the basics of Doxygen, the basics of BSPs and the |
---|
461 | structure of the bsps/ directory, actually adding new Doxygen to bsps/ |
---|
462 | will be much easier than it was before. We will cover a set of rules and |
---|
463 | conventions that you should follow when adding Doxygen to this directory, |
---|
464 | and include some tips and tricks. |
---|
465 | |
---|
466 | Group Naming Conventions |
---|
467 | ------------------------ |
---|
468 | |
---|
469 | This is an easy one. These are in place in order for you to quickly |
---|
470 | identify some of the structure of the Doxygen groups and nested groups, |
---|
471 | without actually generating and looking at the documentation. The basic |
---|
472 | idea is this: when defining a new group (@defgroup), the form of the name |
---|
473 | should be the super group, or the name of the group you are nesting this |
---|
474 | group within, followed by an underscore, followed by the intended name |
---|
475 | of this new group. In command form: |
---|
476 | |
---|
477 | .. code-block:: c |
---|
478 | |
---|
479 | <----- This is your group name -------> <--usual description --> |
---|
480 | @defgroup <super-group name>_<name of this group> <group description> |
---|
481 | |
---|
482 | |
---|
483 | Some examples of this: |
---|
484 | |
---|
485 | * **bsp_arm**: This is the group for the arm architecture. It is a |
---|
486 | member of the all inclusive bsp-kit group (more on this in structure |
---|
487 | conventions), so we prefix it with the "**bsp**" super group name. This |
---|
488 | is the group for the arm architecture, so the rest is just "'''arm'''" |
---|
489 | |
---|
490 | * **arm_raspberrypi**: This is the group for the Raspberry Pi BSP. It |
---|
491 | is is an arm board, and as such, is nested within the bsp_arm group. We |
---|
492 | prefix the group name with an "**arm**" (notice we drop the bsp prefix |
---|
493 | of the arm group - we only care about the immediate super group), |
---|
494 | and the rest is a simple "'''raspberrypi'''", indicating this is the |
---|
495 | raspberrypi group, which is nested within the bsp_arm group. |
---|
496 | |
---|
497 | * **raspberrypi_interrupt** This is the group for code handling |
---|
498 | interrupts on the Raspberry Pi platform. Because this code and the group |
---|
499 | that envelops it is Raspberry Pi dependent, we prefix our name with a |
---|
500 | "**raspberrypi**", indicating this group is nested within the raspberrypi |
---|
501 | group.= Structure Conventions = |
---|
502 | |
---|
503 | This covers where, when, and why you should place the second type of |
---|
504 | Doxygen header. Remember that our goal is to have the structure of |
---|
505 | the documentation to match the organization of the bsps/ directory as |
---|
506 | closely as possible. We accomplish this by creating groups for each |
---|
507 | cpu architecture, each BSP, and each shared directory. These groups are |
---|
508 | nested as appropriate in order to achieve a hierarchy similar to that |
---|
509 | of bsps/. The arm_raspberrypi group would be nested within the bsp_arm |
---|
510 | group, for example. |
---|
511 | |
---|
512 | Where to place @defgroup |
---|
513 | ------------------------ |
---|
514 | |
---|
515 | Remember how I said it really doesn't matter where you place the |
---|
516 | @defgroup? Well, it does and it doesn't. It would be chaotic to place |
---|
517 | these anywhere, and almost impossible to tell when you have a @defgroup |
---|
518 | and when you don't, so we do have some rules in place to guide where |
---|
519 | you should place these. |
---|
520 | |
---|
521 | @defgroups for CPU Architectures and Shared Directories |
---|
522 | ------------------------------------------------------- |
---|
523 | |
---|
524 | The standardized place for these is within a special doxygen.h file |
---|
525 | placed within the particular architectures shared directory. This |
---|
526 | doxygen.h file exists solely for this purpose, to provide a standard |
---|
527 | place to house the group definitions for CPU architectures and the |
---|
528 | shared directory for that architecture. This is done because there is |
---|
529 | no single file that all architectures share, so it would be impossible |
---|
530 | to declare a standardized location for architecture declarations without |
---|
531 | the creation of a new file. This also allows others to quickly determine |
---|
532 | if the group for a particular architecture has already been defined or |
---|
533 | not. Lets look at the doxygen.h for the arm architecture as an example, |
---|
534 | found at arm/shared/doxygen.h: |
---|
535 | |
---|
536 | .. code-block:: c |
---|
537 | |
---|
538 | /** |
---|
539 | * @defgroup bsp_arm ARM |
---|
540 | * |
---|
541 | * @ingroup bsp_kit |
---|
542 | * |
---|
543 | * @brief ARM Board Support Packages |
---|
544 | */ |
---|
545 | |
---|
546 | /** |
---|
547 | * @defgroup arm_shared ARM Shared Modules |
---|
548 | * |
---|
549 | * @ingroup bsp_arm |
---|
550 | * |
---|
551 | * @brief ARM Shared Modules |
---|
552 | */ |
---|
553 | |
---|
554 | |
---|
555 | The doxygen.h contains only 2 Doxygen headers, both of which are of |
---|
556 | the second type. One header is used to create the groups for the arm |
---|
557 | architecture **bsp_arm**, nesting it as part of the bsp_kit group, |
---|
558 | and the other creates an **arm_shared** group to house the code that is |
---|
559 | shared across all BSPs of this architecture. Because these are the second |
---|
560 | type of Doxygen header, where we place them does not matter. This allows |
---|
561 | us to place them in a standard doxygen.h file, and the end user is non |
---|
562 | the wiser. Note that this .h file should never be included by a .c file, |
---|
563 | and that the only group declarations that should be placed here are the |
---|
564 | declarations for the CPU Architecture group and the shared group. |
---|
565 | |
---|
566 | There is also a doxygen.h file that exists at the root bsps/shared |
---|
567 | directory, to @defgroup the the parent **bsp_kit** group (the only |
---|
568 | group to not be nested within any other groups) and to @defgroup |
---|
569 | the **bsp_shared** group, to serve as the holder for the bsps/shared |
---|
570 | directory. |
---|
571 | |
---|
572 | If the architecture in which the BSP you are tasked with does not have |
---|
573 | one of these files already, you will need to copy the format of the file |
---|
574 | here, replacing the **arm** with whatever the CPU Architecture you are |
---|
575 | working with is. Name this file doxygen.h, and place it in the shared |
---|
576 | directory for that architecture. |
---|
577 | |
---|
578 | The only groups you should ever add to this CPU group would be groups |
---|
579 | for specific BSPs and a group for the shared directory. |
---|
580 | |
---|
581 | @defgroups for BSPs |
---|
582 | ------------------- |
---|
583 | |
---|
584 | These are much easier than placing @defgroups for CPU Architectures. The |
---|
585 | overwhelming majority of the time, the @defgroup for a BSP is found within |
---|
586 | the bsp.h file found at '''''bsp'''''/include/bsp.h. It is usually placed |
---|
587 | midway through or towards the end of the file. In the event that your |
---|
588 | board lacks a bsp.h file, include this group declaration within the most |
---|
589 | standard or commonly included header for that BSP. |
---|
590 | |
---|
591 | The group for a BSP should **always** be nested within the group for |
---|
592 | the CPU architecture it uses. This means that the Doxygen header for |
---|
593 | defining a BSP group should always look something like this: |
---|
594 | |
---|
595 | .. code-block:: c |
---|
596 | |
---|
597 | /** |
---|
598 | * @defgroup *architecture*_*BSP* *name* |
---|
599 | * |
---|
600 | * @ingroup bsp_*architecture* |
---|
601 | * |
---|
602 | * @brief *BSP* Support Package |
---|
603 | */ |
---|
604 | |
---|
605 | |
---|
606 | @defgroups for Everything Else |
---|
607 | ------------------------------ |
---|
608 | |
---|
609 | Never be afraid to add more structure! Once the basic CPU and BSP group |
---|
610 | hierarchy is established, what we're left with is all the sub directories |
---|
611 | and implementation code. Whether working within a shared directory for |
---|
612 | a CPU architecture, or within a BSP directory, you should always be |
---|
613 | looking for associations you can make to group files together by. Your |
---|
614 | goal should be to avoid @ingroup-ing files directly to the cpu_shared |
---|
615 | group and the cpu_bsp group as much as possible, you want to find more |
---|
616 | groups you can nest within these groups, and then @ingroup files to |
---|
617 | those groups. Here are some things to look for: |
---|
618 | |
---|
619 | Look Common Features Implemented |
---|
620 | -------------------------------- |
---|
621 | |
---|
622 | Remember that list of common features outlined in the BSP Basics |
---|
623 | section? Find the .h's that are responsible for providing the interface |
---|
624 | for these features, and @defgroup a group to @ingroup the files |
---|
625 | responsible for implementing this feature. |
---|
626 | |
---|
627 | RTEMS has a naming convention for its BSP sub directories, so it should |
---|
628 | be a really quick and easy process to determine what features are there |
---|
629 | and what is missing. |
---|
630 | |
---|
631 | Examples of this are found within the **arm_raspberrypi** group, which |
---|
632 | contains nested subgroups like **raspberry_interrupt** to group files |
---|
633 | responsible for handling interrupts, **raspberrypi_usart** to group files |
---|
634 | responsible for implementing USART support, and many other subgroups. |
---|
635 | |
---|
636 | Check out the Makefile |
---|
637 | ---------------------- |
---|
638 | |
---|
639 | When working within a BSP, take a look at the Makefile.am. Often times, |
---|
640 | you will find that the original developer of the code has outlined the |
---|
641 | groups nicely for you already, with comments and titles before including |
---|
642 | source files to be built. Also, this is often the only way to tell which |
---|
643 | features a BSP simply does not implement, and which features a BSP borrows |
---|
644 | from either the architecture's shared group, or the bsps/ shared group. |
---|
645 | |
---|
646 | Start with a .h, and look for files that include it |
---|
647 | --------------------------------------------------- |
---|
648 | |
---|
649 | You should end up with a @defgroup for ''most'' .h files. Some .h files |
---|
650 | are related and will not have independent groups, but most provide |
---|
651 | interfaces for different features and should have their own group |
---|
652 | defined. Declare a group for the header, then use cscope to find the files |
---|
653 | that include this header, and try to determine where the implementation |
---|
654 | code for prototypes are found. These are the files you should @ingroup. |
---|
655 | |
---|
656 | Files with similar names |
---|
657 | ------------------------ |
---|
658 | |
---|
659 | If you see that a few files have similar names, like they are all prefixed |
---|
660 | with the same characters, then these files should most likely be part |
---|
661 | of the same group. |
---|
662 | |
---|
663 | Remember, your goal is to @defgroup as much as you can. The only files |
---|
664 | you should be @ingroup-ing directly to the BSP group or the shared group |
---|
665 | are files that don't cleanly fit into any other group. |
---|
666 | |
---|
667 | Where to place @ingroup |
---|
668 | ----------------------- |
---|
669 | |
---|
670 | The @ingroups you add should make sense. |
---|
671 | |
---|
672 | * If you are working within an architecture's shared directory, @ingroup should be adding things either to the *architecture*_shared group, or some sub group of it. |
---|
673 | |
---|
674 | * If you are working within a BSP directory, @ingroup should be adding things to either the *architecture_*bsp* group, or some sub group of it. |
---|
675 | |
---|
676 | @ingroup in the first type of Doxygen Header |
---|
677 | -------------------------------------------- |
---|
678 | |
---|
679 | Remember that in the first type of Doxygen header, we are adding files |
---|
680 | to groups. This type of header should always be at the top of the |
---|
681 | file. You should be adding files that are associated in some way to |
---|
682 | the same groups. That is to say, if three different .h files provide an |
---|
683 | interface allowing interrupt support, they should be a part of the same |
---|
684 | group. Some good ways to associate files were outlined above. |
---|
685 | |
---|
686 | @ingroup in the second type of Doxygen Header |
---|
687 | --------------------------------------------- |
---|
688 | |
---|
689 | Here we are using the @ingroup command to add groups to other groups, |
---|
690 | creating a hierarchy. The goal for bsps/ is to have one single group that |
---|
691 | holds all other groups. This root group is the **bsp_kit** group. All |
---|
692 | groups should be added either directly to this group (if you are creating |
---|
693 | an architecture group) or added to one of its sub groups. |
---|
694 | |
---|
695 | When nesting groups, try to match the structure of bsps/ as closely as |
---|
696 | possible. For example, if a group is defined to associate all files that |
---|
697 | provide for a real time clock for the raspberrypi, nest it within the |
---|
698 | arm_raspberrypi group. |
---|
699 | |
---|
700 | @ingroup for shared code |
---|
701 | ------------------------ |
---|
702 | |
---|
703 | This is tricky. You may end up in a situation where your BSP uses code |
---|
704 | found in either the architecture shared directory, or the bsps/shared |
---|
705 | directory. Even though this code is logically associated with the BSP, |
---|
706 | as stated above: all files in the shared directory should be added to |
---|
707 | either the *architecture*_shared group, or some subgroup of it ''not'' |
---|
708 | the BSP group. You could make a note under the @brief line in the header |
---|
709 | (which shows up in the resulting documentation) that a particular BSP |
---|
710 | uses this code. |
---|
711 | |
---|
712 | When working with shared code, you should be careful and add notes to |
---|
713 | @brief to indicate that it is a shared code or interface. Prefixing things |
---|
714 | with "Generic" is a good idea here. You will still be able to form groups |
---|
715 | and associate things when working on the shared level, but sometimes you |
---|
716 | will find that you have the interface (.h) to @defgroup, but not many |
---|
717 | files to add to the group as it may be hardware dependent. This is okay. |
---|