AnsweredAssumed Answered

CW doesn't seem to compile Far functions properly

Question asked by Neil Garner on Oct 23, 2009
Latest reply on Oct 24, 2009 by Neil Garner

Using CW 4.7 (with patch 4.7.1), target: 9S12XDT512

Application is TCP-IP stack implemented as a ROM library installed in processor memory, prior to installing an application program. ROM library is located in a far code segment and banked model is being used to construct the library as a project in its own right. Customised application programs will be built as separate projects that can call functions from the common firmware library.

I have written most functions for a module called UDPIP, based loosely on Freescale AN2304. This module covers Layer 3 of the OSI protocol stack: Ethernet driver below it, a TCP module above it, and an HTTP module above that. The 'middle layer' primarily implements IP, but with UDP and ICMP thrown in.

So far I have written and (mostly) tested and debugged the following functions:

Sending:

UDP_Write() : invoked by higher layer when UDP protocol req'd - mainly for DHCP client
IP_Write() : invoked by UDP_Write() and - when I get to it - TCP_Write()

Receiving:

IP_Receive() : invoked as a callback from lower layer
ICMP_Receive() : invoked by IP_Receive() if protocol is ICMP - generates Echo Reply to a Ping
UDP_Handler() : invoked by IP_Receive() if protocol is ICMP
 - others to follow


Problem:

The compiler INSISTS on treating UDP_Write() as the subject of a near function call - assembly code shows RTS at the end, whereas all others show RTC. I've tried the following:

- naming the code segment with and without the __FAR qualifier
- including and not including the __far prefix with the UDP_Write() prototype (and with the function name in the source code)
- messing about with linker segments and placements

- looking through past 12 months of posts on this board
- tearing hair out
- etc

The only difference between UDP_Write() and other functions in this module is that it has a dependency (IP_Write()) in the same module; this situation may change in due course, as more of the module and other modules are written.

UDP_Write() calls IP_Write() using a far call, as you'd expect with the banked model and without pragmas to override. But UDP_Write() in general would be called from another module, and possibly from another page of code memory. It is essential that, in general, this function be called using a far call. But the compiler insists it is a near function, while all the others are allowed to be far functions.

What could be special about a function in a far segment that makes the compiler treat it as a near 'callee', and put an RTS at the end instead of RTC?

Message Edited by bottom_down_programmer on 2009-10-23 09:38 PM

Outcomes