/*
* Copyright 2001-2008 Texas Instruments - http://www.ti.com/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* ======== cexec.c ========
* "cexec" is a Linux console-based utility that allows developers to load
* and start a new DSP/BIOS Bridge based DSP program. If "cexec" encounters
* an error, it will display a DSP/BIOS Bridge GPP API error code.
*
* Usage:
* cexec [optional args] <dsp_program>
*
* Options:
* -?: displays "cexec" usage. If this option is set, cexec does not
* load the DSP program.
* -w: waits for the user to hit the enter key on the keyboard, which
* stops DSP program execution by placing the DSP into reset. This
* will also display on the WinCE console window the contents of
* DSP/BIOS Bridge trace buffer, which is used internally by the
* DSP/BIOS Bridge runtime. If this option is not specified, "cexec"
* loads and starts the DSP program, then returns immeidately,
* leaving the DSP program running.
* -v: verbose mode.
* -p [processor]: defines the DSP processor on which to execute code,
* where processor is the processor number provided by cexec to
* the DSPProcessor_Attach() function. If this option is not
* specified, the default processor is 0.
* -T: Set scriptable mode. If set, cexec will run to completion after
* loading and running a DSP target. User will not be able to stop
* the loaded DSP target.
*
* Example:
* 1. Load and execute a DSP/BIOS Bridge base image, waiting for user to
* hit enter key to halt the DSP.
*
* cexec -w chnltest_tiomap1510.x55l
*
* 2. Start a program running on the second processor (zero-indexed).
* This will halt the currently running DSP program, if any.
*
* cexec -w -p l chnltest_tiomap1510.x55l
*
* 3. Load and start a program running on the DSP. Cexec will run to
* completion and leave the DSP loaded and running.
*
* cexec -T chnltest_tiomap1510.x55l
*
*! Revision History:
*! ================
*! 20-Oct-2002 map: Instrumented to measure performance on PROC_Load
*! 31-Jul-2002 kc: Added scriptable mode to enable batch testing.
*! 05-Apr-2001 kc: Adapted from existing cexec. Updated cexec program
*! options. Added command line argument handling.
*! Based on DSP/BIOS Bridge API version 0.??.
*! 13-Feb-2001 kc: DSP/BIOS Bridge name update.
*! 15-Nov-2000 jeh Converted to use DSPProcessor.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dbdefs.h>
/* #include <varargs.h> */
#include <stdarg.h>
#include <dbapi.h>
#include <DSPManager.h>
#include <DSPProcessor.h>
#include <DSPProcessor_OEM.h>
/* global constants. */
#define MAXTRACESIZE 256 /* size of trace buffer. */
/* function prototype. */
VOID DisplayUsage();
VOID PrintVerbose(PSTR pstrFmt,...);
/* global variables. */
bool g_fVerbose = false;
/*
* ======== main ========
*/
INT main(INT argc, CHAR * argv[])
{
INT opt;
bool fWaitForTerminate = false;
UINT uProcId = 0; /* default proc ID is 0. */
bool fError = false;
DSP_HPROCESSOR hProc;
DSP_STATUS status = DSP_SOK;
INT cArgc = 0; /* local argc count. */
bool fScriptable = false;
extern char *optarg;
struct DSP_PROCESSORINFO dspInfo;
UINT numProcs;
UINT index = 0;
while ((opt = getopt(argc, argv, "+T+v+w+?p:")) != EOF) {
switch (opt) {
case 'v':
/* verbose mode */
fprintf(stdout, "Verbose mode: ON\n");
g_fVerbose = true;
cArgc++;
break;
case 'w':
/* wait for user input to terminate */
fprintf(stdout, "Not supported \n");
fWaitForTerminate = true;
cArgc++;
break;
case 'T':
fScriptable = true;
cArgc++;
break;
case 'p':
/* user specified DSP processor ID (based on zero-index) */
uProcId = atoi(optarg);
cArgc++;
break;
case '?':
default:
fError = true;
break;
}
}
argv += cArgc + 1;
argc -= cArgc + 1;
if (fError) {
DisplayUsage();
} else {
status = (DBAPI)DspManager_Open(0, NULL);
if (DSP_FAILED(status)) {
PrintVerbose("DSPManager_Open failed \n");
return -1;
}
while (DSP_SUCCEEDED(DSPManager_EnumProcessorInfo(index,&dspInfo,
(UINT)sizeof(struct DSP_PROCESSORINFO),&numProcs))) {
if ((dspInfo.uProcessorType == DSPTYPE_55) ||
(dspInfo.uProcessorType == DSPTYPE_64)) {
printf("DSP device detected !! \n");
uProcId = index;
status = DSP_SOK;
break;
}
index++;
}
status = DSPProcessor_Attach(uProcId, NULL, &hProc);
if (DSP_SUCCEEDED(status)) {
PrintVerbose("DSPProcessor_Attach succeeded.\n");
status = DSPProcessor_Stop(hProc);
if (DSP_SUCCEEDED(status)) {
PrintVerbose("DSPProcessor_Stop succeeded.\n");
status = DSPProcessor_Load(hProc,argc,(CONST CHAR **)argv,NULL);
if (DSP_SUCCEEDED(status)) {
PrintVerbose("DSPProcessor_Load succeeded.\n");
status = DSPProcessor_Start(hProc);
if (DSP_SUCCEEDED(status)) {
fprintf(stdout,"DSPProcessor_Start succeeded.\n");
#if 0
/* It seems Linux bridge does n't yet support
* * DSPProcessor_GetTrace */
if (fWaitForTerminate) {
/* wait for user */
fprintf(stdout,"Hit \"return\" to stop DSP and"
"dump trace buffer:\n");
(void)getchar();
status = DSPProcessor_GetTrace(hProc,
(BYTE *)&traceBuf,MAXTRACESIZE);
fprintf(stdout,"%s\n",traceBuf);
} else {
PrintVerbose("in run free mode...\n");
}
#endif /* 0 */
} else {
PrintVerbose("DSPProcessor_Start failed: 0x%x.\n",
status);
}
} else {
PrintVerbose("DSPProcessor_Load failed: 0x%x.\n",status);
}
DSPProcessor_Detach(hProc);
}
} else {
PrintVerbose("DSPProcessor_Attach failed: 0x%x.\n",status);
}
}
if (!fScriptable) {
/* Wait for user to hit any key before exiting. */
fprintf(stdout, "Hit any key to terminate cexec.\n");
(void)getchar();
}
status = DspManager_Close(0, NULL);
if (DSP_FAILED(status)) {
printf("\nERROR: DSPManager Close FAILED\n");
}
return (DSP_SUCCEEDED(status) ? 0 : -1);
}
VOID DisplayUsage()
{
fprintf(stdout, "Usage: cexec [options] <dsp program>\n");
fprintf(stdout, "\t[optional arguments]:\n");
fprintf(stdout, "\t-?: Display cexec usage\n");
fprintf(stdout, "\t-v: Verbose mode\n");
fprintf(stdout, "\t-w: Waits for user to hit enter key before\n");
fprintf(stdout, "\t terminating. Displays trace buffer\n");
fprintf(stdout, "\t-p [processor]: User-specified processor #\n");
fprintf(stdout, "\n\t[required arguments]:\n");
fprintf(stdout, "\t<dsp program>\n");
fprintf(stdout, "\n\tExample: cexec -w -p 1 prog.x55l\n\n");
}
/*
* ======== PrintVerbose ========
*/
VOID PrintVerbose(PSTR pstrFmt,...)
{
va_list args;
if (g_fVerbose) {
va_start(args, pstrFmt);
vfprintf(stdout, pstrFmt, args);
va_end(args);
fflush(stdout);
}
}