X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-redboot.git;a=blobdiff_plain;f=doc%2Fhtml%2Fref%2Fhal-calling-if.html;fp=doc%2Fhtml%2Fref%2Fhal-calling-if.html;h=5985fc1a34465ff360d61a1096e2a558dede69c8;hp=0000000000000000000000000000000000000000;hb=2b5bec7716c03d42cfb16d8c98c9cea573bf6722;hpb=47412fc4bd1aefc0d5498bcb3860a9d727196f16 diff --git a/doc/html/ref/hal-calling-if.html b/doc/html/ref/hal-calling-if.html new file mode 100644 index 00000000..5985fc1a --- /dev/null +++ b/doc/html/ref/hal-calling-if.html @@ -0,0 +1,1432 @@ + + + + + + + + +
Some eCos platforms have supported full debugging capabilities via +CygMon since day one. Platforms of the architectures PowerPC, ARM, and +SH do not provide those features unless a GDB stub is included in the +application.
This is going to change. All platforms will (eventually) support +all the debugging features by relying on a ROM/RAM calling interface +(also referred to as virtual vector table) provided by the ROM +monitor. This calling interface is based on the tables used by libbsp +and is thus backwards compatible with the existing CygMon supported +platforms.
What are virtual vectors, what do they do, and why are they +needed?
"Virtual vectors" is the name of a table located at a static +location in the target address space. This table contains 64 vectors +that point to service functions or data.
The fact that the vectors are always placed at the same location in +the address space means that both ROM and RAM startup configurations +can access these and thus the services pointed to.
The primary goal is to allow services to be provided by ROM +configurations (ROM monitors such as RedBoot in particular) with +clients in RAM configurations being able to use these +services.
Without the table of pointers this would be impossible since the +ROM and RAM applications would be linked separately - in effect having +separate name spaces - preventing direct references from one to the +other.
This decoupling of service from client is needed by RedBoot, +allowing among other things debugging of applications which do not +contain debugging client code (stubs).
Virtual vectors are a mechanism for decoupling services +from clients in the address space.
The mechanism allows services to be implemented by a ROM +monitor, a RAM application, to be switched out at run-time, to be +disabled by installing pointers to dummy functions, etc.
The appropriate use of the mechanism is specified loosely by a +policy. The general policy dictates that the vectors are +initialized in whole by ROM monitors (built for ROM or RAM), or by +stand-alone applications.
For configurations relying on a ROM monitor environment, the policy +is to allow initialization on a service by service basis. The default +is to initialize all services, except COMMS services since these are +presumed to already be carrying a communication session to the +debugger / console which was used for launching the application. This +means that the bulk of the code gets tested in normal builds, and not +just once in a blue moon when building new stubs or a ROM +configuration.
The configuration options are written to comply with this policy by +default, but can be overridden by the user if desired. Defaults +are:
For application development: the ROM monitor provides +debugging and diagnostic IO services, the RAM application relies +on these by default.
For production systems: the application contains all the +necessary services.
There are pros and cons associated with the use of virtual +vectors. We do believe that the pros generally outweigh the cons by a +great margin, but there may be situations where the opposite is +true.
The use of the services are implemented by way of macros, meaning +that it is possible to circumvent the virtual vectors if +desired. There is (as yet) no implementation for doing this, but it is +possible.
Here is a list of pros and cons:
This is the primary reason for using virtual vectors. It + allows the ROM monitor to provide most of the debugging + infrastructure, requiring only the application to provide + hooks for asynchronous debugger interrupts and for accessing + kernel thread information.
While this is only true where the application does not + actively override the debugging channel setup, it is a very + nice feature during development. In particular it makes it + possible to launch (and/or debug) applications via Ethernet + even though the application configuration does not contain + networking support.
All service functions except HAL IO are included in the + default configuration. But if these are all disabled the + image for download will be a little smaller. Probably + doesn't matter much for regular development, but it is a + worthwhile saving for the 20000 daily tests run in the Red + Hat eCos test farm.
The size increase is a fraction of what is required to + implement the services. So for RAM configurations there is + a net saving, while for ROM configurations there is a small + overhead.
The performance loss means little for most of the + services (of which the most commonly used is diagnostic IO + which happens via polled routines + anyway).
The concern primarily being that of vectors being + trashed by rogue writes from bad code, causing a complete + loss of the service and possibly a crash. But this does + not differ much from a rogue write to anywhere else in the + address space which could cause the same amount of + mayhem. But it is arguably an additional point of failure + for the service in question.
This is a valid concern. However, seeing as most of the + code in question is shared between all HALs and should + remain unchanged over time, the risk of it being broken + when a new HAL is being worked on should be + minimal.
When starting a new port, be sure to implement the HAL + IO drivers according to the scheme used in other drivers, + and there should be no problem.
However, it is still possible to circumvent the vectors + if they are suspect of causing problems: simply change the + HAL_DIAG_INIT and HAL_DIAG_WRITE_CHAR macros to use the raw + IO functions.
The hal_if.h file in the common HAL defines the +complete list of available services. A few worth mentioning in +particular:
COMMS services. All HAL IO happens via the communication + channels.
uS delay. Fine granularity (busy wait) delay function.
Reset. Allows a software initiated reset of the board.
As all HAL IO happens via the COMMS channels these deserve to be +described in a little more detail. In particular the controls of where +diagnostic output is routed and how it is treated to allow for display +in debuggers.
There are two COMMS channels - one for console IO and one for +debugging IO. They can be individually configured to use any of the +actual IO ports (serial or Ethernet) available on the platform.
The console channel is used for any IO initiated by calling the +diag_*() functions. Note that these should only be used during +development for debugging, assertion and possibly tracing +messages. All proper IO should happen via proper devices. This means +it should be possible to remove the HAL device drivers from production +configurations where assertions are disabled.
The debugging channel is used for communication between the +debugger and the stub which remotely controls the target for the +debugger (the stub runs on the target). This usually happens via some +protocol, encoding commands and replies in some suitable form.
Having two separate channels allows, e.g., for simple logging +without conflicts with the debugger or interactive IO which some +debuggers do not allow.
As debuggers usually have a protocol using specialized commands +when communicating with the stub on the target, sending out text as +raw ASCII from the target on the same channel will either result in +protocol errors (with loss of control over the target) or the text may +just be ignored as junk by the debugger.
To get around this, some debuggers have a special command for text +output. Mangling is the process of encoding diagnostic ASCII text +output in the form specified by the debugger protocol.
When it is necessary to use mangling, i.e. when writing console +output to the same port used for debugging, a mangler function is +installed on the console channel which mangles the text and passes it +on to the debugger channel.
Console output configuration is either inherited from the ROM +monitor launching the application, or it is specified by the +application. This is controlled by the new option +CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE which +defaults to enabled when the configuration is set to use a ROM +monitor.
If the user wants to specify the console configuration in the +application image, there are two new options that are used for +this.
Defaults are to direct diagnostic output via a mangler to the +debugging channel (CYGDBG_HAL_DIAG_TO_DEBUG_CHAN +enabled). The mangler type is controlled by the option +CYGSEM_HAL_DIAG_MANGLER. At present there are only +two mangler types:
This causes a mangler appropriate for debugging with GDB to be + installed on the console channel.
This causes a NULL mangler to be installed on the console + channel. It will redirect the IO to/from the debug channel + without mangling of the data. This option differs from setting + the console channel to the same IO port as the debugging + channel in that it will keep redirecting data to the debugging + channel even if that is changed to some other port.
Finally, by disabling CYGDBG_HAL_DIAG_TO_DEBUG_CHAN, the diagnostic +output is directed in raw form to the specified console IO port.
In summary this results in the following common configuration +scenarios for RAM startup configurations:
For regular debugging with diagnostic output appearing in the + debugger, mangling is enabled and stubs disabled.
Diagnostic output appears via the debugging channel as + initiated by the ROM monitor, allowing for correct behavior + whether the application was launched via serial or Ethernet, from + the RedBoot command line or from a debugger.
For debugging with raw diagnostic output, mangling is + disabled.
Debugging session continues as initiated by the ROM monitor, + whether the application was launched via serial or + Ethernet. Diagnostic output is directed at the IO port configured + in the application configuration.
Note:: There is one caveat to be aware of. If the + application uses proper devices (be it serial or Ethernet) on + the same ports as those used by the ROM monitor, the + connections initiated by the ROM monitor will be + terminated.
And for ROM startup configurations:
Production configuration with raw output and no debugging + features (configured for RAM or ROM), mangling is disabled, no + stubs are included.
Diagnostic output appears (in unmangled form) on the specified + IO port.
RedBoot configuration, includes debugging features and necessary + mangling.
Diagnostic and debugging output port is auto-selected by the + first connection to any of the supported IO ports. Can change + from interactive mode to debugging mode when a debugger is + detected - when this happens a mangler will be installed as + required.
GDB stubs configuration (obsoleted by RedBoot configuration), + includes debugging features, mangling is hardwired to GDB + protocol.
Diagnostic and debugging output is hardwired to configured IO + ports, mangling is hardwired.
The current code for controlling the console channel is a +replacement for an older implementation which had some shortcomings +which addressed by the new implementation.
This is what the old implementation did: on initialization it would +check if the CDL configured console channel differed from the active +debug channel - and if so, set the console channel, thereby disabling +mangling.
The idea was that whatever channel was configured to be used for +console (i.e., diagnostic output) in the application was what should +be used. Also, it meant that if debug and console channels were +normally the same, a changed console channel would imply a request for +unmangled output.
But this prevented at least two things:
It was impossible to inherit the existing connection by which + the application was launched (either by RedBoot commands via + telnet, or by via a debugger).
This was mostly a problem on targets supporting Ethernet + access since the diagnostic output would not be returned via the + Ethernet connection, but on the configured serial port.
The problem also occurred on any targets with multiple serial + ports where the ROM monitor was configured to use a different + port than the CDL defaults.
Proper control of when to mangle or just write out raw ASCII + text.
Sometimes it's desirable to disable mangling, even if the + channel specified is the same as that used for debugging. This + usually happens if GDB is used to download the application, but + direct interaction with the application on the same channel is + desired (GDB protocol only allows output from the target, no + input).
The calling interface API is defined by hal_if.h and hal_if.c in +hal/common.
The API provides a set of services. Different platforms, or +different versions of the ROM monitor for a single platform, may +implement fewer or extra service. The table has room for growth, and +any entries which are not supported map to a NOP-service (when called +it returns 0 (false)).
A client of a service should either be selected by configuration, +or have suitable fall back alternatives in case the feature is not +implemented by the ROM monitor.
Note:: Checking for unimplemented service when this may be a data +field/pointer instead of a function: suggest reserving the last entry +in the table as the NOP-service pointer. Then clients can compare a +service entry with this pointer to determine whether it's initialized +or not.
The header file cyg/hal/hal_if.h defines + the table layout and accessor macros (allowing primitive type + checking and alternative implementations should it become necessary).
The source file hal_if.c defines the table + initialization function. All HALs should call this during platform + initialization - the table will get initialized according to + configuration. Also defined here are wrapper functions which map + between the calling interface API and the API of the used eCos + functions.
This is a brief description of the services, some of which are +described in further detail below.
Version of table. Serves as a way to check for how many + features are available in the table. This is the index of the + last service in the table.
[Presently unused by the stub code, but initialized] This + vector defines a function to execute when the system receives + a kill signal from the debugger. It is initialized with the + reset function (see below), but the application (or eCos) can + override it if necessary.
The communication procedure table used for console IO + (see the Section called IO channels.
The communication procedure table used for debugger IO + (see the Section called IO channels).
Flushes the data cache for the specified + region. Some implementations may flush the entire data cache.
Flushes (invalidates) the instruction cache + for the specified region. Some implementations may flush the + entire instruction cache.
Change debugging communication channel.
Change console communication channel.
Vector used to communication between debugger functions in + ROM and in RAM. RAM eCos configurations may install a function + pointer here which the ROM monitor uses to get thread + information from the kernel running in RAM.
Resets the board on call. If it is not possible to reset + the board from software, it will jump to the ROM entry point + which will perform a "software" reset of the board.
Set if a debugger interrupt request was detected while + processing console IO. Allows the actual breakpoint action to + be handled after return to RAM, ensuring proper backtraces + etc.
Will delay the specified number of microseconds. The + precision is platform dependent to some extend - a small value + (<100us) is likely to cause bigger delays than requested.
For accessing configuration settings kept in flash memory.
Installs a breakpoint at the specified address. This is + used by the asynchronous breakpoint support + (see ).
When a platform is changed to support the calling interface, +applications will use it if so configured. That means that if an +application is run on a platform with an older ROM monitor, the +service is almost guaranteed to fail.
For this reason, applications should only use Console Comm for HAL +diagnostics output if explicitly configured to do so +(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG).
As for asynchronous GDB interrupts, the service will always be +used. This is likely to cause a crash under older ROM monitors, but +this crash may be caught by the debugger. The old workaround still +applies: if you need asynchronous breakpoints or thread debugging +under older ROM monitors, you may have to include the debugging +support when configuring eCos.
During the startup of a ROM monitor, the calling table will be +initialized. This also happens if eCos is configured not to rely on +a ROM monitor.
Note:: There is reserved space (256 bytes) for the vector +table whether it gets used or not. This may be something that we want +to change if we ever have to shave off every last byte for a given +target.
If thread debugging features are enabled, the function for accessing +the thread information gets registered in the table during startup of +a RAM startup configuration.
Further implementation details are described where the service itself +is described.
The hal_platform_init() function must call +hal_if_init().
The HAL serial driver must, when called via +cyg_hal_plf_comms_init() must initialize the +communication channels.
The reset() function defined in +hal_if.c will attempt to do a hardware reset, but +if this fails it will fall back to simply jumping to the reset +entry-point. On most platforms the startup initialization will go a +long way to reset the target to a sane state (there will be +exceptions, of course). For this reason, make sure to define +HAL_STUB_PLATFORM_RESET_ENTRY in plf_stub.h.
All debugging features must be in place in order for the debugging +services to be functional. See general platform porting notes.
There are no specific requirements for a new architecture port in +order to support the calling interface, but the basic debugging +features must be in place. See general architecture porting notes.
The calling interface provides procedure tables for all IO channels on +the platform. These are used for console (diagnostic) and debugger IO, +allowing a ROM monitor to provided all the needed IO routines. At +the same time, this makes it easy to switch console/debugger channels +at run-time (the old implementation had hardwired drivers for console +and debugger IO, preventing these to change at run-time).
The hal_if provides wrappers which interface these services to the +eCos infrastructure diagnostics routines. This is done in a way which +ensures proper string mangling of the diagnostics output when required +(e.g. O-packetization when using a GDB compatible ROM monitor).
This is a brief description of the procedures
Pointer to the controller IO base (or a pointer to a per-device + structure if more data than the IO base is required). All the + procedures below are called with this data item as the first + argument.
Writes the buffer to the device.
Fills a buffer from the device.
Write a character to the device.
Read a character from the device.
Device feature control. Second argument specifies function:
Changes baud rate.
Returns the current baud rate.
[Unused]
[Unused]
Disable debugging receive interrupts on the device.
Enable debugging receive interrupts on the device.
Returns the ISR vector used by the device for debugging + receive interrupts.
Set GETC timeout in milliseconds.
Forces driver to flush data in its buffers. Note + that this may not affect hardware buffers + (e.g. FIFOs).
ISR used to handle receive interrupts from the + device (see ).
Read a character from the device with timeout.
The standard eCos diagnostics IO functions use the channel +procedure table when CYGSEM_HAL_VIRTUAL_VECTOR_DIAG is enabled. That +means that when you use diag_printf (or the libc printf function) the +stream goes through the selected console procedure table. If you use +the virtual vector function SET_CONSOLE_COMM you can change the device +which the diagnostics output goes to at run-time.
You can also use the table functions directly if desired +(regardless of the CYGSEM_HAL_VIRTUAL_VECTOR_DIAG setting - assuming +the ROM monitor provides the services). Here is a small example which +changes the console to use channel 2, fetches the comm procs pointer +and calls the write function from that table, then restores the +console to the original channel:
#define T "Hello World!\n" + +int +main(void) +{ + hal_virtual_comm_table_t* comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + + CYGACC_CALL_IF_SET_CONSOLE_COMM(2); + + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_WRITE(*comm, T, strlen(T)); + + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); +} |
Beware that if doing something like the above, you should only do +it to a channel which does not have GDB at the other end: GDB ignores +raw data, so you would not see the output.
The use of this service is controlled by the option +CYGSEM_HAL_VIRTUAL_VECTOR_DIAG which is disabled per default on most +older platforms (thus preserving backwards compatibility with older +stubs). On newer ports, this option should always be set.
There is an array of procedure tables (raw comm channels) for each +IO device of the platform which get initialized by the ROM monitor, or +optionally by a RAM startup configuration (allowing the RAM +configuration to take full control of the target). In addition to +this, there's a special table which is used to hold mangler +procedures.
The vector table defines which of these channels are selected for +console and debugging IO respectively: console entry can be empty, +point to mangler channel, or point to a raw channel. The debugger +entry should always point to a raw channel.
During normal console output (i.e., diagnostic output) the console +table will be used to handle IO if defined. If not defined, the debug +table will be used.
This means that debuggers (such as GDB) which require text streams +to be mangled (O-packetized in the case of GDB), can rely on the ROM +monitor install mangling IO routines in the special mangler table and +select this for console output. The mangler will pass the mangled data +on to the selected debugging channel.
If the eCos configuration specifies a different console channel +from that used by the debugger, the console entry will point to the +selected raw channel, thus overriding any mangler provided by the ROM +monitor.
See hal_if_diag_* routines in hal_if.c for more details of the stream +path of diagnostic output. See cyg_hal_gdb_diag_*() routines in +hal_stub.c for the mangler used for GDB communication.
Define CDL options CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS, +CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL, and +CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL.
If CYGSEM_HAL_VIRTUAL_VECTOR_DIAG is set, make sure the infra diag +code uses the hal_if diag functions:
#define HAL_DIAG_INIT() hal_if_diag_init() + #define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_) + #define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_) |
In addition to the above functions, the platform HAL must also +provide a function cyg_hal_plf_comms_init which initializes the +drivers and the channel procedure tables.
Most of the other functionality in the table is more or less +possible to copy unchanged from existing ports. Some care is necessary +though to ensure the proper handling of interrupt vectors and timeouts +for various devices handled by the same driver. See PowerPC/Cogent +platform HAL for an example implementation.
Note:: When vector table console code is not used, +the platform HAL must map the HAL_DIAG_INIT, HAL_DIAG_WRITE_CHAR and +HAL_DIAG_READ_CHAR macros directly to the low-level IO functions, +hardwired to use a compile-time configured channel.
Note:: On old ports the hardwired HAL_DIAG_INIT, +HAL_DIAG_WRITE_CHAR and +HAL_DIAG_READ_CHAR implementations will also +contain code to O-packetize the output for GDB. This should +not be adopted for new ports! On new ports the +ROM monitor is guaranteed to provide the necessary mangling via the +vector table. The hardwired configuration should be reserved for ROM +startups where achieving minimal image size is crucial.