Downloads
release
dev builds
extras
themes
Documentation
manual
wiki
device status
Support
forums
mailing lists
IRC
Development
bugs
patches
dev guide
Search
Search
| Go
Wiki
>
Main
>
RockboxArchitecture
>
TargetTree
---+!! The Target Tree structure %TOC% <br /> --- ---++ General Rockbox builds on many different targets. We need a way to separate the target specific code to keep the common/generic code as clean as possible. The traditional solution in Rockbox so far has been to use =#ifdef= to conditionally compile target specific stuff. %CODE{"cpp"}% void my_hw_init(void) { #ifdef IRIVER_H100_SERIES or_l(0x00020000, &GPIO1_ENABLE); #elif defined(IRIVER_H300_SERIES) or_l(0x00040000, &GPIO1_ENABLE); #endif } %ENDCODE% When we have many targets, these =#ifdef= statements will clutter the code. The solution is to move the target specific code to separate files. The idea is that each target defines its own =my_hw_init()= function in a separate file, and the =firmware/SOURCES= file decides what files to compile depending on the target. <br /> --- ---++ The directory structure The target tree is divided into subdirectories, where each directory is an abstraction level. <verbatim> firmware/target/<cpu>/<manufacturer>/<model>/ </verbatim> The idea is to have CPU-specific code in the =<cpu>= directory, manufacturer specific stuff in =<manufacturer>= etc. For example, a Coldfire optimized =memcpy()= would be put in =firmware/target/coldfire/memcpy-coldfire.S=, and the =firmware/SOURCES= file would contain something like this: %CODE{"cpp"}% #ifndef SIMULATOR #ifdef CPU_COLDFIRE target/coldfire/memcpy-coldfire.S #endif #endif %ENDCODE% <br /> --- ---++ Backlight example The backlight code is a perfect example of the benefit of the target tree structure. Here we have a generic functionality that turns off the backlight after a user-defined timeout. However, controlling the actual backlight is done differently in virtually all targets. The backlight code calls two functions, =__backlight_on()= and =__backlight_off()= to turn on and off the backlight, and these two have to be defined in a target specific file. Let's take the iAudio X5 as an example. The backlight code is in the X5 target directory: <verbatim> firmware/target/coldfire/iaudio/x5/backlight-x5.c </verbatim> The file is called backlight-x5.c to make it easier to distinguish from the generic one when doing a file search. We recommend you to do the same when you port to a new target. This file defines the =__backlight_xxx()= functions: %CODE{"cpp"}% void __backlight_on(void) { int level = set_irq_level(HIGHEST_IRQ_LEVEL); pcf50606_write(0x38, 0x30); /* Backlight ON */ set_irq_level(level); } void __backlight_off(void) { int level = set_irq_level(HIGHEST_IRQ_LEVEL); pcf50606_write(0x38, 0x70); /* Backlight OFF */ set_irq_level(level); } %ENDCODE% ---++ What about targets not yet ported to the target tree? The =tools/configure= script adds a preprocessor macro, TARGET_TREE for targets that use the target tree. For older targets, the old =#ifdef= hell is still there. Here's how it typically looks in the generic source file: %CODE{"cpp"}% #ifndef TARGET_TREE void my_hw_init(void) { #ifdef IRIVER_H100_SERIES bla bla #elif defined(IRIVER_H300_SERIES) bla bla #endif } #endif %ENDCODE% The function is defined in the generic file unless the TARGET_TREE macro is defined. The goal is to remove all target specific code to the target tree, but we're not there yet. <br /> --- ---++ What about include files? The target tree is supposed to use the =firmware/SOURCES= file to select the source files to compile for each target. However, there are occasions where you want to have target specific information in an include file, like setting up preprocessor macros to be used by the generic driver file. The solution is to have a =*_target.h= file which is included by the generic driver file. The include search path for target-tree enabled targets is as follows: <verbatim> firmware/target/<cpu>/<manufacturer>/<model> firmware/target/<cpu>/<manufacturer>/ firmware/target/<cpu>/ </verbatim> For example, the =firmware/drivers/m5636.h= file does this: %CODE{"cpp"}% #include "m5636-target.h" %ENDCODE% The =m5636-target.h= is in the target specific directory, for example =firmware/target/coldfire/iaudio/x5/m5636-target.h=, along with =firmware/target/coldfire/iaudio/x5/m5636-x5.c=. ---
E
dit
|
A
ttach
|
P
rint version
|
H
istory
: r3
<
r2
<
r1
|
B
acklinks
|
V
iew topic
|
M
ore topic actions
r3 - 24 Sep 2008 - 14:02:10 -
MarcGuay
Parents:
RockboxArchitecture
Copyright © by the contributing authors.