• No results found

Chapter 1: Implementation Startup

1.4 Example Program

Now the fun begins! At the end of each chapter in this book, I describe the example program that appears on the accompanying CD. Each source code module is described, and the func-tions and major structures of that module are defined. This is your opportunity to play with the source code, modify it, and even break it. Refer to the actual code as you read this section for clarification. If you do not have an OSEK/VDX implementation available, you will not be able to play with this code, so you might want to skip this section. If you do proceed, make sure you have read Appendix B, which describes in detail the structure of the development tree that I use and how the system is built. This appendix describes which files can be used as they are and which files might need to be modified if you are not using Wind River OSEK-Works.

At this point, the application can be built using the tools associated with the OSEK/VDX OS implementation. This usually consists of a two-part build. First the OS is built and config-ured based on the information in the OIL file. Next, the entire application is built and linked

Attribute Description

CC Conformance class for the application. With this attribute, the configurator can force a conformance class of AUTO,BCC1,BCC2, ECC1, or ECC2 and can generate an error if the class is violated.

SCHEDULE LikeCC, can force the scheduling policy for the application. Valid values are AUTO,NON,FULL, or MIXED with respect to preemption.

SYSTEMSTACKSIZE Reserves a set amount of system stack space that can be set by the application developer.

Example Program

19

into the OS. The example application is very simple at this time, but it is a complete applica-tion that can be built and run on the target. This small applicaapplica-tion operates rapidly, doing absolutely nothing at all! If you were to stop the software and observe where it is running, you would find it operating in an idle task provided by the OS implementation. Unless the watchdog is operating, it will continue in this tight loop forever.

1.4.1 Modules

The “Modules” section, included in all chapters, describes each of the source code modules found in the src directory.

startup.s The startup.s module contains the startup assembly language code that is entered when the microcontroller is reset. Its only function, _cstart, is entered when the sys-tem is reset; trap vectors also are used in case other exceptions occur. This module is specific to the microcontroller being used and needs to be modified extensively if you use this code on anything other than an MPC555-based system. The good news is that this module is the same throughout the book.

initspr.s Theinitspr.s module contains the assembly language code that sets the spe-cial-purpose registers of an MPC555 microcontroller. Its only function is InitSPR(), which is called from startup.s. It is required because of the inherent nature of addressing special-pur-pose registers in the PowerPC type of processor. This module is not required in systems using a different microcontroller, but a similar module might be required.

cinit.s Thecinit.s module contains two functions, InitRAM() and cinit(), which ini-tialize RAM to a known value as well as all the C iniini-tialized variables. The cinit() function is usually provided by the supplier of the compiler and might have a different name or be inte-grated into a startup module. I developed InitRAM() to initialize memory. Both of these assembly language functions use registers alone and do not require that any memory is initial-ized or available.

init.c Theinit.c module contains the routines that support initialization of the micro-controller registers and the application. At this point, only three services are available to the application.

void InitReg16(InitReg16ListType const *list); This service initializes the microcontroller registers defined in the null-terminated list referenced by the parameter list. This list is an array of structures of type InitReg16ListType, which is defined in init.h. Each entry in the list consists of the address of the register and its initial value.

The null terminator is identified when the address of the register is at zero, which can never occur in an MPC555 microcontroller. The construction of each list uses configura-tion macros defined in init.h and used in init.cfg. When constructing the table, the name of the register is defined as a member of a structure defined in register.h in the for-mat<register set>.<name>. I have chosen the same name found in the Motorola docu-mentation for the processor. The register set value is the name of a set of registers that are both logically related and reside in the same block of memory. The available values can be found at the end of register.h.

20

Chapter 1: Implementation Startup

void InitReg32(InitReg32ListType const *list); This service is identical to InitReg16() described previously but initializes 32-bit registers instead.

void InitSystem(InitType type); This service invokes a series of functions that are registered by the application in init.cfg and that allow the application to initialize itself based on a specific application-wide event. This event is defined in the parameter type, and can be any of the values defined in the InitType enumeration that appears in init.h. This routine invokes all of the functions in the list InitFunctionList, regardless of the value of the parameter type. InitFunctionList is defined using the macros in init.cfg, which create this constant array. The initialization function defined in this list is responsi-ble for determining the actions to be taken based on the initialization type, which is also forwarded as a parameter to each function. As the example application is developed, ini-tialization functions will be added to new modules to ensure that the application is in the proper state.

main.c Themain.c module contains two functions and one OS task. This module will be expanded throughout the book to include functions and tasks that are applicable to the entire application. The two functions are described below.

void main(long argc); This is the C entry point that is called from startup.s. For my particular startup system I allow the startup code to pass one argument defined as a long integer. At this point, the startup code always passes a 0, but it can be modified to pass information that indicates the type of startup that occurred, such as a hard reset, a watchdog timeout, or another exception. This routine performs all functions required out-side of the OS function for the application and invokes the service that starts the OS. It does not return to the startup code in the OSEKWorks implementation, but it may on other systems.

ApplicationErrorType ChangeMode(AppModeType mode); This function enables a running application that is operating within the OS to change the APPMODE of the system.

Because the OSEK/VDX standard does not allow the APPMODE to be changed while the sys-tem is running, this routine shuts down the application and restarts the syssys-tem in a differ-ent APPMODE. It also verifies that the APPMODE is valid and returns an error if an invalid APPMODE has been sent. The ApplicationErrorType enumeration is defined in main.h. In the following chapters, this function is expanded to handle more APPMODEs.

The only task included in main.c is the background task: a do-nothing task that is expanded in future chapters.

1.4.2 Configuration Files

In addition to the module files found in the src directory, a number of files used to configure the application are in the cfg directory. They are header files, into which the application pro-grammer puts application-specific information to tailor the standard operations.

cardgame.oil This is the OSEK/VDX OIL configuration file that is produced by the config-uration utility. It contains all the information used to generate the specific implementation of

Exercises

21

the OSEK/VDX OS. Do not edit this file directly if you have a GUI-based configuration util-ity.

init.cfg This file contains the configurations for the register initialization tables and the function initialization table. These tables are constructed by macros that start the table, add a new entry to the table, and close the table at the end. Refer to the comments in the configura-tion file for a descripconfigura-tion of how the macros are used.