Observations concerning the correlator board DSP software

P.E. Kamphuis

5-2-1999

General

First the structure of the code needs some rework. Right now there are variables declared in header files as well as function types of local functions. These are a possible cause for problems in the future. Besides this, some functions are located in the wrong source files or at least a better and maintainable structure can be created when these functions are moved to other source files.

Also there are functions and variables declared with no clear meaning and use. These functions and variables need to be identified and isolated and maybe even removed to prevent pollution of the code.

The software can be split several functional units.

Scheduler functions

error handler functions

communication functions

data transfer functions

board control functions

data processing functions

test functions

In the current source code setup there are too much dependencies between the different functional units.

Scheduler functions

At first glance the scheduler looks alright. It is an almost independent set of code. There are only a few board dependencies, which is not recommended for a scheduler.

However at this point there seems no need for change.

Regarding the possibility to download tasks to the DSPs. At this point I see no possible way to achieve this. The problems are mainly in resolving the address of the functions called by the downloaded task. Currently all possible tasks are placed in a static array to provide a link between a task id and a physical address.

Error handler functions

The error handler functions contain several errors. These functions can not be in use at Haystack in this way. The errors reported to the CUCC are split incorrectly (and unnecessary) and after reporting queue_size errors it starts reporting arbitrary data. Besides this errors are reported to different location in the dual port memory.

In the current situation the errors are reported using an interrupt to the CUCC. In this situation the error handling is initiated by the control board and by the CUCC, it is even so that error reporting is started by calling the handler from the user application. It is however also possible to schedule the error scheduler as a task.

There are several possibilities to correct these problems.

The error handler can be made part of the scheduler, i.e. basically nothing more than a task scheduled every BOCF tick. In this situation every BOCF tick can be reported, provided it is read by the CUCC. When the error queue get filled up, a decision has to be made which errors to discard. The old ones or the newly reported errors.

A second solution requires the CUCC to schedule the error handler at regular intervals and process all errors in the queue in one go.

Communication functions

The communication functions handle all data and command communication between the processing DSP and the IO DSP. Both DSPs use the same set of functions for communication. Almost all the functions are located in one source file. Currently both the IO DSP and the processing DSP use this source file. It might be useful to place these functions in a library.

Data transfer functions

There are several data transfer functions defined as tasks. Some of these functions use DMA for data transfer. There might be a possibility that a DMA transfer is started, after which is waited for the DMA transfer to finish.

It looks like the tasks wait for the DMA semafoor to be released. This semafoor is released when the DMA transfer in finished. Apparently there is no function to available to suspend a task for other tasks to run. It might also be possible that tasks are re-entered before finishing.

board control functions

The possible board control functions are currently located in different source files. These functions should include all the functions to access correlator board hardware, i.e. cross bar switches, ASIC control, error leds etc.

data processing functions

The data processing functions implement the possible processing to be performed on the data, i.e. accumulation.

test functions

The test functions should include the functions for start up test to be performed as well as functions for dedicated tests. It is recommended to store both type of test functions in different source files and use the dedicated test functions only in special test applications.

Recommended procedure

It is recommended to reorganize the location of functions in the source files. This will result in better maintainable source code.

•	Strip the code down to a basic application with just board initialization and scheduler operation.

•	Add the board level test functions one by one to check the functionality of these routines.

•	Add the inter processor communication routines.

•	Check the data transfer functions.

•	Add data transfer to the CUCC.

Provided that the current scheduler operations are sufficient and correctly working this functional testing of the control board DSP software can be performed in 80 hours.

Variables should be declared in the c-files, not in the h-files.

The h-files contains only function prototypes for the global functions, not for the private function. Header files may include some additional defines and type definitions.

Nested h-files are not preferred

Constant identifiers should be replaced by defines.

Every c-files should include its corresponding h-file as the last include file.

PRCS	identifying Processing DSP

IO	identifying IO DSP

Brdcnfig.c	board configuration code.

PRCStest.c	board test code. Dual port RAM, local RAM A and B, global RAM, XBAR's. ASIC control logic and data output communication

Iotest.c	correlator chip access, I/O global RAM, Eprom access

schedule.c	scheduler code

mstack.asm	scheduler stack handling

bocfhand.asm	BOCF interrupt handler, i.e. timer for the scheduler.

Error.c	error handling code,

TCB	Task Control Block

DAT	DMA access table

CDT	chained DMA table

The general form for a task function is.

void function_name(unsigned *tdpTCB)

{

}

Start up procedure (main)

boot()	initialization of processor registers. Interrupt vectors are installed also. The are also C40 comm task initialized as well as error handlers. The last two don't belong in here. Internal memory is also tested.

OnBoardSetup()	Creates an array with offset for XBAR indexing. Resets dual port interrupt. Clears error led.

SelfDiagnostic()	RAM test local RAM A and B and global RAM. Communication port communication between IO and Processing DSP including DMA. Correlator ASIC read/write dynamic and static parameters. Run the error handler to send errors to RT system.

Schedule.c

void schedule()	Called from interrupt handler. The scheduler maintains a list of TCBs

void entry()	Handles scheduling details

void addTCB(..)	Adds TCB to scheduling queue

void startTCB(..)	Starts up a TCB

void stopTCB(..)	Suspends TCB from rescheduling when done

void removeTCB(..)	Removes TCB from list immediately

void startUpScheduler()	Initialize head and tail pointers

void spawnDaughter(..)	Adds TCB to list and starts task

int taskStatus(..)	Reports the status of a task

int daughterStatus(..)	Reports the status of all daughter tasks

unsigned int parseMemoryID(..)	From memory ID specific to uniform format

void taskProgress(..)	Saves stack context. TaskProgress checks to see if there is a task running, and if so the context of the stack context is saved.

int currentStateIP(..)	Complete status, que removal

int checkState(..)	Returns task state

void changeStateIP(..)	Changes task state to running

struct blockTCB *newTask()	Selects next task to run. Not so logical name.

void updateTaskList()	Status update after event

unsigned int *stackAlloc()	Return memory for stack

void freeStack()	Free stack memory

void detachLink(..)	Removes link from list

unsigned int parseMemory(..)	From memory specific to uniform format. Parsing memory requires that the target memory area be determined as either Dual Port RAM (Byte Wide) or any other memory (Longword wide). The value indexed in that memory is returned with the LSB starting at zero and with a longword mask applied.

More convenient would be a specific function for Dual Port memory.

struct blockTCB *findLink(..)	Finds link in list from TCB address. Search through scheduler list and find address of link that has a matching data area to the one passed

struct blockTCB *findDaughter(..)	Finds spawned task from parent TCB address

comm.c

tasklist.c	containts all possible tasks for the CUCC to run. Plus some additional routines. It is recommended to split this list of tasks in at least two files. One with tasks for the Processing DSP and one with tasks for the IO DSP

void DSPmemAlloc(...)	CUCC controlled allocation of memory

void DSPmemTOmem(...)	DMA transfer of data between any any read/write device

void DSPsetGlobalMode(...)	Sets global mode parameters

void DSPcrossbarWrite(...)	Configures XBAR switches with data from a table

void DSPstaticDataRW(...)	Reads Static parameters from or writes them to ASIC's

void DSPdynamicDataRW(...)	Reads Dynamic parameters from or writes them to ASIC's

void DSPlagDataRead(...)	Reads lag data and DMA to specified location

void DSPDeMuxData(...)	4x4 reconstruct of data from interleave (CfA application)

void DSPzeroArray(...)	Fills block memory with zero's

void allocResponse(...)	Gets memory address allocated in IO DSP and writes it to TCB

void IomemAlloc(...)	Works in conjunction with DSPmemAlloc get of piece IO memory. This routine will allocate or deallocate space in reponse to a MEM_ALLOC TCB passed from the Processing

void IocreateDMA(...)	Creates a IO DMA table

void IostartDMA(...)	Start a DMA transfer with table address passed

void IoreadSP(...)	Reads static parameters

void IowriteSP(...)	Writes static parameters

void IoreadDP(...)	Reads dynamic parameters

void IowriteDP(...)	Writes dynamic parameters

void IolagRead(...)	Reads lags

void IosetASICmask(...)	Sets ASIC mask

void formatMemory(...)	Used to write data to memory of arbitrary size

The following routines are visible only in this object :

void taskComplete(...)	Used to interrupts the CUCC when a task is done

unsigned *makeDMApointer(...)	Creates a pointer to a set of DMA data

void memTOmemDone(...)	Used to unlock a semphore at the end of a DMA transfer

void parseDataByte(...)	Extracts data from byte wide memory

process.c	This file contains the main function for the processing DSP and several board test functions.

prepare.c

dsp.c

vectable.c

demux.asm

bocfhand.asm

mstack.asm