| /* |
| * 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); |
| } |
| } |
| |
| |