This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Type of alarm-function


On Wed, Mar 05, 2008 at 01:52:16PM +0100, Thomas Kl??ber wrote:
> Hello all,
> 
> I am porting eCos to the Infineon TriCore TC1796 as part of my studies. I am 
> using the kernel testcases to verify it's working, most ones are running just 
> fine. During stepping throug kclock0.c as it wouldn't work, I found the 
> following:
> 
> The prototype for an alarm handler function in the C kernel api is
> 
> void alarm_handler(cyg_handle_t alarm, cyg_addrword_t data)
> 
> with cyg_handle_t being a cyg_uint32. The internal kernel prototype for 
> calling the function however is
> 
> void cyg_alarm_fn(Cyg_Alarm *alarm, CYG_ADDRWORD data)
> 
> Note  that the first argument is a pointer in this case. While on most 
> architectures this does not make any difference, it circumvents passing of 
> parameters to the function.
> 
> The TC1796 has separate registers for addresses and for data which are used 
> for passing parameters. When calling a function of type cyg_alarm_fn, the 
> compiler puts the first argument into an address register (%a4) and the 
> second one into a data register (%d4). Unfortunately, the called function has 
> the type alarm_handler, so the compiler trys to read both values from data 
> registers (%d4 and %d5) when entering the function.
> 
> The result is that neither of the arguments is passed correctly to the 
> function as the first one lies in %a4 instead of %d4 and the second one lies 
> in %d4 instead of %d5.

Interesting behaviour. Never heard of this before. 

I suspect there is more broken than just alarms. In the C world a
cyg_handle_t is an abstract type used to represent an object. Inside
the kernel in the C++ world the handle is cast to a C++ object.

The alarm code uses the following to call the alarm function:

 // Call alarm function
alarm->alarm(alarm, alarm->data);

ie it passes the C++ alarm object to the C function and relies on the
fact that a handle and the object are the same thing. So probably all
callbacks from the kernel are broken for you. One that springs to mind
is the entry point to a thread. 

One fix might be to change the type of cyg_handle_t. 
typedef cyg_addrword_t cyg_handle_t;        /* Object handle
typedef CYG_ADDRWORD   cyg_addrword_t;      /* May hold pointer or word
typedef cyg_haladdrword CYG_ADDRWORD;

and in /packages/infra/current/include/cyg_type.h

#ifndef cyg_haladdrword
# define cyg_haladdrword cyg_uint32
#endif

Your HAL is allowed to override this definition. 

Does the compiler ABI have a type which can hold both an 32 bit word
and a pointer? 

You probably also want to look at 

#ifndef cyg_haladdress
# define cyg_haladdress cyg_uint32
#endif

in the same file.

   Andrew

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]