Revision: 1425 Author: sebastien.lelong Date: Wed Oct 28 23:56:59 2009 Log: DITAfied JSG http://code.google.com/p/jallib/source/detail?r=1425
Added: /trunk/doc/dita/development /trunk/doc/dita/development/jsg.xml ======================================= --- /dev/null +++ /trunk/doc/dita/development/jsg.xml Wed Oct 28 23:56:59 2009 @@ -0,0 +1,287 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This document was created with Syntext Serna Free. --><!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd" []> +<topic id="template_id"> + <title>Jallib Style Guide</title> + <shortdesc><b>Jallib Style Guide</b> (JSG) defines the standards used to write jalv2 code.</shortdesc> + <prolog> + <author>Jallib Team</author> + <publisher>Jallib Group</publisher> + </prolog> + <topic id="another"> + <title>Why ?</title> + <body> + <p>There're many ways to write code, whatever the programming language is. Each language has its preferences. For instance, java prefers <i>CamelCase</i> whereas python prefers <i>underscore_lowercase</i>.</p> + <p>While this seems a real constraint, not necessarily needed, it actually helps a lot while sharing code with everyone: it improves <b>readability</b>, and readability is important because code is read much more often than it is written.</p> + <p>Finally, more than a howto write code, this guide is here to help you not forget things like <i>author(s)</i>, <i>licence</i>, and remember you some basic principles.</p> + </body> + </topic> + <topic id="headers"> + <title>Headers in library</title> + <body> + <p>Every jal files published on jallib repository<fn>This is the same for other jalv2 and jallib related projects, like Jaluino.</fn> must have the following headers (comments), as the very beginning of the file:</p> + <p><codeblock>-- Title: [title, very small description if needed] +-- Author: [author's name], Copyright (c) YEAR..YEAR, all rights reserved. +-- Adapted-by: [adapters' name, comma seperated] +-- Compiler: [specify which version of compiler is needed. Ex: >=2.4g, =2.3, ???] +-- +-- This file is part of jallib (http://jallib.googlecode.com) +-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php) +-- +-- Sources: [ if relevant, specify what sources of informations you use: website, article, specifications, appnotes, etc... ] +-- +-- Description: [describe what is the functional purpose of this lib] +-- +-- Notes: [put here information not related to functional description] +-- + +[code start here...]</codeblock></p> + <p>The <b>author</b> is the original author's name. The library may have been modified and adapted by <b>adapters</b>. The <b>compiler</b> helps readers to know which compiler version has been used to test this file (no space between operator and version: >=2.4g). <b>sources</b>, <b>description</b> and <b>notes</b> fields must be followed by an empty line (just <codeph>--</codeph>) to declare the end of the field content. As a consequence, those fields cannot have empty lines within them.</p> + <p>Example:</p> + <p><codeblock>-- Title: USART hardware control +-- Author: Stef Mientki, Copyright (c) 2002..2008, all rights reserved. +-- Adapted-by: Sebastien Lelong, Someone Else +-- Compiler: >=2.4g +-- +-- This file is part of jallib (http://jallib.googlecode.com) +-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php) +-- +-- Description: Routines for sending and receiving through the PIC-usart, +-- both RS232 and SPI are supported (for SPI see spi_hardware.jal) +-- Baudrate can simply be set through a human constant, +-- because the baudrate depending registers are calculated by this unit. +-- Baudrate is calculated, starting at the high baudrate flag, +-- which will ensure the highest possible accuracy. +-- -- +-- SPI routines are setup for more SPI-devices, +-- in which case CS should be controled outside this unit. +-- +-- Sources: excellent article on USART: http://www.google.fr/search?q=usart +-- +-- Notes: an incredible note +--</codeblock></p> + <p><note>if you need to create a new paragraph within a multiline field, use the "<codeph>--</codeph>" special chars. See example in Description field: "<codeph>SPI routines ...</codeph>" is part of the Description field, but visually seperated from the beginning of the field content.</note></p> + <p>In the <filepath>/tools</filepath> directory jallib SVN repository, you'll find <cmdname>jallib.py</cmdname>. Amongst many things, you can run "<cmdname>validate</cmdname>" action, and check lots of JSG requirements. You can (must) use it to make sure your jal files are JSG compliant. This script will help you to identify problems:</p> + <p>Example:</p> + <p><screen>bash$ python jallib.py validate my_file.jal + +File: my_file.jal +6 errors found + ERROR: Cannot find references to jallib (should have: '^-- This file is part of jallib\\s+\\(http://jallib.googlecode.com\\)') + ERROR: Cannot find references to license (should have: '^-- Released under the BSD license\\s+\\(http://www.opensource.org/licenses/bsd-license.php\\)') + ERROR: Cannot find field Title (searched for '^-- Title:\s*(.*)') + ERROR: Cannot find field Author (searched for '^-- Author:\s*(.*)') + ERROR: Cannot find field Compiler (searched for '^-- Compiler:\s*(.*)') + ERROR: Cannot find field Description (searched for '^-- Description:\s*(.*)') + +0 warnings found</screen></p> + </body> + </topic> + <topic id="rules"> + <title>Rules Of Thumb</title> + <topic id="fvpnc"> + <title>Filenames, variables, procedures naming convention</title> + <body> + <section> + <title>Filenames</title> + <p>A library must be named as:<ul> + <li><filepath><function>_<implementation| other>.jal</filepath> for PIC-specific libraries (peripherals). <i>function</i> gives clues about what the library is about. Then <i>implementation</i> or <i>other</i> is here to differentiate libraries, and is more about implementations (<filepath>serial_hardware.jal</filepath>, <filepath>serial_software.jal</filepath>), things specific to the function (<filepath>pwm_ccp1.jal</filepath>, <filepath>pwm_ccp2.jal</filepath>, ...).<p>Ex: <filepath>serial_hardware.jal</filepath>, <filepath>serial_software.jal</filepath>, <filepath>pwm_ccp1.jal</filepath>.</p></li> + <li><filepath><device-family>_<device>.jal</filepath> for external libraries. <i>device-family</i> describes the device family (...), and is often the directory name where the lib is. <i>device</i><p>Ex: <filepath>lcd_hd44780_4.jal</filepath>, <filepath>rtc_ds1302.jal</filepath>, <filepath>co2_t6603.jal</filepath></p> precisely sets the part.</li> + </ul></p> + </section> + <section> + <title>Constants, variables, procedures, functions</title> + <p>All <b>external names</b> (of global variables, constants, procedures and functions available to application programs) <b>must</b> start with a prefix unique to the library. Names of other global entities (not supposed being used by application programs) should use this prefix and use an additional underscore at the beginning.</p> + <p>Variables, constants, procedures and functions must be named as:<ul> + <li><codeph><device>_<whatever></codeph> if you want to avoid namespace collision</li> + <li><codeph><device-family>_<whatever></codeph> if you want to have a common API</li> + </ul></p> + <p>For example, <filepath>co2_t6603.jal</filepath> library have all its procedures starting with <codeph>t6603_</codeph> (and <codeph>_t6603_</codeph> for internal names). This makes all these procedures very specific to this library. If you have another CO2 sensor, you'll be able to use both at the same time, because they'll be no namespace collision. This is the purpose of the <codeph><device>_<whatever></codeph> naming convention.</p> + <p>Another example: the names of the procedures in the LCD libaries start with <codeph>lcd_</codeph> (and <codeph>_lcd_</codeph> for internal names). There are many different LCD types, but all implements the same API, because procedures, variables, etc... are named according to the device-family, not the device itself. This is the purpose of the <codeph><device-family>_<whatever></codeph> naming convention.</p> + <p>Now, how do you know which to follow ? Ask, we'll discuss...</p> + <note>following the same principle, naming const/var/procdecure/function in a PIC-specific libraries (peripherals) can include the <i>function</i> and/or the <i>implementation</i>. This depends whether you want to have more than one function within a same PIC.</note> + <p>Ex: There are two implementations of i2c and serial: hardware and software. Having both i2c implementation within a same PIC is not useful, since i2c is adressable. Thus, all const/var/... are prefixed by <filepath>i2c_<whatever>.jal</filepath>. On the contrary, it can be useful to have two serial implementation within a same PIC (eg. one talking a PIC, another talking to a external device). Thus, serial libs' const/var/... are prefixed by <filepath>serial_hw_<whatever>.jal</filepath> or <filepath>serial_sw_<whatever>.jal</filepath>. +</p> + </section> + <section> + <title>Pin names</title> + <p>The pins are named as:<ul> + <li><codeph><device>_<external_pin_name></codeph> if you want to avoid namespace collision</li> + <li><codeph><device-family>_<external_pin_name></codeph> if you want to have a common API</li> + </ul></p> + <p>This is almost the same as for variables, contants, ... except the <codeph><whatever></codeph> part now corresponds the pin name of the external device (usually found in datasheets). Using the <codeph><device-family>_<external_pin_name></codeph> convention to build a common API may cause problems, if pin names aren't named the same in all supported devices. In that case, the pin name should be as explicit as possible...</p> + <note type="important">See also the very important rules about pin names within a library: <xref href="#duppn">"Don't use port and pin names"</xref></note> + </section> + <section> + <title>Samples and tests</title> + <p>Tests are named as <filepath>test_<whatever>.jal</filepath>. That is, they should starts with the prefix <filepath>test_</filepath>. That is, samples must not start with <filepath>test_</filepath>.</p> + <p>Board files are named as <filepath>board_<pic>_<whatever>.jal</filepath></p> + <p>Samples are named as <filepath><pic>_<whatever>.jal</filepath></p> + <p><filepath><whatever></filepath> can be whatever, but should give users hints about what the sample is (eg. <filepath>16f88_serial_hardware.jal</filepath>)</p> + </section> + <section> + <title>Why such a pain ?...</title> + <p>The main purpose of this is to control the naming conflicts between libraries and application code. Bear in mind that this is about source-level libraries which are combined by the compiler to form a single application program.</p> + <p>Having naming convention is also a great optimize process, saving time, by scripting and generating code. This is good.</p> + </section> + </body> + </topic> + <topic id="duppn"> + <title>Don't use port and pin names</title> + <body> + <p><b>Don't use port and pin names</b> like <codeph>portA</codeph> or <codeph>pin_a5</codeph> in your great library, because someone may (will) want to use your library on another port or pin. It also helps to make your great library PIC independent.</p> + <p><b>Name your pins according to the context</b>, to what your library is doing. Client code, ie. users, will have to define those variables before actually include your great library.</p> + <p><b>Let the user set the pin directions, except if the library is supposed to modify direction during execution</b>.</p> + <p>Ex: how to use your library (doing amazing things with the GP2D02 IR ranger)</p> + <p><codeblock>-- declare in/out pins for the ranger +alias ranger_pin_in is pin_A0 +alias ranger_pin_out is pin_A1</codeblock></p> + <p>and make sure the pins work as required:</p> + <p><codeblock>-- specify the direction of the pins +-- Since directions won't change during execution, this is +-- done here, during the setup, before including the library +pin_A0_direction = input +pin_A1_direction = output</codeblock></p> + <p>and now include the library:</p> + <p><codeblock>-- now include the library which uses ranger_pin_in and ranger_pin_out +include gp2d02 -- ranger library </codeblock></p> + <p><i>Exception</i>: if your library uses a special PIC feature, it may use the name defined in the device files / datasheet. Not so much an exception, as you'll use the pin name given the context (feature, peripheral)no</p> + <note>syntax "<codeph>var ... is ...</codeph>" is now deprecated in favor of "<codeph>alias ... is ...</codeph>" and must not be used anymore. "<codeph>alias</codeph>" keyword is more powerful as it allows to create synonyms for any type of names (variables, constants, procedures, functions, psdeudo-variables)</note> + <p>Ex: a i2c hardware library (using built-in PIC i2c) may refer to SCK and SDA. Those pin names are set into the device include file (prefixed with the portname!).</p> + </body> + </topic> + <topic id="luil"> + <title>Let the user initialize the library</title> + <body> + <p>Most of the time, a library needs to configured (you define variables/constants before including the file), then initialized (you call <codeph><libname>_init()</codeph>). While having the init step automatically called when the library is called can be convenient, this results in a lack of flexibility. Indeed, you may want to initialize one library or the other, or initialization step can take quite a long time, so you want to have control about when you can "waste" such time.</p> + <p>So, <b>a library must never call its own init procedures, the user will</b>. And the init procedure must be named either as <codeph><device>_init</codeph> or <codeph><function>_init</codeph>, whether you want to avoid namespace collision, or on the contrary, if you want to have different implementation for the same API (see rules about naming convention above).</p> + </body> + </topic> + <topic id="awdvil"> + <title>Avoid weird default values in library</title> + <body> + <p><b>Don't put default values in your library</b>, someone may (will) have a different opinion about what's a <i>default value</i>. Even if it's tempting because it can save time writing the same value again and again. Remember, your library is to be shared, nasty default value can be a real obstacle using it...</p> + </body> + </topic> + <topic id="we"> + <title>Write examples</title> + <body> + <p><b>Write examples</b> to show the world how to use your great library. Without it, people may (will) not use your library, because it's too complicated and time-consuming reading code to actually discover what it does. Also remember writing examples can help you to design a usable, simple and clear API.</p> + </body> + </topic> + <topic id="assembler"> + <title>Assembler</title> + <body> + <p>Avoid the use of inline Assembler. If you cannot do without it use <b>standard asm opcodes</b> and avoid nasty Assembler statements. So:</p> + <p><b>Good</b>:</p> + <p><codeblock>btfsc STATUS_Z</codeblock></p> + <p><b>Bad</b>:</p> + <p><codeblock>skpnz</codeblock></p> + </body> + </topic> + <topic id="warnerr"> + <title>Warnings are errors...</title> + <body> + <p>Don't be tempted to ignore warnings. <b>Consider warnings as errors</b>, until you've completely understand why there should be a warning (or not). Warnings can mask more relevant warnings and errors, so track them and try to avoid them. <b>A library should compile without any warnings... if possible</b>.</p> + </body> + </topic> + </topic> + <topic id="codelayout"> + <title>Code Layout</title> + <body> + <section> + <title>Indent your code</title> + <p>It helps following the code structure (flows). Code must be indented using 3 spaces (no tab). You can use <cmdname>python jallib.py reindent <file.jal></cmdname> for this.</p> + <p><b>Good</b>:</p> + <p><codeblock>var byte char +forever loop + if serial_hw_read(char) then + echo(char) + end if +end loop</codeblock></p> + <p><b>Bad</b>:</p> + <p><codeblock>var byte char +forever loop +if serial_hw_read(char) then +echo(char) +end if +end loop</codeblock></p> + </section> + <section> + <title>Use lower_case_with_underscores ...</title> + <p><b>Good</b>:</p> + <p><codeblock>var byte this_is_a_variable +var byte another_one</codeblock></p> + <p><b>Bad</b>:</p> + <p><codeblock>var byte ThisIsAVariable +var byte Another_One</codeblock></p> + </section> + <section> + <title>... except for constants</title> + <p>Uppercase variables should be used for constants, internal PIC function registers or for external PIN names, if they are uppercase in the datasheet as well.</p> + <p><b>Good</b>:</p> + <p><codeblock>const RESET_CHAR = "*" +SSPCON1_CKP = 1</codeblock></p> + <p><b>Bad</b>:</p> + <p><codeblock>const reset_CHAR = "*" +sspCON1_Ckp = 1</codeblock></p> + </section> + <section> + <title>Be explicit when calling procedures and functions</title> + <p>When a procedure (or a function) does not take any parameters, be explicit and help your readers: put parenthesis so everyone knows it's a call. Same when defining the function/procedures. Also note no space is allowed between the procedure/function name and the opening parenthesis. Finally, pseudo-variable must be defined with parenthesis, but not when used (heh, these are functions/procedures behaving like variables !).</p> + <p><b>Good</b>:</p> + <p><codeblock>-- Defining +procedure do_it_please() is + -- I will do it +end procedure + +-- Calling +do_it_please() + +-- pseudo-var +function my_pseudo_var'get() return byte is + -- I promise I'll do it +end function + +var byte what = my_pseudo_var</codeblock></p> + <p><b>Bad</b>:</p> + <p><codeblock>procedure do_it_again is + -- this is bad +end procedure + +do_it_again + +function my_pseudo_var'get () return byte is + -- this is bad, too because there's a space ! +end procedure</codeblock></p> + </section> + <section> + <title>Filenames are lowercased, includes statements too</title> + <p>All jal files must be lowercased. So:</p> + <p><b>Good</b>:</p> + <p><screen>$ ls 16f88.jal</screen></p> + <p><b>Bad</b>:</p> + <p><screen>$ ls 16F88.jal</screen></p> + <p>Being consistent, include statements are lowercased, too:</p> + <p><b>Good</b>:</p> + <p><codeblock>include 16f88</codeblock></p> + <p><b>Bad</b>:</p> + <p><codeblock>include 16F88</codeblock></p> + </section> + <section> + <title>Inform readers what should be considered private</title> + <p>Functions, procedures, variables, etc... starting with an underscore is warning to users saying "you shouldn't use me, I'm for internal use only". Play carefully with this, remember users are quite curious and may want them anyway :)</p> + </section> + <section> + <title>Comment your code</title> + <p>It helps readers understand what's going on. The comment should describe <b>why</b> your code does its thing, not what is does. That should be obvious from the code itself.</p> + </section> + </body> + </topic> + <topic id="externaldata"> + <title>External data</title> + <body> + <p>When developing a library, you may need to collect and organize external / 3rd party data. For instance, the relation between a datasheet reference and the PICs described in this datasheet is what we call external data: it's not jal code, but <i>often</i> used to generate some, and <i>always</i> a source of information everyone can refer too.</p> + <p>External data must store in a <b>structured format</b> so everyone potentially is able to use it. Before we, developers, are also (kind of) humans, we want this format to be readable, and even writable, but also structured enough so a computer can also use and exploit it. That's why this format is <xref href="http://www.json.org/" format="html">JSON</xref> (and not XML), which is available in many languages. This is a way to share information, amongst the many scripts used to deal jal code base.</p> + </body> + </topic> +</topic> --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jallib" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jallib?hl=en -~----------~----~----~----~------~----~------~--~---
