📄 target28xx.cpp
字号:
// Target28xx.cpp: implementation of the Target28xx class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SDLoader.h"
#include "Target28xx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Target28xx::Target28xx()
{
}
Target28xx::~Target28xx()
{
}
/*F***************************************************************************
* NAME: OpenConnection( void )
*
* DESCRIPTION: Open emulation connection
*
*
*F***************************************************************************/
BOOL Target28xx::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 Target28xx::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 Target28xx::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 Target28xx::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 Target28xx::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 Target28xx::WaitForHaltEvent( )
{
BOOL isEvt = FALSE;
long TimeOutInMs = (long)(((m_ExecTimeoutMs+9)/10)*10);
InitEvent();
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
do
{
isEvt = CheckEvents();
if( isEvt )
{
if( m_Evt.System )
break;
if( m_Evt.Type != EVT_NONE )
break;
isEvt = FALSE;
}
else {
Sleep(10);
}
TimeOutInMs -= 10;
}while( TimeOutInMs > 0 );
return( isEvt );
}
/*F***************************************************************************
* NAME: RunTarget( void )
*
* DESCRIPTION: Start the target running from it's current program counter.
* If processor had stopped on a breakpoint then it will be
* stepped over by low level code.
*
*
*F***************************************************************************/
BOOL Target28xx::RunTarget( void )
{
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
return( m_pSdti_Intf->pExe->Continue( m_Sdti_Hndl ));
}
/*F***************************************************************************
* NAME: StepTarget( void )
*
* DESCRIPTION: Step the target
*
*F***************************************************************************/
BOOL Target28xx::StepTarget( DWORD Count )
{
BOOL Success;
BOOL isEvt;
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
Success = m_pSdti_Intf->pExe->Step( m_Sdti_Hndl, (unsigned long)Count );
if( Success == FALSE )
return( FALSE );
isEvt = WaitForHaltEvent();
// Timed out or some oher event but may not be halted
if( isEvt == FALSE )
return( FALSE );
// Target has not halted return error
if( m_pSdti_Intf->pExe->IsRunning( m_Sdti_Hndl ) == TRUE )
return( FALSE );
return( TRUE );}
/*F***************************************************************************
* NAME: RunTargetTillDone( )
*
* DESCRIPTION: Run processor and wait for a "halting" event. Then verify
* the processor has stopped.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -