Archives

Page Ranking

CoOS Real Time Kernel (CooCox.org) – Part 2

As I noted in my previous posting, CoOS was initially intended for ARM Cortex M3 and M0 architecture. With a bit of work CoOS can be ported on the popular ARM7 as well. The authors assume that the development is done using the following tool chains: Keil, IAR and GCC. The CooCox CoBuilder is an internet-based component-oriented embedded development platform that is based on GCC. It is somewhat similar with LPCXpresso which is an Eclipse-based IDE, a GNU C compiler, linker, libraries, and a GDB debugger all hosted online with the exception of the front-end client that requires local installation. The same thing applies to CoBuilder.

Personally, I appreciate more the offline tools because I’m a control freak and because of the speed and comfort of my own setup but I must admit that having access to your projects online is an attractive option, especially for people on the go; plus the peace of mind that your project is hosted on a server in a data center where reliability and safety should be the norm.

The code style is clean without being pedantic. Personally, I would use a more strict naming convention but, without doubt, CoOS code uses meaningful names for functions, variables and constants that makes the code readable. I would also argue for a longer source line — with the wide screen monitors available today a 100…120 character line size would make a lot of sense.

Comments are formatted for Doxygen (a documentation system for C++, C, Java, etc. that extracts the information from commented source files).

Each module (i.e. source file) begins with a comment block clearly stating the version number, name, date, description:

/**
 *******************************************************************************
 * @file       core.c
 * @version    V1.12
 * @date       2010.03.01
 * @brief      Core implementation code of CooCox CoOS kernel.
 *******************************************************************************
 * @copy
 *
 * INTERNAL FILE,DON'T PUBLIC.
 *
 * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
 *******************************************************************************
 */

Each function is preceded by its own comment block describing the purpose, input and output parameters, return value and notes:

/**
 *******************************************************************************
 * @brief      Enter a ISR.
 * @param[in]  None
 * @param[out] None
 * @retval     None
 *
 * @par Description
 * @details    This function is called to notify OS when enter to an ISR.
 *
 * @note       When you call API in ISR,you must call CoEnterISR() before your
 *             interrupt handler code,and call CoExitISR() after your handler
 *             code and before exiting from ISR.
 *******************************************************************************
 */
void CoEnterISR (void)
{
    . . . . .
}

I like the trailing comments used almost everywhere in the code — they bring clarity separating the code from the story. However, the short line length (~80 characters) makes this task difficult: one more reason for a long line.

void CoStartOS (void)
{
    TCBRunning  = &TCBTbl[0];          /* Get running task                        */
    TCBNext     = TCBRunning;          /* Set next scheduled task as running task */
    TCBRunning->state = TASK_RUNNING;  /* Set running task status to RUNNING      */
    RemoveFromTCBRdyList(TCBRunning);  /* Remove running task from READY list     */
    OsSchedUnlock();                   /* Enable Schedule, call task schedule     */
}

The code uses portable data types, a good practice to achieve portability but a bit more difficult when it comes to reconcile them with your own type definitions. However, many embedded software developers agree that portable data types are a necessity in order to avoid hard to find problems when the code is moved from one CPU to another (especially if they differ in word size). Here is an example of portable data types used in CoOS.

typedef signed char        S8;
typedef unsigned char      U8;
typedef short              S16;
typedef unsigned short     U16;
typedef int                S32;
typedef unsigned int       U32;
typedef long long          S64;
typedef unsigned long long U64;
typedef unsigned char      BOOL;

I used similar definitions for years (e.g. UINT8, UINT16, UINT32, BOOLEAN, etc.). As one can see they are similar, except the names. For compatibility with my own code I use either macros or derived types to reconcile the two definition sets. For example:

typedef SINT8              S8;
typedef UINT8              U8;
typedef SINT16             S16;
typedef UINT16             U16;
typedef SINT32             S32;
typedef UINT32             U32;
typedef SINT64             S64;
typedef UINT64             U64;
#define BOOL               bool  // available with a C99 compiler

I will end here my comments regarding style. The next postings will reflect my struggles to put this RTOS to work. So, don’t expect any particular order.

4 comments to CoOS Real Time Kernel (CooCox.org) – Part 2

  • Adriano Prado

    According to the CooCox CoOS page, it will take less than 1K for the Kernel code, and about 200K of RAM!
    With such small footprint I think it beats FreeRTOS for devices with low memory space, like the LPC210x.
    Now I’m just wondering if the support will be as good as in FreeRTOS, but I think it’s worth to check. I hope you post your findings about it soon (specially if you port it to ARM7).

    Regards.

  • admin

    Here is the reality: if you need all the available features, then the size can be ~10 KB. If you keep everything minimal the size reduces to ~2.5 KB but you will be limited to multitasking without inter-task communication and synchronization. If you add semaphores (more realistic) the code size will be ~4 KB and ~500 B of data (depending of number of tasks, semaphores, etc.) Expect about 20…30% code size reduction if you enable full optimization in the compiler. Still not 1 KB!
    But I agree that FreeRTOS may require a bit more code space without so many features that CoOS offers. There are other options for really small RTOS preemptive kernels but don’t expect miracles.

    In the list below you will find each module and its size (IAR EWARM 5.30, no optimization, CPU is Cortex M3):


    Module..........Code........Data........Const
    arch............222.........12..........0
    core............418.........3...........0
    event...........718.........164.........0
    flag............1538........20..........0
    hook............4...........0...........0
    kernelHeap......716.........212.........0
    mbox............480.........0...........0
    mm..............548.........36..........0
    mutex...........674.........81..........0
    portForM3.......120.........0...........0
    queue...........762.........36..........0
    sem.............452.........0...........0
    serviceReq......308.........71..........0
    task............1640........520.........0
    time............676.........4...........0
    timer...........1220........56..........0
    utility.........158.........0...........0
    Total...........10654.......1215........0

    It is possible that the code can be ported on ARM7 but this requires a bit of work and my time is limited for the moment. However, CoOS authors may have this in plan anyway. Keep an eye on this site or coocox.org for news.

    Good luck!

  • LeQ

    At first, I’m really looking forward to read your next article about this OS. I checked out the Webpage of CooCox, and it seems to be interesting. I’m using FreeRTOS and µC/OS at most. This seems to be a nice alternative. I just wonder “What’s the catch?”. With the BSD License of the OS you avoid this silly FreeRTOS thing, where you need to print the FreeRTOS logo in your product documentation. But whatever I will check out the OS myself within the next month.

    One thing to the data type naming conventions. I personally don’t understand why people always use go on there own… I personally like to use the ISO-C / UNIX / MISRA-C:2004 Data type conventions like uint32_t. Yap It is long and maybe unhandy, but it’s regarding to a common standard and especially with gcc and a good toolchain you have the stdint.h anyways, with correct data types for you anyways.

    Well thanks for this articles, looking for more! 🙂

  • admin

    I’m really busy building a serious application around CoOS. This is the main reason I stopped writing articles and began to write a lot of code. I intend to share some of that code (the parts that are independent of my project) in about few weeks from now together with a series of postings about CoOS. As for the naming conventions and portable data types I agree — is would be beneficial to adhere to some standard and write code that is portable. Unfortunately, the lack of standards until recently, the lax nature of the ANSI C standard, the “community standards and styles” created this mess that we are in. I’m guilty as any other developer of not following ISO-C / UNIX / MISRA-C:2004 guidelines for years and many serious software houses are even guiltier for not promoting the standards themselves when providing the tools. This is the reason we keep reinventing the wheel trying to bring a bit of order.

    However, I’ve noticed that became more mainstream today, many tool chains providing portable data types as you mentioned. It would be nice for the compilers to adhere to C99 standard as well with all the benefits but, unfortunately, it may take a bit more for some… Look how inconsistent the 64-bit integer type is defined: is it long long or __int64? Silly, isn’t it?

    I will also dedicate postings on style and standards one day. What I need is time… just time 🙂