ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.06.2025

Просмотров: 4214

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Hardware Description Table

data_area: This is a typeless pointer to the different category-depend-

ent data structures that hold type-specific information for the assigned drivers. It is a typeless pointer, since no common structure can be used to store the diversity of parameters for all the drivers.

The array of these structures has no predefined length and therefore requires a special end marker to prevent RoBIOS from running past the last valid entry. This final entry is denoted as:

{END_OF_HDT,UNKNOWN_SEMANTICS,"END",(void *)0}

Apart from this marker, two other entries are mandatory for all HDTs:

WAIT: This entry points to a list of waitstate values for the different

chip-access times on the controller platform, which are directly derived from the chosen CPU frequency.

INFO: This entry points to a structure of numerous basic settings, like

the CPU frequency to be used, download and serial port settings, network ID, robot name, etc.

Program B.2 is an example of the shortest valid HDT.

Program B.2: Shortest valid HDT file

1

#include "robios.h"

2

int

magic = 123456789;

3

extern HDT_entry_type HDT[];

4

HDT_entry_type *hdtbase = &HDT[0];

5

/* Info: EyeBot summary */

6

7

info_type roboinfo = {0, VEHICLE, SER115200, RTSCTS,

8SERIAL1, 0, 0, AUTOBRIGHTNESS, BATTERY_ON, 35, 1.0,

9"Eye-M5",1};

10/* waitstates for: ROM, RAM, LCD, IO, UART */

11waitstate_type waitstates = {0,3,1,2,1,2};

12

13HDT_entry_type HDT[] =

14{ {WAIT,WAIT,"WAIT",(void *)&waitstates},

15{INFO,INFO,"INFO",(void *)&roboinfo},

16{END_OF_HDT,UNKNOWN_SEMANTICS,"END",(void *)0}

17};

The descriptions of all the different HDT data structures can be found in Appendix C. Together with the array of component structures, the used data structures build up the complete source code for an HDT binary. To obtain a downloadable binary image the HDT source code has to be compiled with the special HDT batch commands provided with the RoBIOS distribution. For example:

gcchdt myhdt.c -o myhdt.hex

The HDT code is compiled like a normal program except for a different linker file that tells the linker not to include any start-up code or main() func-

381


B RoBIOS Operating System

tion, since only the data part is needed. During the download of an HDT binary to the controller, the “magic number” in the HDT header is recognized by RoBIOS and the user is prompted to authorize updating the HDT in flashROM.

B.3.2 HDT Access Functions

There are five internal functions in RoBIOS to handle the HDT. They are mainly used by hardware drivers to find the data structure corresponding to a given semantics or to iterate through all assigned data structures with the same type identifier:

int HDT_Validate(void)

This function is used by RoBiOS to check the magic number of the HDT and to initialize the global HDT access data structure.

void *HDTFindEntry(TypeID typeid,DeviceSemantics semantics)

With the help of this function the address of the data structure that corresponds to the given type identifier and semantics is found. This is the only function that can also be called from a user program to obtain more detailed information about a specific device configuration or characteristic.

DeviceSemantics HDT_FindSemantics(TypeID typeid, int x)

This is the function that is needed to iterate through all available entries of the same type. By calling this function in a loop with increasing values for x until reaching UNKNOWN_SEMANTICS, it is possible to inspect all instances of a specific category. The return value is the semantics of the corresponding instance of this type and might be used in calling HDT_FindEntry() or the device driver initialization function.

int HDT_TypeCount(TypeID typeid)

This function returns the number of entries found for a specific type identifier.

char *HDT_GetString(TypeID typeid,DeviceSemantics semantics)

This function returns the readable name found in the entry associated with the given type and semantics.

Normally, an application program does not need to bother with the internal structure of the HDT. It can simply call the driver functions with the defined semantics as shown in an example for the motor driver functions in Program B.3. For details of all HDT entries see Appendix C.

382

Boot Procedure

Program B.3: Example of HDT usage

1/* Step1: Define handle variable as a motor reference */

2MotorHandle leftmotor;

3

4/* Step2: Initialize handle with the semantics (name) of

5chosen motor. The function will search the HDT

6for a MOTOR entry with given semantics and, if

7successful, initialize motor hardware and return

8the corresponding handle */

9leftmotor = MOTORInit(LEFTMOTOR);

10

11/* Step3: Use a motor command to set a certain speed.

12Command would fail if handle was not initial. */

13MOTORDrive (leftmotor,50);

14

15/* Step4: Release motor handle when motor is no longer

16needed */

17MOTORRelease (leftmotor);

B.4 Boot Procedure

The time between switching on the EyeCon controller and the display of the RoBIOS user interface is called the boot phase. During this time numerous actions are performed to bring the system up to an initialized and well-defined state.

In the beginning, the CPU is trying to fetch the start address of an executable program from memory location $000004. Since the RAM is not yet initialized, the default memory area for the CPU is the flash-ROM, which is activated by the hardware chip-select line CSBOOT’ and therefore is internally mapped to address $000000. As shown in Figure 1.11, RoBIOS starts at exactly that memory location, so the CPU will start executing the RoBIOS bootstrap loader, which precedes the compressed RoBIOS binary. This code initializes the CPU chip-select signals for the RAM chips, so that the compressed RoBIOS can later be unpacked into RAM. Furthermore, the address mapping is changed so that after the unpacking the RAM area will start at address $000000, while the ROM area will start at $C00000.

It seems to be a waste of RAM space to have RoBIOS in ROM and in RAM, but this offers a number of advantages. First, RAM access is about three times faster than ROM access because of different waitstates and the 16bit RAM bus compared to the 8bit ROM bus. This increases RoBIOS performance considerably. Secondly, it allows storage of the RoBIOS image in compressed form in ROM, saving ROM space for user programs. And finally, it allows the use of self-modifying code. This is often regarded as bad programming style, but can result in higher performance, e.g for time consuming tasks like frame grabbing or interrupt handling. On the other hand, a RAM location has the disadvantage of being vulnerable to memory modifications caused by

383


B RoBIOS Operating System

user programs, which can temporarily lead to an unexpected system behavior or a total crash. However, after a reset everything will work fine again, since a new RoBIOS copy will be read from the protected flash-ROM.

After the RAM chips and all other required chip-select pins have been initialized, the start-up code copies a small decompression algorithm to a CPUlocal RAM area (TPU-RAM), where it can be executed with zero waitstates, which speeds up the unpacking of the RoBIOS binary to external RAM. Finally, after having placed the executable RoBIOS image in the address area from $000000 to $020000, the start-up code jumps into the first line of the now uncompressed RoBIOS in RAM, where the remaining initialization tasks are performed. Among those are the test for additional mounted RAM chips and the subsequent calculation of the actual RAM size.

In the same manner the ROM size is checked, to see if it exceeds the minimum of 128KB. If so, RoBIOS knows that user programs can be stored in ROM. Now it is checked if a new HDT is located at the first user ROM slot. In this case, a short message is printed on the LCD that the re-programming of the flash-ROM will take place before the system continues booting. Now that an HDT is available, RoBIOS checks it for integrity and starts extracting information from it like the desired CPU clock rate, or the waitstate settings for different chip-select lines. Finally, the interrupt handlers, the 100Hz system timer, and some basic drivers, for example for serial interface, ADC, in/out-latches and audio, are started just before the welcome screen is shown and a melody is played.

Before displaying the standard monitor status screen, RoBIOS has to check whether a program called “startup.hex” or “startup.hx” is stored in ROM. If this is the case, a turn-key system has been created and the application program will be loaded and started immediately, unless a button is being pressed. This is very useful for an embedded application of the EyeCon controller or in the case when no LCD is mounted, which obviously would make a manual user program start difficult.

B.5 RoBIOS Library Functions

This section describes the RoBIOS operating system library routines in version 6.5 (2006). Newer versions of the RoBIOS software may differ from the functionality described below – see the latest software documentation. The following libraries are available in ROM for programming in C.

In application files use:

#include "eyebot.h"

The following libraries are available in ROM for programming in C and are automatically linked when calling "gcc68" and the like (using librobi.a).

Note that there are also a number of libraries available which are not listed here, since they are not in ROM but in the EyeBot distribution (e.g. elaborate

384

RoBIOS Library Functions

image processing library). They can also be linked with an application program, as shown in the demo programs provided.

Return Codes

Unless specifically noted otherwise, all routines return 0 when successful, or a value !=0 when an error has occurred. Only very few routines support multiple return codes.

B.5.1 Image Processing

A few basic image processing functions are included in RoBiOS. A larger collection of image processing functions is contained in the "image processing library", which can be linked to an application program.

Data Types:

/* image is 80x60 but has a border of 1 pixel */ #define imagecolumns 82

#define imagerows 62

typedef BYTE image[imagerows][imagecolumns]; typedef BYTE colimage[imagerows][imagecoulmns][3];

int IPLaplace (image *src, image *dest);

Input:

(src) source b/w image

image

Output:

(dest) destination b/w

Semantics:

The Laplace operator is applied to the source image

and the result is written to the destination image

int IPSobel (image *src, image *dest);

Input:

(src) source b/w image

image

Output:

(dest) destination b/w

Semantics:

The Sobel operator is applied to the source image

and the result is written to the destination image

int IPDither (image *src, image *dest);

Input:

(src) source b/w image

image

Output:

(dest) destination b/w

Semantics:

The Dithering operator

with a 2x2 pattern is applied

to the source image and the result is written to the

destination image

int IPDiffer (image *current, image *last, image *dest);

Input:

(current) the current b/w image

Output:

(last) the last read b/w image

(dest) destination b/w

image

Semantics:

Calculate the grey level difference at each pixel

position between current and last image, and

store the result in destination.

int IPColor2Grey (colimage *src, image *dest);

Input:

(src) source color image

Output:

(dest) destination b/w

image

Semantics:

Convert RGB color image given as source to 8-bit

grey level image and store the result in

destination.

Advanced image processing functions are available as library "improc.a". For detailed info see the Improv web-page:

http://robotics.ee.uwa.edu.au/improv/

385


B RoBIOS Operating System

B.5.2 Key Input

Using the standard Unix "libc" library, it is possible to use standard C "scanf" commands to read key "characters" from the "keyboard".

int KEYGetBuf (char *buf);

Input:

(buf) a pointer to one character

Output:

(buf) the keycode is written into the buffer

Valid keycodes are: KEY1,KEY2,KEY3,KEY4 (keys

Semantics:

from

left to right)

Wait

for a keypress and store the keycode into

the buffer

int KEYGet (void);

Input:

NONE

Output:

(returncode) the keycode of a pressed key is returned

Valid

keycodes are: KEY1,KEY2,KEY3,KEY4 (keys

Semantics:

from left to right)

Wait

for a keypress and return keycode

int KEYRead (void);

Input:

NONE

Output:

(returncode) the keycode of a pressed key is

returned or 0 if no key is pressed.

Valid keycodes are: KEY1,KEY2,KEY3,KEY4 (keys

Semantics:

from

left to right) or 0 for no key.

Read

keycode and return it. Function does not wait.

int KEYWait (int excode);

Input:

(excode) the code of the key expected to be pressed

Valid

keycodes are: KEY1,KEY2,KEY3,KEY4 (keys

Output:

from

left to right) or ANYKEY.

NONE

for a specific key

Semantics:

Wait

B.5.3 LCD Output

Using the standard Unix "libc" library, it is possible to use standard C "printf" commands to print on the LCD "screen". E.g. the "hello world" program works:

printf("Hello, World!\n");

The following routines can be used for specific output functions:

int LCDPrintf (const

char format[], ...);

Input:

format string and parameters

Output:

NONE

Semantics:

Prints text or numbers or combination of both

onto

LCD. This is a simplified and smaller

version of standard Clib "printf".

int LCDClear (void);

Input:

NONE

Output:

NONE

Semantics:

Clear the LCD

int LCDPutChar (char

char);

Input:

(char) the character to be written

Output:

NONE

Semantics:

Write the given character to the current cursor

386