📄 coffloader.cpp
字号:
/*
* Copyright 2003 by Spectrum Digital Incorporated.
* All rights reserved. Property of Spectrum Digital Incorporated.
*/
// CoffLoader.cpp
#include "stdafx.h"
#include "SDLoader.h"
#include "SDLoaderDlg.h"
/* ==============================
Valid register names and size
{"PC", sizeof(TREG_32)
{"SP", sizeof(TREG_16)
{"ACC", sizeof(TREG_32)
{"P", sizeof(TREG_32)
{"T", sizeof(TREG_16)
{"ST0", sizeof(TREG_16)
{"ST1", sizeof(TREG_16)
{"AR0", sizeof(TREG_16)
{"AR1", sizeof(TREG_16)
{"AR2", sizeof(TREG_16)
{"AR3", sizeof(TREG_16)
{"AR4", sizeof(TREG_16)
{"AR5", sizeof(TREG_16)
{"XAR6", sizeof(TREG_32)
{"XAR7", sizeof(TREG_32)
{"IER", sizeof(TREG_16)
{"DP", sizeof(TREG_16)
{"IFR", sizeof(TREG_16)
{"DBGIER", sizeof(TREG_16)
// Added June 2004.
{"DBGIM", sizeof(TREG_16)
{"HPI", sizeof(TREG_16)
{"PREEMPT", sizeof(TREG_16)
// This is little hack to get C28xx XARx regs. The ids
// still match C27xx but low level driver will return 32
// bit value
{"XAR0", sizeof(TREG_32)
{"XAR1", sizeof(TREG_32)
{"XAR2", sizeof(TREG_32)
{"XAR3", sizeof(TREG_32)
{"XAR4", sizeof(TREG_32)
{"XAR5", sizeof(TREG_32)
*/
/*F***************************************************************************
* NAME: Constructor
*
* DESCRIPTION: Do basic initialization here.
*
*
*F***************************************************************************/
CoffLoader::CoffLoader( )
{
m_pSdti_Intf = NULL;
m_Sdti_Hndl = NULL;
m_isConnected = FALSE;
m_coffHndl = NULL;
m_coffLib = NULL;
m_symlist = NULL;
m_swbplist = NULL;
m_numSymbols = 0;
m_verboseError = TRUE;
m_verboseMessage = TRUE;
m_SciLoopBack = FALSE;
m_CanLoopBack = FALSE;
m_I2CLoopBack = FALSE;
m_isRealTimeAllowed = FALSE;
}
/*F***************************************************************************
* NAME: Destructor
*
* DESCRIPTION: Do cleanup here. In theory the main code cleans up after
* itself. But just in case there is a untested exit path we
* can catch it here. Beware clean up has to be done in reverse
* order.
*
*F***************************************************************************/
CoffLoader::~CoffLoader( )
{
CloseConnection();
}
/*F***************************************************************************
* NAME: Message( CString MsgString )
*
* DESCRIPTION:
* This function allows for messages to be posted back to the main dialog
* window. Each message string is allocated as a new CString object. This
* ensures no memory problems when the code load has completed.
*
*F***************************************************************************/
void CoffLoader::Message( CString MsgString )
{
if( m_verboseMessage == TRUE )
{
/* Create a new CString object */
CString * message = new CString( MsgString );
/* Post the message to the Dialog Window */
m_mainWindow->PostMessage( UWM_ONTHREADMESSAGE, 0, ( LPARAM )message );
}
}
/*F***************************************************************************
* NAME: ErrMsg( CString MsgString )
*
* DESCRIPTION:
* This function allows for erros to be posted back to the main dialog
* window. Each message string is allocated as a new CString object. This
* ensures no memory problems when the code load has completed.
*
*F***************************************************************************/
void CoffLoader::ErrMsg( CString MsgString )
{
if( m_verboseError == TRUE )
{
/* Create a new CString object */
CString * message = new CString( MsgString );
/* Post the message to the Dialog Window */
m_mainWindow->PostMessage( UWM_ONTHREADMESSAGE, 0, ( LPARAM )message );
}
}
/*F***************************************************************************
* NAME: OpenConnection( void )
*
* DESCRIPTION: Open emulation connection
*
*
*F***************************************************************************/
BOOL CoffLoader::OpenConnection( void )
{
// Just one connection per session
if( m_isConnected == TRUE )
return( FALSE );
// Create SD_TARGET_INTERFACE
if ( ! SDTI_GetInterface( ( void** )&m_pSdti_Intf, CSTRING_TO_PCHAR( m_procFamily ) ) )
{
ErrMsg( "ERROR \tCannot fetch SD Target Interface for processor type "
+ m_procFamily );
return( FALSE );
}
// Create m_Sdti_Hndl, TMS320C27XX_28XX is the name embedded into the ccs .dvr file.
// If we specify a name then SDTI will check for valid name. Else pass NULL and
// take what you get.
//
if ( ! m_pSdti_Intf->pCfg->CreateHndl( &m_Sdti_Hndl,
CSTRING_TO_PCHAR( m_driverPath ),
CSTRING_TO_PCHAR( m_driverName ),
"TMS320C27XX_28XX" ))
{
ErrMsg( "ERROR \tCannot create a SDTI handle for processor type "
+ m_procFamily + " in driver " + m_driverName );
return( FALSE );
}
// The SetOptions function will inform the drivers on what the
// board setting is currently being used and which processor on the board
// the user wants to access.
//
// The physical link between computer and target board may vary from a
// parallel port ( address 0x378 ) to usb ( address 0x540 ). Each type of link
// has an associated port address used for emulation.
//
// The diverse board configurations require an external board file to be
// used. This board file contains the type of processors used and the
// position of each on the scan chain.
//
// To access a single processor on the board, the drivers needs to
// identified it through the board file's scan chain. Each processor is
// designated with a "cpu_#", where # is the position.
//
// DevConnectRealtime (YES/NO)
// DevRunOnDisconnect (YES/NO)
// DevEnableMemoryMapChecking (YES/NO)
// DevMaxMemoryBlockSize (256-2048)
// DevForceStatusCheck (YES/NO)
// Set emulator port address
if ( ! m_pSdti_Intf->pCfg->SetOptions( m_Sdti_Hndl, CSTRING_TO_PCHAR( "EmuPortAddr=" + m_procAddr ) ) )
{
ErrMsg( "ERROR \tFailed to Set Option [ EmuPortAddr="
+ m_procAddr + " ]." );
return( FALSE );
}
// Set device board file
if ( ! m_pSdti_Intf->pCfg->SetOptions( m_Sdti_Hndl, CSTRING_TO_PCHAR( m_BoardFile ) ) )
{
ErrMsg( "ERROR \tFailed to Set Option [ DevBoardName="
+ m_workingDirectory + m_targetPath + m_boardName + " ]." );
return( FALSE );
}
// Set device processor
if ( ! m_pSdti_Intf->pCfg->SetOptions( m_Sdti_Hndl, CSTRING_TO_PCHAR( "DevProcName=" + m_procName ) ) )
{
ErrMsg( "ERROR \tFailed to Set Option [ DevProcName="
+ m_procName + " ]." );
return( FALSE );
}
// Set the memory block size
if ( ! m_pSdti_Intf->pCfg->SetOptions( m_Sdti_Hndl, CSTRING_TO_PCHAR( "DevMaxMemoryBlockSize=2048") ) )
{
ErrMsg( "ERROR \tFailed to Set Option [ DevProcName="
+ m_procName + " ]." );
return( FALSE );
}
//
// Once the configuration settings are complete, the computer
// can now connect to the processor. After a successful connection to the
// processor, all non-configuration functions become available to use.
//
// Connect to target processor
if ( ! m_pSdti_Intf->pCfg->Connect( m_Sdti_Hndl ) )
{
ErrMsg( "ERROR \tFailed to CONNECT to Target." );
// Flush error/messages for debug
while( CheckEvents() ){}
return( FALSE );
}
m_isConnected = TRUE;
return( TRUE );
}
/*F***************************************************************************
* NAME: CloseConnection( void )
*
* DESCRIPTION: Close emulation connection
*
*
*F***************************************************************************/
BOOL CoffLoader::CloseConnection(void)
{
// Delete breakpoints if they exists
if( m_swbplist != NULL ) {
DeleteSwbpList();
m_swbplist = NULL;
}
// Delete symbols
if( m_symlist != NULL ) {
DeleteSymbolList();
m_symlist = NULL;
}
// Close any open handles and free lists if they are still active
//
if( (m_coffLib != NULL) && ( m_coffHndl != NULL )) {
m_coffLib->COFFR_FileClose( m_coffHndl );
m_coffHndl = NULL;
}
// Close the emulation connection
if( (m_pSdti_Intf != NULL ) && ( m_Sdti_Hndl != NULL )) {
m_pSdti_Intf->pCfg->Disconnect( m_Sdti_Hndl );
m_pSdti_Intf->pCfg->FreeHndl( m_Sdti_Hndl );
m_Sdti_Hndl = NULL;
/* Sleep for 2 second so usb device can disconnect from windows.
* Windows USB Issue */
Sleep(2000);
}
m_isConnected = FALSE;
return( TRUE );
}
BOOL CoffLoader::CheckConnection(void)
{
if( ( m_pSdti_Intf == NULL )
|| ( m_Sdti_Hndl == NULL )
|| ( m_isConnected == FALSE)) {
return( FALSE );
}else {
return( TRUE );
}
}
/*F***************************************************************************
* NAME: InitEvent( void )
*
* DESCRIPTION: Set the status event to a NULL state.
*
*
*F***************************************************************************/
void CoffLoader::InitEvent( void )
{
m_Evt.EvtId = 0;
m_Evt.Taddr = 0;
m_Evt.Space = M_NATURAL;
m_Evt.Type = EVT_NONE;
m_Evt.System = EVT_SYS_NONE;
m_Evt.Error = 0;
}
/*F***************************************************************************
* NAME: CheckEvents( void )
*
* DESCRIPTION: The SDTI interface puts pretty much all status and errors into
* and event queue. This is a common place to pull all the events
* and process they come in.
*
*F***************************************************************************/
BOOL CoffLoader::CheckEvents( void )
{
BOOL isEvt;
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
InitEvent();
isEvt = m_pSdti_Intf->pExe->IsEvent( m_Sdti_Hndl, &m_Evt );
if( isEvt )
{
// Event processing flow:
// 1) Handle error events first
// 2) Then spurious errors that are do not generate system events.
// Generally code mishap.
// 3) Then handle target events like breakpoints and such
if( m_Evt.System != EVT_SYS_NONE )
{
// 1) System error events
// If system warning event then do not send error message.
// These are for internal processing. Return that we saw
// an event so that caller can continue processing other
// events as required.
if( m_Evt.System == EVT_SYS_WARN )
return( isEvt );
else
{
// If we have a DISCONNECTED error then return isEvt==FALSE.
// If you are disconnected you will always get a disconnected
// error, i.e. an endless loop
//
if( m_Evt.Error == CFG_ERR_DISCONNECTED )
return( FALSE );
CString Error;
if( m_Evt.Error > (CFG_ERR_GENERIC -1 ) ) {
Error.Format( "ERR: SDTI error: Id: %x, Addr: 0x%x, Space: %x, Type: %x, System: 0x%x, Error: %d",
m_Evt.EvtId,
m_Evt.Taddr,
m_Evt.Space,
m_Evt.Type,
m_Evt.System,
m_Evt.Error );
}
else if ( m_Evt.Error < 0 ) {
// Handle the USB connection error special
if( m_Evt.Error == -4037 ) {
Error.Format( "ERR: USB Error: %d, USB connection not found or in use by another application",
m_Evt.Error );
}
else {
Error.Format( "ERR: OTIS error: Id: %x, Addr: 0x%x, Space: %x, Type: %x, System: 0x%x, Error: %d",
m_Evt.EvtId,
m_Evt.Taddr,
m_Evt.Space,
m_Evt.Type,
m_Evt.System,
m_Evt.Error );
}
}
if( !Error.IsEmpty() ) {
ErrMsg( Error + "\r\n");
}
}
}
else
{
// This should not occur but here for safety
if( m_Evt.Error )
{
// 2) Spurious events
// If we have a DISCONNECTED error then return isEvt==FALSE.
// If you are disconnected you will always get a disconnected
// error, i.e. an endless loop
//
if( m_Evt.Error == CFG_ERR_DISCONNECTED )
return( FALSE );
else
{
switch( m_Evt.Error )
{
case CFG_ERR_LIB_HANDLE:
ErrMsg("ERR: Could not obtain a handle to specified driver");
break;
case CFG_ERR_LIB_INTERFACE:
ErrMsg("ERR: Driver interface is not supported");
break;
case CFG_ERR_LIB_VERSION:
ErrMsg("ERR: Driver version is incorrect");
break;
case CFG_ERR_FAMILY:
ErrMsg("ERR: Processor family is not supported");
break;
default:
ErrMsg("MSG: Execution event detected");
break;
}
}
}
else if( m_Evt.Type != EVT_NONE )
{
// 3) Target events like breakpoints. Nothing to do but could
// add some messages and stuff.
CString StopEvent;
switch( m_Evt.Type )
{
case EVT_HALT:
StopEvent.Format( "Stopped at Addr: 0x%x",m_Evt.Taddr );
break;
case EVT_SWBP:
StopEvent.Format( "Breakpoint at Addr: 0x%x",m_Evt.Taddr );
break;
case EVT_HWIAQ:
StopEvent.Format( "Hardware IAQ at Addr: 0x%x",m_Evt.Taddr );
break;
case EVT_HWDATA:
StopEvent.Format( "Hardware data break at Addr: 0x%x",m_Evt.Taddr );
break;
}
if( !StopEvent.IsEmpty() ) {
Message( StopEvent );
}
}
}
}
return( isEvt );
}
/*F***************************************************************************
* NAME: WaitForHaltEvent( )
*
* DESCRIPTION: Following a run command we can wait for target to halt
* execution. If we get a system event then this is probably
* and error. In in this case we still break out so that caller
* can take action. Otherwise any event other the EVT_NONE will
* have halted the processor.
*
*F***************************************************************************/
BOOL CoffLoader::WaitForHaltEvent( )
{
BOOL isEvt = FALSE;
long TimeOutInMs = (long)(((m_ExecTimeoutMs+9)/10)*10);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -