SPRAB89A September 2011 – March 2014
A copy table has the following format:
typedef struct
{
uint16 rec_size;
uint16 num_recs;
COPY_RECORD recs[num_recs];
} COPY_TABLE;
rec_size is a 16-bit unsigned integer that specifies the size in bytes of each copy record in the table.
num_recs is a 16-bit unsigned integer that specifies the number of copy records in the table.
The remainder of the table consists of a vector of copy records, each of which has the following format:
typedef struct
{
uint32 load_addr;
uint32 run_addr;
uint32 size;
} COPY_RECORD;
The load_addr field is the address of the source data in offline storage.
The run_addr field is the destination address to which the data will be copied.
The size field is overloaded:
The rest of the source data is format-specific. The copy-in routine reads the first byte of the source data to determine its format/index, uses that value to index into the handler table, and invokes the handler to finish decompressing and copying the data.
The handler table has the following format:
The copy-in routine references the table via special linker-defined symbols as shown. The assignment of handler indexes is not fixed; the linker reassigns indices for each application depending on what decompression routines are needed for that application. The handler table is generated into the .cinit section of the executable file.
The run-time support library in the TI toolchain contains handler functions for all the supported compression formats. The first argument to the handler function is the address pointing to the byte after the 8-bit index. The second argument is the destination address.
Reference Implementation of Copy-In Function provides a reference implementation of the copy_in function:
typedef void (*handler_fptr)(const unsigned char *src, unsigned char *dst);
extern int __TI_Handler_Table_Base;
void copy_in(COPY_TABLE *tp)
{
unsigned short i;
for (i = 0; i < tp->num_recs; i++)
{
COPY_RECORD crp = tp->recs[i];
const unsigned char *ld_addr = (const unsigned char *)crp.load_addr;
unsigned char *rn_addr = (unsigned char *)crp.run_addr;
if (crp.size) // not compressed, just copy the data.
memcpy(rn_addr, ld_addr, crp.size);
else // invoke decompression routine
{
unsigned char index = *ld_addr++;
handler_fptr hndl = ((handler_fptr *)(__TI_Handler_Table_Base))[index];
(*hndl)(ld_addr, rn_addr);
}
}
}