Mobile communication system with cross compiler and cross linker6029000Abstract A wireless data platform (10) comprises a plurality of processors (12,16). Channels of communication are set up between processors such that they may communicate information as tasks are performed. A dynamic cross compiler (80) executed on one processor compiles code into native processing code for another processor. A dynamic cross linker (82) links the compiled code for other processor. Native code may also be downloaded to the platform through use of a JAVA Bean (90) (or other language type) which encapsulates the native code. The JAVA Bean can be encrypted and digitally signed for security purposes. Claims We claim: Description BACKGROUND OF THE INVENTION
TABLE 1
______________________________________
Task Creation Structure.
Field
Data Type
Name Description
______________________________________
T.sub.-- DSP.sub.-- Name
Name User defined name for the task.
U32 MIPS
MIPS used by the task.
T.sub.-- ChanID
ChanIn The channel ID used for task input.
T.sub.-- ChanID
ChanOut The channel ID used for task output.
T.sub.-- StrmID
StrmIn The stream ID used for task input.
T.sub.-- StrmID
StrmOut The stream ID used for task output.
U16 The task's priority.
U32 The task's timeslice in system ticks.
T.sub.-- Size
StackReq
The amount of stack required.
T.sub.-- DSP.sub.-- Ptr
MsgHandler
Pointer to code to handle messages to the
task.
T.sub.-- HOST.sub.-- Ptr
CallBack
Pointer to Host code to handle messages
from the task.
T.sub.-- DSP.sub.-- Ptr
Create Pointer to code to execute when task is
created.
T.sub.-- DSP.sub.-- Ptr
Start Pointer to code to execute when task is
started.
T.sub.-- DSP.sub.-- Ptr
Suspend
Pointer to code to execute when task is
suspended.
T.sub.-- DSP.sub.-- Ptr
Resume Pointer to code to execute when task is
resumed.
T.sub.-- DSP.sub.-- Ptr
Stop Pointer to code to execute when task is
stopped.
______________________________________
Once the task is created, the Create entry point will be called, giving the task the opportunity to do any necessary preliminary initialization. The Create, Suspend, Resume, and Stop entry points can be Null. The resultant Task ID contains both the device ID (DevID), and the DSP's task ID. If the TaskID is NULL, the create failed. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- INVALID.sub.-- PRIORITY DSP.sub.-- CHANNEL.sub.-- NOT.sub.-- FOUND DSP.sub.-- ALLOCATION.sub.-- ERROR DSP.sub.-- Start.sub.-- Task BOOL DSP.sub.-- Start.sub.-- Task(T.sub.-- TaskID TaskID, U16 *errcode); This function will start a DSP task specified by Task ID. Execution will begin at the task's Start entry point. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- TASK.sub.-- NOT.sub.-- FOUND DSP.sub.-- Suspend.sub.-- Task BOOL DSP.sub.-- Suspend.sub.-- Task(T.sub.-- TaskID TaskID, U16 *errcode); This function will suspend a DSP task specified by TaskID. Prior to being suspended, the task's Suspend entry point will be called to give the task a chance to perform any necessary housekeeping. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- TASK.sub.-- NOT.sub.-- FOUND DSP.sub.-- Resume.sub.-- Task BOOL DSP.sub.-- Resume.sub.-- Task(T.sub.-- TaskID TaskID, U16 *errcode); This function will resume a DSP task that was suspended by DSP.sub.-- Suspend.sub.-- Task. Prior to being resumed, the task's Resume entry point will be called to give the task a chance to perform any necessary housekeeping. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- TASK.sub.-- NOT.sub.-- FOUND DSP.sub.-- TASK.sub.-- NOT.sub.-- SUSPENDED DSP.sub.-- Delete.sub.-- Task BOOL DSP.sub.-- Delete.sub.-- Task(T.sub.-- TaskID TaskID, U16 *errcode); This function will delete a DSP task specified by TaskID. Prior to the deletion, the task's Stop entry point will be called to give the task a chance to perform any necessary cleanup. This should include freeing any memory that was allocated by the task, and returning any resources the task acquired. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- TASK.sub.-- NOT.sub.-- FOUND DSP.sub.-- Change.sub.-- Task.sub.-- Priority BOOL DSP.sub.-- Change.sub.-- Task.sub.-- Priority(T.sub.-- TaskID TaskID, U16 newpriority, U16 *oldpriority, U16 *errcode); This function will change the priorty of a DSP task specified by TaskID. The priority will be changed to newpriority. The possible values of newpriority are RTOS dependent. Upon return, the oldpriority parameter will be set to the previous priority of the task. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- TASK.sub.-- NOT.sub.-- FOUND DSP.sub.-- INVALID.sub.-- PRIORITY DSP.sub.-- Get.sub.-- Task.sub.-- Status BOOL DSP.sub.-- Get.sub.-- Task.sub.-- Status(T.sub.-- TaskID TaskID, U16 *status, U16 *priority, T.sub.-- ChanID *Input, T.sub.-- ChanID *Output, U16 *errcode); This function returns the status for a DSP task specified by TaskID. The status will be one of the following values: DSP.sub.-- TASK.sub.-- RUNNING DSP.sub.-- TASK.sub.-- SUSPENDED DSP.sub.-- TASK.sub.-- WAITFOR.sub.-- SEM DSP.sub.-- TASK.sub.-- WAITFOR.sub.-- QUEUE DSP.sub.-- TASK.sub.-- WAITFOR.sub.-- MSG The priority parameter will contain the task's priority, and the Input and Output parameters will contain the task's input and output channel IDs, respectively. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- TASK.sub.-- NOT.sub.-- FOUND DSP.sub.-- Get.sub.-- ID.sub.-- From.sub.-- Name BOOL DSP.sub.-- Get.sub.-- ID.sub.-- From.sub.-- Name(T.sub.-- DeviceID DevID, T.sub.-- DSP.sub.-- Name Name, T.sub.-- DSP.sub.-- ID *ID, U16 *errcode); This function returns the ID for a named object on the DSP 16. The named object may be a channel, a task, a memory block, or any other supported named DSP object. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- NAME.sub.-- NOT.sub.-- FOUND DSP.sub.-- Dbg.sub.-- Read.sub.-- Mem BOOL DSP.sub.-- Dbg.sub.-- Read.sub.-- Mem(DEVICE.sub.-- ID DevID, U8 mempage, DSP.sub.-- PTR addr, U32 count, DSP.sub.-- WORD *buf, U16 *errcode); This function requests a block of memory. The mempage specifies program memory (0) or data memory (1). The addr parameter specifies the memory starting address, and the count indicates how many T.sub.-- DSP.sub.-- Words to read. The buf parameter is a pointer to a caller provided buffer to which the memory should be copied. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- INVALID.sub.-- MEMPAGE DSP.sub.-- Dbg.sub.-- Write.sub.-- Mem BOOL DSP.sub.-- Dbg.sub.-- Write.sub.-- Mem(T.sub.-- DeviceID DevID, U16 mempage, T.sub.-- DSP.sub.-- Ptr addr, T.sub.-- Count count, T.sub.-- DSP.sub.-- Word *buf, U16 *errcode); This function writes a block of memory. The mempage specifies program memory (0) or data memory(1). The addr parameter specifies the memory starting address, and the count indicates how many T.sub.-- DSP.sub.-- Words to write. The buf parameter is a pointer the buffer containing the memory to write. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DEP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- INVALID.sub.-- MEMPAGE DSP.sub.-- Dbg.sub.-- Read.sub.-- Reg BOOL DSP.sub.-- Dbg.sub.-- Read.sub.-- Reg(T.sub.-- DeviceID DevID, U16 RegID, T.sub.-- DSP.sub.-- Word *regvalue, U16 *errcode), This function reads a DSP register and returns the value in regvalue. The RegID parameter specifies which register to return. If the RegID is -1, then all of the register values are returned. The regvalue parameter, which is a pointer to a called provided buffer, should point to sufficient storage to hold all of the values. The register IDs are DSP specific and will depend on a particular implementation. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- INVALID.sub.-- REGISTER DSP.sub.-- Dbg.sub.-- Write.sub.-- Reg BOOL DSP.sub.-- Dbg.sub.-- Write.sub.-- Reg(T.sub.-- DeviceID DevID, U16 RegID, T.sub.-- DSP.sub.-- Word regvalue, U16 *errcode); This function writes a DSP register. The RegID parameter specifies which register to modify. regvalue contains the new value to write. The register IDs are DSP specific and will depend on a particular implementation. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- INVALID.sub.-- REGISTER DSP.sub.-- Dbg.sub.-- Set.sub.-- Break BOOL DSP.sub.-- Dbg.sub.-- Set.sub.-- Break(T.sub.-- DeviceID DevID, DSP.sub.-- Ptr addr, U16 *errcode); This function sets a break point at the given code address (addr). The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- Dbg.sub.-- Clr.sub.-- Break BOOL DSP.sub.-- Dbg.sub.-- Clr.sub.-- Break(T.sub.-- DeviceID DevID, T.sub.-- DSP.sub.-- Ptr adddr, U16 *errcode); This function clears a break point that was previously set by DSP.sub.-- Dbg.sub.-- Set.sub.-- Break at the given code address (addr). The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- BP.sub.-- DID.sub.-- NOT.sub.-- EXIST DSP DEVICE DRIVER The DSP Device Driver 54 handles communications from the Host 12 to the DSP 16. The driver functions will take the communication requests as specified in the Host-DSP Communications Protocol and handle the transmission of the information via the available hardware interface. The device driver is RTOS dependent and communications hardware dependent. DSP LIBRARY The DSP Library 58 contains the blocks of code that can be downloaded to the DSP 16 for execution. Each block of code will be previously unlinked, or relocatably linked as a library, so that the dynamic cross linker can resolve all address references. Each code block will also include information about the block's requirements for DSP MIPS (millions of instructions per second), priority, time slice quantum, and memory. The format for the code block header is shown in Table 2. The program memory and data memory sizes are approximations to give the Host 12 a quick check on whether the DSP can support the task's memory requirements. If there appears to be sufficient space, the dynamic cross linker can then attempt to link and load the code. It should be noted that the dynamic cross linker could still fail, due to page alignment and contiguity requirements. In the preferred embodiment, the code is in a version 2 COFF file format.
TABLE 2
______________________________________
Code Block Header.
Data Type
Field Name Description
______________________________________
U16 Processor The target processor type.
T.sub.-- DSP.sub.--l Name
Name Task's name.
U32 MIPS
Worst case MIPS required by the task.
T.sub.-- Size
ProgSize
Total program memory size needed.
T.sub.-- Size
DataSize
Total data memory size needed.
T.sub.-- Size
InFrameSize
Size of a frame in the task's input
channel.
T.sub.-- Size
OutFrameSize
Size of a frame in the task's output
channel.
T.sub.-- Size
InStrmSize
Size of the task's input stream FIFO.
T.sub.-- Size
OutStrmSize
Size of the task's output stream FIFO.
U16 Task's priority.
U32 Task's time slice quantum (number of
system ticks).
T.sub.-- Size
StackReq
Stack required.
T.sub.-- Size
CoffSize
Total size of the COFF file.
T.sub.-- DSP.sub.-- Ptr
MsgHandler
Offset to a message handler entry point
for the task.
T.sub.-- DSP.sub.-- Ptr
Create Offset to a create entry point that is
called when the task is created.
T.sub.-- DSP.sub.-- Ptr
Start Offset to the start of the task's code.
T.sub.-- DSP.sub.-- Ptr
Suspend
Offset to a suspend entry point that is
called prior to the task being suspended.
T.sub.-- DSP.sub.-- Ptr
Resume Offset to a resume entry point that is
called prior to the task being resumed.
T.sub.-- DSP.sub.-- Ptr
Stop Offset to a stop entry point that is called
prior to the task being deleted.
T.sub.-- Host.sub.-- Ptr
CoffPtr Pointer to the location of the COFF data
in the DSP Library.
______________________________________
CONVERSION OF PORTABLE CODE INTO LINKED TARGET CODE A procedure for converting portable (processor independent) code, such as JAVA code, into linked target code is shown in FIG. 3. The procedure uses two functions, a dynamic cross compiler 80 and a dynamic cross linker 82. Each function is implemented on the host processor 12. The dynamic cross linker is part of the DSP-API in the preferred embodiment. The cross compiler may also be part of the DSP-API. The dynamic cross compiler 80 converts portable code into unlinked, executable target processor code. The dynamic cross linker 82 converts the unlinked, executable target processor code into linked, executable target processor code. To do so, it must resolve addresses within a block of code, prior to loading on the DSP 16. The dynamic cross linker 82 links the code segments and data segments of the function, allocates the memory on the DSP 16, and loads the code and constant data to the DSP 16. The functions are referred to as "cross" compiling and "cross" linking, because the functions (compiling and linking) occur on a different processor (i.e., the host processor 12) from the target processor which executes the code (i.e., the DSP 16). The dynamic cross compiler 80 accepts previously unlinked code loaded on demand by a user or a user agent (such as a browser). The code is processed to either (1) identify "tagged" sections of the code or (2) analyze untagged code segments for suitability of execution on the DSP 16. A tagged section of source code could delineate source targetable to a DSP by predetermined markers such as "<start DSP code>" and <end DSP code>" embedded in the source code. If a tagged section is identified either directly or through analysis, a decision is made to either cross compile or not based on the current processing state of the DSP 16. If a decision is made to compile, the section of code processed by compiling software that outputs unlinked, executable target processor code, using well known compiling methods. A decision not to compile could be made if for example, the DSP has insufficient available processing capacity (generally stated as available MIPS--million of instructions per section) or insufficient available memory, due to other tasks being executed by the DSP 16. The compiled code can be passed to the dynamic cross linker 82 for immediate use in the DSP 16, or could be saved in the DSP library 58. The dynamic cross linker 82 accepts previously unlinked code, which is either (1) statically stored in connection with the host processor 12 or (2) dynamically downloaded to the host processor 12 over a network connection (including global networks such as the Internet) or (3) dynamically generated by the dynamic cross compiler 80. The dynamic cross linker 82 links the input code for a memory starting address of the DSP 16 determined at runtime. The memory starting address can be determined from a memory map or memory table stored on and managed by either the host processor 12 or DSP 16. The dynamic cross linker 82 convert referenced memory location sin the code to actual memory locations in the DSP. These memory locations could include, for example, branch addresses in the code or references to locations of data in the code. In the preferred embodiment, the portable code is in a COFF (common object file format) which contains all information about the code, including whether it is linked or unlinked. If it is unlinked, symbol tables define the address which must be changed for linking the code. The conversion process described above has several significant advantages over the prior art. First, the dynamic cross compiler 80 allows run-time decisions to be made about where to execute the downloaded portable code. For example, in a system with multiple target processors (such as two DSPs 16), the dynamic cross compiler 80 could compile the portable code to any one of the target processors based on available resources or capabilities. The dynamic cross linker 82 provides for linking code to run on a target processor which does not support relocatable code. Since the code is linked at run-time, memory locations in the DSP 16 (or other target processor) do not need to be reserved, allowing optimum efficiency of use of all computing resources in the device. Because the compiling is accomplished with knowledge of the architecture of the platform 10, the compiling can take advantage of processor and platform specific features, such as intelligent cache architectures in one or both processors. Thus, the DSP 16 can have various functions which are changed dynamically to fully use its processing capabilities. For example, the user may wish to load a user interface including voice recognition. At that time, the host processor could download software and dynamically cross compile and cross link the voice recognition software for execution in the DSP 16. Alternatively, previously compiled software in the DSP library 58 could be dynamically cross linked, based on the current status of the DSP 16, for execution. HOST DEVICE DRIVER The Host Device Driver handles communications from the DSP 16 to the Host 12. The driver functions takes the communication requests as specified in the Host-DSP Communications Protocol and handles transmission of the information via the available hardware interface. The device driver is RTOS dependent and communications hardware dependent. HOST-DSP COMMUNICATIONS PROTOCOL (HOST-DSP INTERFACE LAYER) The Host-DSP Communications Protocol governs the communications of commands and data between the Host 12 and the DSP 16. The communications consist of several paths: messages, data channels, and streams. Messages are used to send initialization parameters and commands to the tasks. Data channels carry large amounts of data between tasks and between the DSP 16 and Host 12, in the form of data frames. Streams are used to pass streamed data between tasks and between the DSP 16 and Host 12. Messages Each task has an entry point to a message handler, which handles messages. The messages are user defined and will include initialization parameters for the task's function, and commands for controlling the task. The tasks send messages to the Host 12 via the callback specified when the task is created. The prototype for the task's message handler and the prototype for the Host's callback are shown here: void TaskMsgHandler(T.sub.-- ReplyRef replyref, T.sub.-- MsgID MsgID, T.sub.-- Count count, T.sub.-- DSP.sub.-- Word *buf); void HostCallBack(T.sub.-- ReplyRef replyref, T.sub.-- MsgID MsgID, T.sub.-- Count count, T.sub.-- DSP.sub.-- Word *buf); The replyref parameter refers to an implementation dependent reference value, which is used to route the reply back to the sender. For every Send.sub.-- Message call, the recipient must call Reply.sub.-- Message using the replyref parameter. The actual messages may appear as follows:
______________________________________
Sent message:
MsgPktFlag
taskid replyref
msgid count
buf[.....]
Reply message:
MsgPktFlag
-1 replyref
msgid
count
buf[.....]
______________________________________
The multiword data is sent least significant word first. A TaskID of 0 in the Send.sub.-- Message function indicates a system level message. The system level messages are used to implement the DSP-API functions Following are the Message functions: Send.sub.-- Message BOOL Send.sub.-- Message(T.sub.-- TaskID TaskID, T.sub.-- MsgID MsgID, T.sub.-- Count count, T.sub.-- DSP.sub.-- Word *msgbuf, T.sub.-- DSP.sub.-- Word *replybuf, T.sub.-- Size replybufsize, T.sub.-- Count replycount, U16 *errcode); This function will send a user defined message to a task specified by TaskID. The MsgID defines the message, and the msgbuf contains the actual message data. The message size is count T.sub.-- DSP.sub.-- Words. The reply to the message will be contained in the replybuf parameter, which points to a buffer of size replybufsize, provided by the caller. It should be of sufficient size to handle the reply for the particular message. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- TASK.sub.-- NOT.sub.-- FOUND Reply.sub.-- Message BOOL Reply.sub.-- Message(T.sub.-- ReplyRef replyref, T.sub.-- Count count, T.sub.-- DSP.sub.-- Word *buf, U16 *errcode); This function is used to reply to messages. The replyref parameter is a reference used to route the reply back to the sender of the original message, and is implementation specific. The reply is contained in the buf parameter and its size is count T.sub.-- DSP.sub.-- Words. The errcode parameter will contain the following possible results: DSP.sub.-- SUCCESS DSP.sub.-- DEVID.sub.-- NOT.sub.-- FOUND DSP.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING DSP.sub.-- BAD.sub.-- REPLY .sub.-- REF CHANNELS The concept of channels is used to transmit frame-based data from one processor to another, or between tasks on the same processor. When created, a channel allocates a specified number and size of frames to contain the data. Initially, the channel will contain a list of empty frames. Tasks that produce data will request empty frames in which output the data, then once filled, the frame is returned to the channel. Tasks that consume data will request full frames from the channel, and once emptied, the frame is returned to the channel. This requesting and returning of frame buffers allows data to move about with a minimum of copying. Each task has a specified Input and Output channel. Once a channel is created, it should be designated as the input to one task, and the output to another task. A channel's ID includes a device ID, so channels can pass data between processors. Channel data flow across the Host-DSP interface may appear as follows:
______________________________________
ChanPktFlag Channel ID Count Data[...]
______________________________________
The following are the channel functions: Create.sub.-- Channel BOOL Create.sub.-- Channel(T.sub.-- DeviceID DevID, T.sub.-- Size framesize, T.sub.-- Count numframes, T.sub.-- ChanID *ChannelID, U16 *errcode); This function creates a data frame-based communication channel. This creates a channel control structure, which maintains control of a set of frame buffers, whose count and size are specified in the numframes and framesize parameters, respectively. When created, the channel allocates the data frames, and adds them to its list of empty frames. ChannelID will return the ID of the new channel. If the DevID is not that of the calling processor, a channel control structure is created on both the calling processor and the DevID processor, to control data flowing across the communications interface. The errcode parameter will contain the following possible results: CHAN.sub.-- SUCCESS CHAN.sub.-- DEVID.sub.-- NOT.sub.-- FOUND CHAN.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING CHAN.sub.-- ALLOCATION.sub.-- ERROR Delete.sub.-- Channel BOOL Delete.sub.-- Channel(T.sub.-- ChanID ChannelID, U16 *errcode); This function deletes an existing channel specified by ChannelID. The errcode parameter will contain the following possible results: CHAN.sub.-- SUCCESS CHAN.sub.-- DEVID.sub.-- NOT.sub.-- FOUND CHAN.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING CHAN.sub.-- CHANNEL.sub.-- NOT.sub.-- FOUND Request.sub.-- Empty.sub.-- Frame BOOL Request.sub.-- Empty.sub.-- Frame(T.sub.-- LocalChanID Chn, T.sub.-- DSP.sub.-- Word **bufptr, BOOL WaitFlag, U16 *errcode); This function requests an empty frame from the specified local channel ID. If Chn is Null, then the task's output channel is used. Upon return, the bufptr parameter will contain the pointer to the frame buffer. If the WaitFlag is TRUE, and there is not frame buffer available, the caller will be suspended until a buffer becomes available. If the WaitFlag is FALSE, the function will return regardless. The errcode parameter will contain the following possible results: CHAN.sub.-- SUCCESS CHAN.sub.-- CHANNEL.sub.-- NOT.sub.-- FOUND CHAN.sub.-- BUFFER.sub.-- UNAVAILABLE Return.sub.-- Full.sub.-- Frame BOOL Return.sub.13 Full.sub.-- Frame(T.sub.-- LocalChanID Chn, T.sub.-- DSP.sub.-- Word *bufptr, U16 *errcode); Once a task has filled a frame buffer, it returns is to the channel suing this function. The buffer pointed to by bufptr is returned to the channel ID specified. If Chn is Null, then the task's output channel is used. The errcode parameter will contain the following possible results: CHAN.sub.-- SUCCESS CHAN.sub.-- CHANNEL.sub.-- NOT.sub.-- FOUND CHAN.sub.-- BUFFER.sub.-- CTRL.sub.-- ERROR Request.sub.-- Full.sub.-- Frame BOOL Request.sub.-- Full.sub.-- Frame(T.sub.-- LocalChanID Chn, T.sub.-- DSP.sub.-- Word **bufptr, BOOL WaitFlag, U16 *errcode); This function requests a full frame of data from the specified local channel ID. If Chn is NULL, then the task's input channel is used. Upon return, the bufptr parameter will contain the pointer to the frame buffer. If the WaitFlag is TRUE, and there are no full frame buffers available, the caller will be suspended until a buffer becomes available. If the WaitFlag is FALSE, the function will return regardless. The errcode parameter will contain the following possible results: CHAN.sub.-- SUCCESS CHAN.sub.-- CHANNEL.sub.-- NOT.sub.-- FOUND CHAN.sub.-- BUFFER.sub.-- UNAVAILABLE Return.sub.-- Empty.sub.-- Frame BOOL Return.sub.-- Empty.sub.-- Frame(T.sub.-- LocalChanID Chn, T.sub.-- DSP.sub.-- Word *bufptr, U16 *errcode); Once a task has used the data from a frame buffer, it should return the buffer to the channel using this function. The buffer pointed to by bufptr is returned to the channel ID specified. If Chn is NULL, then the task's input channel is used. The errcode parameter will contain the following possible results: CHAN.sub.-- SUCCESS CHAN.sub.-- CHANNEL.sub.-- NOT.sub.-- FOUND CHAN.sub.-- BUFFER.sub.-- CTRL.sub.-- ERROR Set.sub.-- Task.sub.-- Input.sub.-- Channel BOOL Set.sub.-- Task.sub.13 Input.sub.-- Channel(T.sub.-- Task *TaskID, T.sub.-- ChanID ChanID, U16 *errcode); This function sets a task's input channel to the specified channel ID. The errcode parameter will contain the following possible results: CHAN.sub.-- SUCCESS CHAN.sub.-- DEVID.sub.-- NOT.sub.-- FOUND CHAN.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING CHAN.sub.-- TASK.sub.-- NOT.sub.-- FOUND CHAN.sub.-- CHANNEL.sub.-- NOT.sub.-- FOUND Set.sub.-- Task.sub.-- Output.sub.-- Channel BOOL Set.sub.-- Task.sub.-- Output.sub.-- Channel(T.sub.-- Task *TaskID, T.sub.-- ChanID ChanID, U16 *errcode); This function sets a task's output channel to the specified channel ID. The errcode parameter will contain the following possible results: CHAN.sub.-- SUCCESS CHAN.sub.-- DEVID.sub.-- NOT.sub.-- FOUND CHAN.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING CHAN.sub.-- TASK.sub.-- NOT .sub.-- FOUND CHAN.sub.-- CHANNEL.sub.-- NOT.sub.-- FOUND Streams Streams are used for data, which can not be broken into frames, but which continuously flow into and out of a task. A stream will consist of a circular buffer (FIFO) with associated head and tail pointers to track the data as it flows in and out. Each task can have a designated input and output stream. Stream data flow across the Host-DSP interface may appear as follows:
______________________________________
StrmPktFlag Stream ID Count Data[...]
______________________________________
Following are the stream functions: Create.sub.-- Stream BOOL Create.sub.-- Stream(T.sub.-- DeviceID DevID, T.sub.-- Size FIFOsize, T.sub.-- StrmID *StreamID, U16 *errcode); This function creates a FIFO-based communication stream. This creates a stream control structure, which maintains control of a FIFO of size FIFOsize. When created, the stream allocates an empty FIFO, and initializes head and tail pointers to handle data flow into and out of the stream. StreamID will return the ID of the new stream. If the DevID is not that of the calling processor, a stream control structure is created on both the calling processor and the DevID processor, to control data flowing across the communications interface. The errcode parameter will contain the following possible results: STRM.sub.-- SUCCESS STRM.sub.-- DEVID.sub.-- NOT.sub.-- FOUND STRM.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING STRM.sub.-- ALLOCATION.sub.-- ERROR Delete.sub.-- Channel BOOL Delete.sub.-- Stream(T.sub.-- StrmID StreamID, U16 *errcode); This function deletes an existing stream specified by StreamID. The errcode parameter will contain the following possible results: STRM.sub.-- SUCCESS STRM.sub.-- DEVID.sub.-- NOT.sub.-- FOUND STRM.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING STRM.sub.-- STREAM.sub.-- NOT.sub.-- FOUND Get.sub.-- Stream.sub.-- Count BOOL Get.sub.-- Stream.sub.-- Count(T.sub.-- LocalStrmID StrmID, T.sub.-- Count *count, U16 *errcode); This function requests the count of T.sub.-- DSP.sub.-- Words currently in the stream FIFO specified by strmID. The count parameter will contain the number upon return. The errcode parameter will contain the following possible results: STRM.sub.-- SUCCESS STRM.sub.-- STREAM.sub.-- NOT.sub.-- FOUND Write.sub.-- Stream BOOL Write.sub.-- Stream(T.sub.-- LocalStrmID Strm, T.sub.-- DSP.sub.-- Word *bufptr, T.sub.-- Count count, T.sub.-- Count *countwritten, U16 *errcode); This function will write count number of T.sub.-- DSP.sub.-- Words to the stream specified by the Strm. If Strm is NULL, the task's output stream is used. The data is pointed to by the bufptr parameter. Upon return, countwritten will contain the number of T.sub.-- DSP.sub.-- Words actually written. The errcode parameter will contain the following possible results: STRM.sub.-- SUCCESS STRM.sub.-- DEVID.sub.-- NOT.sub.-- FOUND STRM.sub.-- DEVID.sub.-- NOT.sub.-- RESPONSIBLE STRM.sub.-- STREAM.sub.-- NOT.sub.-- FOUND STRM.sub.-- STREAM.sub.-- OVERFLOW Read.sub.-- Stream BOOL Read.sub.-- Stream(T.sub.-- LocalStrmID Strm, T.sub.-- DSP.sub.-- Word *bufptr, T.sub.-- Count maxcount, BOOL WaitFlag, T.sub.-- Count *countread, U16 *errcode); This function reads data from the stream specified by Strm. If Strm is NULL, the task's input stream is used. The data will be stored in the buffer pointed to by bufptr. Up to maxcount T.sub.-- DSP.sub.-- Words will be read from the stream. The countread parameter will contain the actual count of the data read. The errcode parameter will contain the following possible results: STRM.sub.-- SUCCESS STRM.sub.-- DEVID.sub.-- NOT.sub.-- FOUND STRM.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING STRM.sub.-- STREAM.sub.-- NOT.sub.-- FOUND Set.sub.-- Task.sub.-- Input.sub.-- Stream BOOL Set.sub.-- Task.sub.-- Input.sub.-- Stream(T.sub.-- Task *TaskID, T.sub.-- StrmID StrmID, U16 *errcode); This function sets a task's input stream to the specified stream ID. The errcode parameter will contain the following possible results: STRM.sub.-- SUCCESS STRM.sub.-- DEVID.sub.-- NOT.sub.-- FOUND STRM.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING STRM.sub.-- TASK.sub.-- NOT.sub.--L FOUND STRM.sub.-- STREAM.sub.-- NOT.sub.-- FOUND Set.sub.-- Task.sub.-- Output.sub.-- Stream BOOL Set.sub.-- Task.sub.-- Output.sub.-- Stream(T.sub.-- Task *TaskID, T.sub.-- StrmID StrmID, U16 *errcode); This function sets a task's output stream to the specified stream ID. The errcode parameter will contain the following possible results: STRM.sub.-- SUCCESS STRM.sub.-- DEVID.sub.-- NOT.sub.-- FOUND STRM.sub.-- DEVID.sub.-- NOT.sub.-- RESPONDING STRM.sub.-- TASK.sub.-- NOT.sub.-- FOUND STRM.sub.-- STREAM.sub.-- NOT.sub.-- FOUND DATA TYPES Data types used herein are defined in Table 3:
TABLE 3
______________________________________
Symbol Description
______________________________________
S8 Signed 8-bit integer.
U8 Unsigned 8-bit integer.
S16 Signed 16-bit integer.
U16 Unsigned 16-bit integer.
S32 Signed 32-bit integer.
U32 Unsigned 32-bit integer.
T.sub.-- HostWord
A word on the Host processor.
T.sub.-- DSP.sub.-- Word
A word on the DSP processor.
BOOL Boolean value (TRUE or FALSE).
T.sub.-- HostPtr
Pointer on the Host processor.
T.sub.-- DSP.sub.-- Ptr
Pointer on the DSP processor.
T.sub.-- DeviceID
Processor device ID.
T.sub.-- TaskID
A structure containing fields for a device ID and a
processor local task ID.
T.sub.-- ChanID
A structure containing fields for a device ID and a
processor local channel ID.
T.sub.-- MsgID
Message ID.
T.sub.-- DSP.sub.-- ID
An object ID on the DSP.
T.sub.-- Count
Data type for a count.
T.sub.-- Size
Data type for a size.
T.sub.-- HostCallBack
Value used when tasks send message back to the Host.
T.sub.-- ReplyRef
Message reply reference.
T.sub.-- LocalTaskID
Local rask ID.
T.sub.-- LocalChanID
Local channel ID.
T.sub.-- DSP.sub.-- Name
Name for DSP objects (RTOS dependent).
T.sub.-- CodeHdr
Code header structure for a DSP Library entry.
T.sub.-- TaskCreate
Task creation structure.
______________________________________
SYSTEM MESSAGES These tables define the messages passing between devices (i.e. Host to DSP 16). The device IDs present as parameters in the corresponding function calls are not incorporated in the messages since they are used to actually route the message to the device. Similarly, task IDs that include a device ID as their upper half for the function call will not include the device ID in the message, but only the DSP's local task ID portion.
TABLE 4
__________________________________________________________________________
DSP-API Messages
Direction
Message Send Parameters
Reply Parameters
Host DSP
__________________________________________________________________________
GET.sub.-- MIPS
None U32 mips .fwdarw.
GET.sub.-- MEM.sub.-- AVAIL
T.sub.-- Size progmem
.fwdarw.
T.sub.-- Size datamem
ALLOC.sub.-- MEM
U16 mempage T.sub.-- DSP.sub.-- Word*memptr
.fwdarw.
U16 errcodeb.-- Size size
FREE.sub.-- MEM
U16 mempage
U16 errcode
.fwdarw.
T.sub.-- DSP Word*memptr
PUT.sub.-- BLOB
T.sub.-- DSP.sub.-- Ptr destaddr
U16 errcode
.fwdarw.
U16 mempage
T.sub.-- Size size
T.sub.-- DSP.sub.-- Word BLOB[size]
CREATE.sub.-- TASK
T.sub.-- TaskCreate tcs
T.sub.-- TaskID TaskID
.fwdarw.
U16 errcode
START.sub.-- TASK
T.sub.-- TaskID TaskID
U16 errcode
.fwdarw.
SUSPEND.sub.-- TASK
T.sub.-- TaskID TaskID
U16 errcode
.fwdarw.
RESUME.sub.-- TASK
T.sub.-- TaskID TaskID
U16 errcode
.fwdarw.
DELETE.sub.-- TASK
T.sub.-- TaskID TaskID
U16 errcode
.fwdarw.
CHANGE.sub.-- PRIORITY
T.sub.-- TaskID TaskID
U16 oldpriority
.fwdarw.
U16 errcodety
GET.sub.-- TASK.sub.-- STATUS
T.sub.-- TaskID TaskID
U16 status
.fwdarw.
U16 priority
T.sub.-- ChanID Input
T.sub.-- ChanID Output
U16 errcode
GET.sub.-- ID
T.sub.-- DSP.sub.-- Name Name
T.sub.-- DSP.sub.-- ID ID
.fwdarw.
U16 errcode
__________________________________________________________________________
DOWNLOADING NATIVE CODE FIGS. 4-6 illustrate an embodiment for downloading native code to a target processor (i.e., the host 12 or DSP 16) in a secure and efficient manner. This embodiment for downloading code could be used, for example, in downloading code from the Internet, or other global network, from a Local or Wide Area Network, or from a peripheral device, such as a PC Card or Smartcard. In FIG. 4, an embodiment of a JAVA Bean 90 is shown, where the Bean 90 acts as a wrapper for native code 92. The Bean further includes several attributes 94, listed as a Code Type attribute 94a, a Code Size Attribute 94b and a MIPS Required attribute 94c. The Bean 90 has several actions 96, including a Load Code action 96a, a Load Parameters action 96b and an Execute Parameter 96c. In operation, the Load Code action 96a is used to load external native code (native to the target processor) into the Bean. Since JAVA Beans have persistence, the Bean 90 can store its internal state, including the native code 92 and the attributes 94. The Load Parameters action 96b retrieves parameters from the native code 92 (using, the for example, the COFF file format described above) and stores the parameters as attributes 94a-c. The Execute action 96c executes tasks installed in the DSP 16. FIG. 5 illustrates use of the Bean 90 to download code to the target processor. In this example, it is assumed that the target processor is the DSP 16 (or one of multiple DSPs 16), although it could be used to download native code to the host processor 12 as well. Further, it is assumed that the desired Bean 90 is resident in a network server, such as a LAN server or an Internet server, although the Bean could be resident in any device in communication with the platform 10, such as a Smartcard. For a wireless data platform 10, the connection to the network server 100 will often be wireless. In FIG. 5, the platform 10 is coupled to a network server 100. The host processor 12, as shown in greater detail in FIG. 2, may execute one or more JAVA applets 40 through a JAVA virtual machine 44. In order to download new code, the host 12 loads an applet containing the Bean 90 from the network server 100 or the Bean, without the containing applet, can be downloaded from the server 100. Once the wrapper Bean 90 has been retrieved, it can be queried for the size of the native code, code type (for which processor is the code intended) and MIPs required. If the intended processor has sufficient resources to run the code 92, the code 92 can be installed to execute on the intended processor, either the host processor 12 or DSP 16 in the architecture shown in FIG. 5. Typically, the native code 92 will be unlinked, compiled code. Thus, the cross linker 82 of the DSP-API 50 will link the code to an available memory location. The Bean would pass the binary native code 92 to the dynamic cross linker 82, which would install and execute the code. A typical manner in which a download of native code might occur is when the user is running an applet in which a DSP function is desired. First, the applet would check to see if the desired code was installed as a task 60 in the DSP or was available in the DSP Library 58. If so, the task could be executed without a download. If the task is not stored in the DSP 16 or the DSP library 58, an object (referred to as the "DSPLoader" object herein) could be created to load the Bean 90. If the DSPLoader class is local on the host 12, JAVA will check to see if the Bean is available locally as well. In a first instance, there may be a Bean with the code stored locally. If so, the code from the Bean is installed to the DSP (or to whichever processor specified by the Code Type). If a Bean without the code is stored locally, the Bean can retrieve the code from the appropriate server. On the other hand, if the DSPLoader object is not local, then JAVA will load the Bean 90 from the server that wrote the applet. The code from the Bean will then be installed as described above. While the downloading of native code is described in connection with the use of a JAVA Bean, it could also be accomplished by wrapping the code within another language, such as an ActiveX applet. Using a JAVA Bean (or other applet) as a wrapper to the native code has significant advantages. First, it allows a simple, standard method for loading code onto one of a plurality of processors. The Bean is created, code is loaded into the Bean and the code is linked to the appropriate processor. Without wrapping the code within the Bean, the process may taken several hundred steps. Second, it allows multiple pieces of native code to be combined by a single applet, providing for complex applications to be generated from multiple discrete routines using a single applet to combine the routines as desired. Third, it takes advantage of the language's security features, thereby protecting not only the JAVA code in the Bean 90, but the native code 92 as well. Other languages, such as ActiveX, have security features as well. SECURITY Two of the most important security features are digital signing and encryption. A JAVA Bean or ActiveX applet may be signed by the source of the code; when the Bean or applet is downloaded, the signature is verified by the receiving application, which has a list of trusted sources. If the Bean or applet is signed by a trusted source, it can be decrypted using standard techniques. Accordingly, the native code is encrypted during transmission along with the code of the Bean or applet, preventing unauthorized modification of the code. Because the native code is secure and comes from a trusted source, the attributes can also be trusted as accurate. FIG. 6 illustrates a flow chart describing the process of downloading native code for a processor using a JAVA Bean, it being understood that the native code could be wrapped in an applet of a different language using similar techniques. In step 110, the encrypted, digitally signed Bean 90 is downloaded to a device running a JAVA virtual machine. In step 112, the signature is verified. If it is not from a source listed as a trusted source, exception processing is enabled in step 114. In the case of the Bean coming from a trusted source, the exception processing function may give the user an opportunity to accept the Bean, if the user is comfortable with the source. If the signature is invalid, the exception processing may delete the Bean 90 and send an appropriate error message to the user. If the signature is valid and comes from a trusted source, the Bean is decrypted in step 116. This step decrypts both the JAVA code and the native code in the Bean. In step 118, the attributes are retrieved from the Bean 90 and in step 120 the applet determines whether the appropriate processor has sufficient resources to run the code. If not, the exception processing step 114 may decline to install the native code, or steps may be taken to free resources. If there are sufficient resources, the code is linked using the cross-linker and installed on the desired processor in step 122. In step 124, the native code is executed. Sample JAVA script for a Bean 90 is provided hereinbelow:
______________________________________
package ti.dsp.loader;
import java.awt.*;
import java.io.*;
import java.net.*;
public class NativeBean extends Canvas implements Serializable
public NativeBean() {
setBackground(Color.white);
funcData = new ByteArrayOutputStream();
try {
funcCodeBase = new URL("http://localhost");
}
catch (MalformedURLException e) {
}
}
public Dimension getMinimumSize() {
return new Dimension(50, 50);
}
public void loadCode() {
URL baseURL = null;
try {
baseURL = new URL(funcCodeBase.toString() + "/" +
my Function);
}
catch (MalformedURLException e) {
}
DataInputStream source = null;
int read;
byte buffer;
buffer = new byte[1024];
try {
source = new DataInputStream(baseURL.openStream());
}
catch (IOException e) {
System.out.println("IOException creating streams: " + e);
}
codeSize = 0;
funcData.reset();
try {
while (true) {
read = source.read(buffer);
if (read ==-1)
break;
funcData.write(buffer, 0, read);
}
}
catch (IOException e) {
System.out.println("IOException: " + e);
}
codeSize = funcData.size();
System.out.println("Code size = " + codeSize);
try {
source.close();
}
catch (IOException e) {
System.out.println("IOException closing: " + e);
}
}
public synchronized String getFunctionName() {
return myFunction;
}
public void setFunctionName(String function) {
myFunction = function;
}
public synchronized String getCodeBase() {
return funcCodeBase.toString();
}
public void setCodeBase(String newBase) {
try {
funcCodeBase = new URL(newBase);
}
catch (MalformedURLException e) {
}
}
public void installCode() {
FileOutputStream destination = null;
File libFile = new File(myFunction);
try {
destination = new FileOutputStream(libFile);
}
catch (IOException e) {
System.out.println("IOException creating streams: " + e);
}
if (destination != null) {
try {
funcData.writeTo(destination);
}
catch (IOException e) {
System.out.println("IO Exception installing native
code: " + e);
}
}
}
linkCode(funcData)
public void loadParameters() {
}
public void execute() {
}
public synchronized int getCodeSize() {
return codeSize;
}
public synchronized int getCodeType() {
return codeType;
}
public void setCodeType(int newType) {
codeType = newType;
}
private int codeSize = 0;
private int codeType = 1;
private String myFunction = "";
private URL funcCodeBase = null;
private ByteArrayOutputStream funcData = null;
}
______________________________________
In the script set forth above, the Native Bean() routine creates the Bean 90 which will hold the native code. The loadCode() routine gets the native code from the server. The getFunctionName() and getCodeBase() routines retrieve attributes. The installCode() routine calls the cross linker to link the native code to the DSP and to load the linked code. The loadParameters() routine instructs the Bean to examine the native code and determine its attributes. The getCodesize() and getCodetype() routines transfer the attributes to the requesting applet. Although the Detailed Description of the invention has been directed to certain exemplary embodiments, various modifications of these embodiments, as well as alternative embodiments, will be suggested to those skilled in the art. The invention encompasses any modifications or alternative embodiments that fall within the scope of the Claims.
|
Same subclass Same class Consider this |
||||||||||
