123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- -------------------------------------------------------------------------------
- HACKING
- -------------------------------------------------------------------------------
- Coding style
- ------------
- This project is programmed using the Linux kernel coding style, see
- http://lxr.linux.no/linux/Documentation/CodingStyle for details.
- Please use the same style for any code contributions, thanks!
- Contributions
- -------------
- - Patches should be sent to the development mailinglist at
- sigrok-devel@lists.sourceforge.net (please subscribe to the list first).
- https://lists.sourceforge.net/lists/listinfo/sigrok-devel
- - Alternatively, you can also clone the git repository and let us know
- from where to pull/review your changes. You can use gitorious.org,
- github.com, or any other public git hosting site.
- Adding a new hardware driver
- ----------------------------
- The simple, scripted way (recommended):
- ---------------------------------------
- Use the 'new-driver' script from the sigrok-util repo:
- $ git clone git://sigrok.org/sigrok-util
- $ cd sigrok-util/source
- $ ./new-driver "Tondaj SL-814"
- The example above generates a patch file against the current libsigrok
- development git tree which adds a simple "stub" driver for your device
- (the Tondaj SL-814 sound level meter in this case).
- You can apply it like this:
- $ cd libsigrok
- $ git am 0001-tondaj-sl-814-Initial-driver-skeleton.patch
- You can now edit the files in the hardware/tondaj-sl-814 directory as needed
- and implement your driver based on the skeleton files there. That means your
- patch submission later will consist of at least two patches: the initial one
- adding the skeleton driver, and one or more additional patches that actually
- implement the respective driver code.
- The manual way:
- ---------------
- This is a rough overview of what you need to do in order to add a new driver
- (using the Tondaj SL-814 device as example). It's basically what the
- 'new-driver' script (see above) does for you:
- - configure.ac:
- - Add an --enable-tondaj-sl-814 option.
- - Add "hardware/tondaj-sl-814/Makefile" to the AC_CONFIG_FILES list.
- - Add and entry for the device in the "Enabled hardware drivers" list
- at the bottom of the file.
- - hardware/Makefile.am: Add "tondaj-sl-814" to the SUBDIRS variable.
- - hwdriver.c: Add a tondaj_sl_814_driver_info entry in two places.
- - hardware/tondaj-sl-814/ directory: Add the following files:
- Makefile.am, api.c, protocol.c, protocol.h
- See existing drivers or the 'new-driver' output for the details.
- Random notes
- ------------
- - Don't do variable declarations in compound statements, only at the
- beginning of a function.
- - Generally avoid assigning values to variables at declaration time,
- especially so for complex and/or run-time dependent values.
- - Consistently use g_try_malloc() / g_try_malloc0(). Do not use standard
- malloc()/calloc() if it can be avoided (sometimes other libs such
- as libftdi can return malloc()'d memory, for example).
- - Always properly match allocations with the proper *free() functions. If
- glib's g_try_malloc()/g_try_malloc0() was used, use g_free() to free the
- memory. Otherwise use standard free(). Never use the wrong function!
- - Never use g_malloc() or g_malloc0(). These functions do not return NULL
- if not enough memory is available but rather lead to an exit() or segfault
- instead. This behaviour is not acceptable for libraries.
- Use g_try_malloc()/g_try_malloc0() instead and check the return value.
- - You should never print any messages (neither to stdout nor stderr nor
- elsewhere) "manually" via e.g. printf() or g_log() or similar functions.
- Only sr_err()/sr_warn()/sr_info()/sr_dbg()/sr_spew() should be used.
- - Use glib's gboolean / TRUE / FALSE for boolean types consistently.
- Do not use <stdbool.h> and its true / false, and do not invent private
- definitions for this either.
- - Consistently use the same naming convention for #include guards in headers:
- <PROJECTNAME>_<PATH_TO_FILE>_<FILE>
- This ensures that all #include guards are always unique and consistent.
- Examples: LIBSIGROK_LIBSIGROK_H, LIBSIGROK_HARDWARE_MIC_985XX_PROTOCOL_H
- - Consistently use the same naming convention for API functions:
- <libprefix>_<groupname>_<action>().
- Examples:
- sr_log_loglevel_set(), sr_log_loglevel_get(), sr_log_handler_set(),
- sr_log_handler_set_default(), and so on.
- Or:
- sr_session_new(), sr_session_destroy(), sr_session_load(), and so on.
- Getter/setter function names should usually end with "_get" or "_set".
- Functions creating new "objects" should end with "_new".
- Functions destroying "objects" should end with "_destroy".
- Functions adding or removing items (e.g. from lists) should end with
- either "_add" or "_remove".
- Functions operating on all items from a list (not on only one of them),
- should end with "_all", e.g. "_remove_all", "_get_all", and so on.
- Use "_remove_all" in favor of "_clear" for consistency.
- - All enums should generally use an explicit start number of 10000.
- If there are multiple "categories" in the enum entries, each category
- should be 10000 entries apart from the next one. The start of categories
- are thus 10000, 20000, 30000, and so on.
- Adding items to an enum MUST always append to a "category", never add
- items in the middle of a category. The order of items MUST NOT be changed.
- Any of the above would break the ABI.
- The enum item 0 is special and is used as terminator in some lists, thus
- enums should not use this for "valid" entries (and start at 10000 instead).
- Doxygen
- -------
- - In Doxygen comments, put an empty line between the block of @param lines
- and the final @return line. The @param lines themselves (if there is more
- than one) are not separated by empty lines.
- - Mark private functions (SR_PRIV) with /** @private */, so that Doxygen
- doesn't include them in the output. Functions that are "static" anyway
- don't need to be marked like this.
- - Mark private variables/#defines with /** @cond PRIVATE */ and
- /** @endcond */, so that Doxygen doesn't include them in the output.
- Variables that are "static" don't need to be marked like this.
- - Mark all public API functions (SR_API) with a @since tag which indicates
- in which release the respective function was added (e.g. "@since 0.1.0").
- If the function has existed before, but its API changed later, the @since
- tag should mention only the release when the API last changed.
- Example: The sr_foo() call was added in 0.1.0, but the API changed in
- the later 0.2.0 release. The docs should read "@since 0.2.0" in that case.
- Non-public functions (static ones, and those marked SR_PRIV) don't need
- to have @since markers.
- The @since tag should be the last one, i.e. it should come after @param,
- @return, @see, and so on.
- Testsuite
- ---------
- You can run the libsigrok testsuite using:
- $ make check
- Release engineering
- -------------------
- See
- http://sigrok.org/wiki/Developers/Release_process
- for a list of items that need to be done when releasing a new tarball.
|