From 0e65ce62afe05e6ae04cb13fad5e853d0b9cee44 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 8 May 2013 12:23:25 +0700 Subject: [PATCH] documenting on the way --- docs/images/what_is_tinyusb.png | Bin 0 -> 43212 bytes readme.md | 79 ++++++++++++++++++++------------ tests/readme.md | 7 ++- 3 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 docs/images/what_is_tinyusb.png diff --git a/docs/images/what_is_tinyusb.png b/docs/images/what_is_tinyusb.png new file mode 100644 index 0000000000000000000000000000000000000000..3064d7d4faf55cad8435540d4c4d86be76733a78 GIT binary patch literal 43212 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 Z+*TlZA^Fb-fpfs0wz|Grxr)v6{{iK-j!Xam literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index a57822941..34e0520c8 100644 --- a/readme.md +++ b/readme.md @@ -2,21 +2,13 @@ ## What Is tinyusb ## -tinyusb is an open-source (BSD-licensed) USB Host/Device/OTG stack for embedded micro-controller. It is developed using [Test-Driven Development](tests/readme.md) approach to eliminate bugs as soon as possible. +tinyusb is an open-source (BSD-licensed) USB Host/Device/OTG stack for embedded micro-controller. It is developed using [Test-Driven Development (TDD)](tests/readme.md) approach to eliminate bugs as soon as possible. -More detail on TDD can be found at - -- [James W. Grenning's book "Test Driven Development for Embedded C"](http://www.amazon.com/Driven-Development-Embedded-Pragmatic-Programmers/dp/193435662X) -- [throwtheswitch's Ceedling, CMock & Unity](http://throwtheswitch.org/) +![tinyusb diagram](/docs/images/what_is_tinyusb.png) ## Features ## -### RTOS ### - -tinyusb is designed to be OS-ware and run across OS vendors, thanks to its OS Abstraction Layer (OSAL). However, it can also run without an OS (OSAL will be expanded to be a state machine in this case). Currently the following OS can be run with tinyusb (out of the box). - -- **None OS** -- **FreeRTOS** +designed to be simple and run out-of-the-box provided the configuration is correct. ### Host ### @@ -30,27 +22,12 @@ tinyusb is designed to be OS-ware and run across OS vendors, thanks to its OS Ab coming soon ... -## Coding Standards ## +### RTOS ### -tinyusb make use of goodies features of C99, which saves a tons of code lines (also means save a tons of bugs). However, those features can be misused (plus C is a dangerous language by itself) and pave the way for bugs sneaking into. Therefore, to minimize bugs, the author try to comply with published Coding Standards like: +tinyusb is designed to be OS-ware and run across OS vendors, thanks to its OS Abstraction Layer (OSAL). However, it can also run without an OS (OSAL will be expanded to be a state machine in this case). Currently the following OS can be run with tinyusb (out of the box). -- [MISRA-C](http://www.misra-c.com/Activities/MISRAC/tabid/160/Default.aspx) -- [Power of 10](http://spinroot.com/p10/) -- ... - -### MISRA-C 2004 Exceptions ### - -MISRA-C is well respected & a bar for industrial coding standard. Where is possible, MISRA-C is followed but it is almost impossible to follow the standard without the following exceptions: - -- **Rule 2.2: use only /*** It has long passed the day that C99 comment style // will cause any issues, especially compiler's C99 mode is required to build tinyusb. I think they will eventually drop this rule in upcoming MISRA-C 2012. -- **Rule 8.5: No definitions of objects or function in a header file** function definitions in header files are used to allow 'inlining' -- **Rule 14.7: A function shall have a single point of exit at the end of the function** Unfortunately, following this rule will have a lot of nesting if-else, I prefer to exit as soon as possible with assert style and flatten if-else. -- **Rule 18.4: Unions shall not be used** sorry MISRA, union is required to effectively mapped to MCU's registers -- expect to have more & more exceptions. - -### Power of 10 Exceptions ### - -- coming soon +- **None OS** +- **FreeRTOS** ## Is It Ready ## @@ -77,6 +54,48 @@ this code base can run out of the box with the following boards - [Embedded Artists LPC4357 OEM & Base board](http://www.embeddedartists.com/products/kits/lpc4357_kit.php) - [NGX Technologies LPC4330 Explorer](http://shop.ngxtechnologies.com/product_info.php?products_id=104) +## Coding Standards ## + +C is a dangerous language by itself, plus tinyusb make use of goodies features of C99, which saves a tons of code lines (also means save a tons of bugs). However, those features can be misused and pave the way for bugs sneaking into. Therefore, to minimize bugs, the author try to comply with published Coding Standards like: + +- [MISRA-C](http://www.misra-c.com/Activities/MISRAC/tabid/160/Default.aspx) +- [Power of 10](http://spinroot.com/p10/) +- [Jet Propulsion Laboratory (JPL) for C](http://lars-lab.jpl.nasa.gov) +- ... + +Where is possible, standards are followed but it is almost impossible to follow all of these without making some exceptions. I am pretty sure this code base violates more than what are described below, if you can find any, please report it to me or file an issue on github. + +### MISRA-C 2004 Exceptions ### + +MISRA-C is well respected & a bar for industrial coding standard. + +- **Rule 2.2: use only /*** It has long passed the day that C99 comment style // will cause any issues, especially compiler's C99 mode is required to build tinyusb. I think they will eventually drop this rule in upcoming MISRA-C 2012. +- **Rule 8.5: No definitions of objects or function in a header file** function definitions in header files are used to allow 'inlining' +- **Rule 14.7: A function shall have a single point of exit at the end of the function** Unfortunately, following this rule will have a lot of nesting if-else, I prefer to exit as soon as possible with assert style and flatten if-else. +- **Rule 18.4: Unions shall not be used** sorry MISRA, union is required to effectively mapped to MCU's registers +- expect to have more & more exceptions. + +### Power of 10 ### + +is a small & easy to remember but yet powerful coding guideline. Most (if not all) of the rules here are included in JPL. Because it is very small, all the rules will be listed here, those with bold is compliant, italic is violated. + +1. **Restrict to simple control flow constructs:** yes, I hate goto statement, therefore there is none of those here +2. **Give all loops a fixed upper-bound:** one of my favorite rule +3. **Do not use dynamic memory allocation after initialization:** +the tinyusb uses the static memory for all of its data. +4. *Limit functions to no more than 60 lines of text:* 60 is a little bit too strict, I will update the relaxing number later +5. **Use minimally two assertions per function on average:** not sure the exact number, but I use a tons of those assert +6. **Declare data objects at the smallest possible level of scope:** one of the best & easiest rule to follow +7. **Check the return value of non-void functions, and check the validity of function parameters:** I did check all of the public application API's parameters. For internal API, calling function needs to trust their caller to reduce duplicated check. +8. *Limit the use of the preprocessor to file inclusion and simple macros* Although I prefer inline function, however C macros are far powerful than that. I simply cannot hold myself to use, for example X-Macro technique to simplify code. +9. **Limit the use of pointers. Use no more than two levels of dereferencing per expression:** never intend to get in trouble with complex pointer dereferencing. +10. **Compile with all warnings enabled, and use one or more source code analyzers:** I try to use all the defensive option of gnu, let me know if I miss some. +> -pedantic -Wextra -Wswitch-default -Wunsafe-loop-optimizations -Wcast-align -Wlogical-op -Wpacked-bitfield-compat -Wpadded -Wnested-externs -Wredundant-decls -Winline -Wpacked + +### JPL ### + +coming soon ... + ## How Can I Help ## If you find my little USB stack is useful, please take some time to file any issues that you encountered. It is not necessary to be a software bug, it can be a question, request, suggestion etc. We can consider each github's issue as a forum's topic. Alternatively, you can buy me a cup of coffee if you happen to be in Hochiminh city. diff --git a/tests/readme.md b/tests/readme.md index 0602a6dc8..0ed3b1e6f 100644 --- a/tests/readme.md +++ b/tests/readme.md @@ -1,3 +1,8 @@ # Test-Driven Development (TDD) # -TDD indeed works with C & embedded with the help of Ceedling, Unity & CMock as a testing framework. +TDD indeed works with C & embedded with the help of Ceedling, Unity & CMock as a testing framework. + +More detail on TDD can be found at + +- [James W. Grenning's book "Test Driven Development for Embedded C"](http://www.amazon.com/Driven-Development-Embedded-Pragmatic-Programmers/dp/193435662X) +- [throwtheswitch's Ceedling, CMock & Unity](http://throwtheswitch.org/)