File Layout Questions (Suggestions?)

I’m a new user to FreeRTOS.  I’m working on a new project using at AT90SUB1287.  You can see my blog at http://mudplace.org/?cat=3 I have some questions about the file layout and includes.  Specifically I’m curious about the #include mechanism and ports. 1.  Why require a "FreeRTOSConfig.h"?  Or at least allow for an external definition of the values.  Say something like: #ifndef DONT_USE_FREE_RTOS_CONFIG #include "FreeRTOSConfig.h" #endif This way a user can tailor the specifics of the kernel using command-line values, such as -DconfigUSE_PREEMPTION=1, etc.  And for those compilers that do not support the -D option, it can fallback to the #include mechanism. 2.  Why have portable.h #include one of a variety of files?  Instead, why not require the user to provide a portable.h?  The user can then copy one of the variety of portmacro.h files over to portable.h, or at least just have a generic #include "portable.h" and make the user point to the appropriate directory (or copy the file) to find the portable.h. The problem, for me at least, is the relative path includes, such as "..\..sourceowatcom16bitdospcportmacro.h".  This kind of include forces me to compile from the FreeRTOS directory, rather than from any directry I want. Perhaps something like: #ifndef PORTABLE_H #define PORTABLE_H #include "portmacro.h" .. #endif /* PORTABLE_H */ 3.  Why couple the port.c file so tightly to the hardware?  For example, in portable/GCC/ATMega323, the xPortStartScheduler() configures a specific timer for context switching.  What if the user wanted a different timer?  They would then have to modify the FreeRTOS source itself.  Or on the Microblaze port, the code assumes use of the Xilinx provided drivers.  What if a user had their own driver for the OPB timer?  What if they didn’t use the OPB timer but provided their own?  It seems this kind of code is better suited to the demos. For example, we use ThreadX and uCos at work.  In ThreadX, there is a tx_port.h file that defines a minimum of hardware specific items, such as portmacro.h does.  It defines the types, has macro definitions for critical sections, etc.  We compile ThreadX into a library, independent of the firmware.  All we have to provide in the firmware are callbacks to tx_kernel_enter(), tx_application_define(), _tx_timer_interrupt(), etc at link time.  Also, all the features are individually selectable through pre-processor defintions (we use -D on the command line to specify what we want). Also, by compiling into a library, I can only pull in the symbols that are actually needed.  Linking the object files with the application directly may pull in symbols that are never called (depends upon the compiler/linker).  I personally found a decrease in final exectuable size of nearly 5K by using a library. In my use of FreeRTOS, I modified portable.h to remove the relative include paths.  I then put port.c and portmacro.h in a separate area where I could provide my own backend functions.  I then compiled everything and archived it into a library.  Now I just compile my code separately and link with the FreeRTOS library.  But now I am tempted to copy the FreeRTOS files over, modify the #includes, and them just stick with v4.7.1. I’m not trying to be pedantic or annoying on this.  Just curious about the structure and design decisions.  And perhaps suggest some changes. Thanks, Pete

File Layout Questions (Suggestions?)

Hi, > 1.  Why require a "FreeRTOSConfig.h"?  Or at least allow for > an external definition > of the values.  Say something like: > > #ifndef DONT_USE_FREE_RTOS_CONFIG > #include "FreeRTOSConfig.h" > #endif > > This way a user can tailor the specifics of the kernel using > command-line values, > such as -DconfigUSE_PREEMPTION=1, etc.  And for those > compilers that do not > support the -D option, it can fallback to the #include mechanism. I try to keep conditional compilation to a minimum for code readability – although this is being breached more and more. I think the use of such a configuration file is the norm, and easier for novice users.  If you want to use command line options instead then simply delete the contents of FreeRTOSConfig.h.  FreeRTOSConfig.h is purely an application side header file, rather than part of the kernel itself (i.e. it appears in the Demo directory tree, not the Source directory tree). > > 2.  Why have portable.h #include one of a variety of files?  > Instead, why not > require the user to provide a portable.h?  The user can then > copy one of the > variety of portmacro.h files over to portable.h, or at least > just have a generic > #include "portable.h" and make the user point to the > appropriate directory (or > copy the file) to find the portable.h. > The mechanism is hidden from the user – it compiles ‘out of the box’ without the user needing to know the implementation details. > The problem, for me at least, is the relative path includes, such > as "..\..sourceowatcom16bitdospcportmacro.h".  This kind > of include forces > me to compile from the FreeRTOS directory, rather than from > any directry I want. > Why not just have a -I option to the path, then have "#include portmacro.h" with no path.  This is how the the newer ports are going (AVR32, and Fujitsu). > 3.  Why couple the port.c file so tightly to the hardware?  > For example, in > portable/GCC/ATMega323, the xPortStartScheduler() configures > a specific timer > for context switching.  What if the user wanted a different > timer?  They would > then have to modify the FreeRTOS source itself.  Or on the > Microblaze port, > the code assumes use of the Xilinx provided drivers.  What if > a user had their > own driver for the OPB timer?  What if they didn’t use the > OPB timer but provided > their own?  It seems this kind of code is better suited to the demos. Microblaze is a Xilinx processor – it can only be used on Xilinx parts using Xilinx tools as far as I know.  Users are free to alter the source code as much as they like.  Again, the demos are designed to allow out of the box compilation, not all users have the skill to start supplying their own drivers, more experienced users can change the timers quite easily. I think the tick source is the only coupling the hardware? > For example, we use ThreadX and uCos at work.  In ThreadX, > there is a tx_port.h > file that defines a minimum of hardware specific items, such > as portmacro.h > does.  It defines the types, has macro definitions for > critical sections, etc. > We compile ThreadX into a library, independent of the > firmware.  All we have > to provide in the firmware are callbacks to tx_kernel_enter(), > tx_application_define(), _tx_timer_interrupt(), etc at link > time.  Also, all That is a good idea, provided the demos come with examples. > > Also, by compiling into a library, I can only pull in the > symbols that are actually > needed.  Linking the object files with the application > directly may pull in > symbols that are never called (depends upon the > compiler/linker).  I think GCC is the only compiler that will do this by default – but you can use the linker command line options to prevent this happening. > I personally > found a decrease in final exectuable size of nearly 5K by > using a library. I forget the command line options required, something like but not exactly -gcc-sections. > In my use of FreeRTOS, I modified portable.h to remove the > relative include > paths.  I then put port.c and portmacro.h in a separate area > where I could provide > my own backend functions.  I then compiled everything and > archived it into a > library.  Now I just compile my code separately and link with > the FreeRTOS library. You are using the open source nature to its full benefit then! > But now I am tempted to copy the FreeRTOS files over, modify > the #includes, > and them just stick with v4.7.1. > > I’m not trying to be pedantic or annoying on this.  Just > curious about the structure > and design decisions.  And perhaps suggest some changes. Its always good to get feedback.  It helps improve the project in the future.  I like you ideas regarding the user supplied functions – although in effect users can do this already but it means editing the core code which is bad for maintainability/upgrading. Regards.

File Layout Questions (Suggestions?)

>I think the use of such a configuration file is the norm, and easier for >novice users. If you want to use command line options instead then simply >delete the contents of FreeRTOSConfig.h. FreeRTOSConfig.h is purely an >application side header file, rather than part of the kernel itself (i.e. >it appears in the Demo directory tree, not the Source directory tree). Ahh.  This is a good idea.  Zeroing this out and using -D on the command line is a good, configurable way. I guess what I was driving at was eliminating the #include for the config file.  And, in fact, looking over tx_port.h there is an option for a conditional include–as per the example I gave earlier.  For example, from tx_port.h: /* Determine if the optional ThreadX user define should be used. */ #ifdef TX_INCLUDE_USER_DEFINE_FILE /* Yes, include the user defines in tx_user.h.  The defines in this file may    alternately be defined on the command line. */    #include "tx_user.h" #endif I guess that is what I was driving at in my example. >> 2. Why have portable.h #include one of a variety of files?  >> Instead, why not >> require the user to provide a portable.h? The user can then  >> copy one of the >> variety of portmacro.h files over to portable.h, or at least  >> just have a generic >> #include "portable.h" and make the user point to the  >> appropriate directory (or >> copy the file) to find the portable.h. >>  > >The mechanism is hidden from the user – it compiles ‘out of the box’ without >the user needing to know the implementation details. Fair enough.  It does work out of the box. >> The problem, for me at least, is the relative path includes, such >> as "..\..sourceowatcom16bitdospcportmacro.h". This kind  >> of include forces >> me to compile from the FreeRTOS directory, rather than from  >> any directry I want. >>  > > >Why not just have a -I option to the path, then have "#include portmacro.h" >with no path. This is how the the newer ports are going (AVR32, and Fujitsu). Ah.  Thanks for the pointer.  This makes much more sense.  I only looked at my platforms (Microblaze and the AT90USB). >> 3. Why couple the port.c file so tightly to the hardware?  >> For example, in >> portable/GCC/ATMega323, the xPortStartScheduler() configures  >> a specific timer >> for context switching. What if the user wanted a different  >> timer? They would >> then have to modify the FreeRTOS source itself. Or on the  >> Microblaze port, >> the code assumes use of the Xilinx provided drivers. What if  >> a user had their >> own driver for the OPB timer? What if they didn’t use the  >> OPB timer but provided >> their own? It seems this kind of code is better suited to the demos. > > > >Microblaze is a Xilinx processor – it can only be used on Xilinx parts using >Xilinx tools as far as I know. Users are free to alter the source code as >much as they like. Again, the demos are designed to allow out of the box >compilation, not all users have the skill to start supplying their own >drivers, more experienced users can change the timers quite easily. True, the Microblaze requires the EDK from Xilinx.  But I wasn’t referring to the demo source, but the code in portable/GCC/Microblaze.  The actual use of the timer is something platform specific, not processor specific.  That is why I suggested moving it to the demo area. >I think the tick source is the only coupling the hardware? Yes, mostly.  The microblaze_en(dis)able_interrupts() are specific to the Xilinx EDK library.  A more portable option is something like: #define portDISABLE_INTERRUPTS __asm__ __volatile__("mfs r3, rmsr; andi r3,r4,0xfffffffd; mts rmsr,r4" : : : "r3", "r4") #define portENABLE_INTERRUPTS __asm__ __volatile__("mfs r3, rmsr; ori r3,r4,2; mts rmsr,r4" : : : "r3", "r4") (Though I found that the clobber registers part of the the current EDK do not preserve registers that are clobbered.) It just seems (I’m probably wrong) that the portable/ directory is a fundamental part of FreeRTOS, and shouldn’t have any library or hardware specific stuff in it. >> For example, we use ThreadX and uCos at work. In ThreadX,  >> there is a tx_port.h >> file that defines a minimum of hardware specific items, such  >> as portmacro.h >> does. It defines the types, has macro definitions for  >> critical sections, etc. >> We compile ThreadX into a library, independent of the  >> firmware. All we have >> to provide in the firmware are callbacks to tx_kernel_enter(), >> tx_application_define(), _tx_timer_interrupt(), etc at link  >> time. Also, all > >That is a good idea, provided the demos come with examples. Perhaps I can create a demo for the USBKEY that makes use of this. >> Also, by compiling into a library, I can only pull in the  >> symbols that are actually >> needed. Linking the object files with the application  >> directly may pull in >> symbols that are never called (depends upon the  >> compiler/linker).  > >I think GCC is the only compiler that will do this by default – but you can >use the linker command line options to prevent this happening. Hmm…I’ll have to look into this. >> I personally >> found a decrease in final exectuable size of nearly 5K by  >> using a library. > >I forget the command line options required, something like but not >exactly -gcc-sections. Really?  This would be very useful–not only for this, but at work too. >> In my use of FreeRTOS, I modified portable.h to remove the  >> relative include >> paths. I then put port.c and portmacro.h in a separate area  >> where I could provide >> my own backend functions. I then compiled everything and  >> archived it into a >> library. Now I just compile my code separately and link with  >> the FreeRTOS library. > >You are using the open source nature to its full benefit then! But I am still limited in upgradability.  If there is a fix to FreeRTOS or a feature upgrade, it is difficult to do the upgrade. >> But now I am tempted to copy the FreeRTOS files over, modify  >> the #includes, >> and them just stick with v4.7.1. >>  >> I’m not trying to be pedantic or annoying on this. Just  >> curious about the structure >> and design decisions. And perhaps suggest some changes. > > >Its always good to get feedback. It helps improve the project in the future. >I like you ideas regarding the user supplied functions – although in effect >users can do this already but it means editing the core code which is bad for >maintainability/upgrading. My point exactly.  I don’t want to commit to a version, then figure out how to scab in an upgrade if it occurs.  But you have some great ideas for making this more friendly to an upgrade and compiling elsewhere. Thanks, Pete

File Layout Questions (Suggestions?)

>>> I personally  >>> found a decrease in final exectuable size of nearly 5K by  >>> using a library.  >>  >>I forget the command line options required, something like but not >>exactly -gcc-sections.  >Really? This would be very useful–not only for this, but at work too. Try compiling with -fdata-sections -ffunction-sections, which I think places all data/functions in their own sections, then linking with –gc-sections to only include used sections. I might have this a bit wrong it should be a big enough clue as to what to look for in the GCC manual. This should effectively remove "dead" code which is ok provided all is linked statically.