Thfifo

From ProjectWiki
Revision as of 22:18, 13 August 2008 by 68.210.166.7 (Talk)
Jump to: navigation, search

Contents

What is this?

A novel approach to inter-processor communications and related resource management for the Nintendo DS. Based on the concepts of simplicity, ease of use, modularity, and run-time resource allocation.

In addition to the usual FIFO functionality, functions for managing the 4K shared memory space (swrmalloc/swrfree), and rudimentary inter-processor mutual exclusion functions are also provided.

Inter-processor systems provided:

  • Shared Work Ram allocation (swrmalloc/swrfree)
  • Shared Work Ram mutual exclusion locks
  • FIFO for sending data and alerting other CPU of events
  • Ring buffers for queuing data recieved by fifo (seperate library)

Other libraries using thfifo include:

Shared Work Ram Management

Functions detailed here are for managing the 4K shared work ram (swr) segment. This segment is uncached on the arm9 side and therefore slower so should only be used for variables and structures that routinely need to be immediately available to both CPUs.

Traditionally this area was managed at compile time using complex #define statements requiring careful planning to prevent two libraries reusing the same region twice. To avoid these potential pitfalls a simple dynamic runtime allocation system is provided so that libraries may request swr space with minimal concern.

These functions may be called from either CPU, and you should be able to malloc on one side and free on the other! (however this is discouraged).

ToDo:

  • the malloc/free functions should be recoded so that they use less space and store the malloc structures directly in swr. The functions are currently just modified version of vram malloc... >_>

SWR Functions

swrInit
Initialize the swr functionality, called on both CPUs before using. Calling this function is unnecessary if using the FIFO because its called already in fifoInit().

void swrInit(void);

swrmalloc
Allocate a region of swr. Only argument is the size requested. Returns a pointer to the newly allocated region or null if fail.

void *swrmalloc(int size);

swrfree
Frees up a previously allocated region of swr. Only argument is the previously allocated swr pointer. returns true if successful.

Do not see this being used very often if at all, but it is provided for completeness.

bool swrfree(void *loc);


Inter-processor Mutual Exclusion

Two functions are available to restrict access during critical read/writes to swr. For this the well documented Peterson algorithm is used.

These functions were originally conceived to prevent corruption during swrmalloc but may be useful to developers as well. Still debating if the FIFO section itself shouldnt provide per channel locks... @_@

While use of these functions is provided it should generally be avoided since it slows down the other CPU, and essentially wastes time while waiting.

getGlobalSWRLock
This function is caled before accessing critical data.

void getGlobalSWRLock(void);

giveGlobalSWRLock
This function is caled after accessing critical data.

void giveGlobalSWRLock(void);

Usage example:

getGlobalSWRLock();   //get exclusive access to SWR for this cpu, and/or wait until other CPU is finished with it
 myIpcData->variable=newvalue;
 myIpcData->othervar=anothervalue;
 giveGlobalSWRLock();  //allow other CPU access to SWR

FIFO

The design philosophy here is based on simplicity and modularity. It is essentially a channelized version of the hardware rather than an attempt to provide facilities for every possible need.

Each channel is assigned an ASCII name so that it may be easily identified by the other CPU, and an optional pointer to user data to be shared between CPUs (most likely allocated with swrmalloc :P). Each CPU expecting to receiving data is required to assign a handler function.

Up to 24 bits of data may be transfered at a time, the format of this data is left up to the developer.

FIFO Functions

fifoInit

void fifoInit(void);

fifoChanCreate

thfifo_t fifoChanCreate(const char *name, void *udata);

fifoChanSetFunc
Sets a function to be called whenever this channel receives data from other CPU.

bool fifoChanSetFunc(thfifo_t chan, _pHFifoFunc func);

The _pHFifoFunc callback function should accecpt the following arguments:

  • chan - channel number 0-15
  • data - up to 24 bits of data sent from other side
  • udata- pointer to shared IPC structure (prolly not used)
typedef void(*_pHFifoFunc)(thfifo_t chan, u32 data, void *udata);	//callback

fifoSendChan24

void fifoSendChan24(thfifo_t chan, u32 data);

fifoFindChan

thfifo_t fifoFindChan(const char *name);

fifoChanRecvChk

bool fifoChanRecvChk(thfifo_t chan);

fifoGetUData

void *fifoGetUData(thfifo_t chan);
Personal tools
irssi scripts
eggdrop scripts