Esempio n. 1
0
void USB_debug_printf( const char* format, ... )
{
    char    buffer[256];
    va_list arg_ptr;

    va_start( arg_ptr, format );

    int len = hal_vsnprintf( buffer, sizeof(buffer)-1, format, arg_ptr );
                               
    // flush existing characters
    DebuggerPort_Flush( USART_DEFAULT_PORT );

    // write string
    DebuggerPort_Write( USART_DEFAULT_PORT, buffer, len );

    // flush new characters
    DebuggerPort_Flush( USART_DEFAULT_PORT );

    va_end( arg_ptr );
}
Esempio n. 2
0
void debug_printf(char const* format, ... )
{

    char    buffer[256];
    va_list arg_ptr;

    va_start( arg_ptr, format );

   int len = hal_vsnprintf( buffer, sizeof(buffer)-1, format, arg_ptr );

    // flush existing characters
    DebuggerPort_Flush( HalSystemConfig.DebugTextPort );

    // write string
    DebuggerPort_Write( HalSystemConfig.DebugTextPort, buffer, len );

    // flush new characters
    DebuggerPort_Flush( HalSystemConfig.DebugTextPort );

    va_end( arg_ptr );


}
Esempio n. 3
0
void ApplicationEntryPoint()
{
    INT32 timeout       = 20000; // 20 second timeout
    bool  enterBootMode = false;

    // crypto API needs to allocate memory. Initialize simple heap for it. 
    UINT8* BaseAddress;                                 
    UINT32 SizeInBytes;                                 
                                                        
    HeapLocation         ( BaseAddress, SizeInBytes );  
    SimpleHeap_Initialize( BaseAddress, SizeInBytes );  

    g_eng.Initialize( HalSystemConfig.DebuggerPorts[ 0 ] );

    // internal reset and stop check
    enterBootMode = g_PrimaryConfigManager.IsBootLoaderRequired( timeout );

    // ODM defined method to enter bootloader mode
    if(!enterBootMode)
    {
        enterBootMode = WaitForTinyBooterUpload( timeout );
    }
    if(!enterBootMode)   
    {
        if(!g_eng.EnumerateAndLaunch())
        {
            timeout       = -1;
            enterBootMode = true;
        }
    }

    if(enterBootMode)
    {
        LCD_Clear();
        
        hal_fprintf( STREAM_LCD, "TinyBooter v%d.%d.%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION);
        hal_fprintf( STREAM_LCD, "%s Build Date:\r\n\t%s %s\r\n", HalName, __DATE__, __TIME__ );

        DebuggerPort_Initialize( HalSystemConfig.DebuggerPorts[ 0 ] );

        TinyBooter_OnStateChange( State_EnterBooterMode, NULL );

        DebuggerPort_Flush( HalSystemConfig.DebugTextPort  );
        hal_printf( "TinyBooter v%d.%d.%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION);
        hal_printf( "%s Build Date: %s %s\r\n", HalName, __DATE__, __TIME__ );
#if defined(__GNUC__)
        hal_printf("GNU Compiler version %d\r\n", __GNUC__);
#elif defined(_ARC)
        hal_printf("ARC Compiler version %d\r\n", _ARCVER);
#elif defined(__ADSPBLACKFIN__)
        hal_printf( "Blackfin Compiler version %d\r\n", __VERSIONNUM__ );
#elif defined(__RENESAS__)
        hal_printf( "Renesas Compiler version %d\r\n", __RENESAS_VERSION__ );
#else
        hal_printf( "ARM Compiler version %d\r\n", __ARMCC_VERSION );
#endif
        DebuggerPort_Flush( HalSystemConfig.DebugTextPort );

        //
        // Send "presence" ping.
        //
        {
            CLR_DBG_Commands::Monitor_Ping cmd;

            cmd.m_source = CLR_DBG_Commands::Monitor_Ping::c_Ping_Source_TinyBooter;

            g_eng.m_controller.SendProtocolMessage( CLR_DBG_Commands::c_Monitor_Ping, WP_Flags::c_NonCritical, sizeof(cmd), (UINT8*)&cmd );
        }
    
        UINT64 ticksStart = HAL_Time_CurrentTicks();

        //
        // Wait for somebody to press a button; if no button press comes in, lauch the image
        //
        do
        {
            const UINT32 c_EventsMask = SYSTEM_EVENT_FLAG_COM_IN |
                                        SYSTEM_EVENT_FLAG_USB_IN |
                                        SYSTEM_EVENT_FLAG_BUTTON;

            UINT32 events = ::Events_WaitForEvents( c_EventsMask, timeout );

            if(events != 0)
            {
                Events_Clear( events );
            }

            if(events & SYSTEM_EVENT_FLAG_BUTTON)
            {
                TinyBooter_OnStateChange( State_ButtonPress, (void*)&timeout );
            }
            
            if(events & (SYSTEM_EVENT_FLAG_COM_IN | SYSTEM_EVENT_FLAG_USB_IN))
            {
                g_eng.ProcessCommands();
            }

            if(LOADER_ENGINE_ISFLAGSET(&g_eng, Loader_Engine::c_LoaderEngineFlag_ValidConnection))
            {
                LOADER_ENGINE_CLEARFLAG(&g_eng, Loader_Engine::c_LoaderEngineFlag_ValidConnection);
                
                TinyBooter_OnStateChange( State_ValidCommunication, (void*)&timeout );

                ticksStart = HAL_Time_CurrentTicks();
            }
            else if((timeout != -1) && (HAL_Time_CurrentTicks()-ticksStart) > CPU_MillisecondsToTicks((UINT32)timeout))
            {
                TinyBooter_OnStateChange( State_Timeout, NULL );
                g_eng.EnumerateAndLaunch();
            }
        } while(true);
    }

    ::CPU_Reset();
}
Esempio n. 4
0
////////////////////////////////////////////////////////////////////////////////
// The TinyBooter_OnStateChange method is an event handler for state changes in 
// the TinyBooter.  It is designed to help porting kit users control the tinybooter
// execution and allow them to add diagnostics.
////////////////////////////////////////////////////////////////////////////////
void TinyBooter_OnStateChange( TinyBooterState state, void* data, void ** retData )
{
    switch(state)
    {
        ////////////////////////////////////////////////////////////////////////////////////
        // State_EnterBooterMode - TinyBooter has entered upload mode
        ////////////////////////////////////////////////////////////////////////////////////
        case State_EnterBooterMode:
            CPU_GPIO_EnableOutputPin(LED1, TRUE);
            CPU_GPIO_EnableOutputPin(LED2, TRUE);
            CPU_GPIO_EnableOutputPin(LED3, TRUE);
#if defined(TARGETLOCATION_RAM)
            CPU_GPIO_EnableOutputPin(LED4, TRUE);
#else
            CPU_GPIO_EnableOutputPin(LED4, FALSE);
#endif
            hal_fprintf( STREAM_LCD, "Waiting\r" );
            break;

        ////////////////////////////////////////////////////////////////////////////////////
        // State_ButtonPress - A button was pressed while Tinybooter 
        // The data parameter is a pointer to the timeout value for the booter mode.
        ////////////////////////////////////////////////////////////////////////////////////
        case State_ButtonPress:
            if(NULL != data)
            {
                UINT32 down, up;
                INT32* timeout_ms = (INT32*)data;
                
                // wait forever if a button was pressed
                *timeout_ms = -1;

                // process buttons
                while(Buttons_GetNextStateChange(down, up))
                {
                    // leave a way to exit boot mode incase it was accidentally entered
                     if(0 != (down & BUTTON_ENTR)) 
                     {
                        // force an enumerate and launch
                        *timeout_ms = 0; 
                     }
                }
            }
            break;

        ////////////////////////////////////////////////////////////////////////////////////
        // State_ValidCommunication - TinyBooter has received valid communication from the host
        // The data parameter is a pointer to the timeout value for the booter mode.
        ////////////////////////////////////////////////////////////////////////////////////
        case State_ValidCommunication:
            if(NULL != data)
            {
                INT32* timeout_ms = (INT32*)data;

                // if we received any com/usb data then let's change the timeout to at least 20 seconds
                if(*timeout_ms != -1 && *timeout_ms < 20000)
                {
                    *timeout_ms = 20000;
                }
            }
            break;

        ////////////////////////////////////////////////////////////////////////////////////
        // State_Timeout - The default timeout for TinyBooter has expired and TinyBooter will 
        // perform an EnumerateAndLaunch
        ////////////////////////////////////////////////////////////////////////////////////
        case State_Timeout:
            break;

        ////////////////////////////////////////////////////////////////////////////////////
        // State_MemoryXXX - Identifies memory accesses.
        ////////////////////////////////////////////////////////////////////////////////////
        case State_MemoryWrite:
            hal_fprintf( STREAM_LCD, "Wr: 0x%08x\r", (UINT32)data );
            break;
        case State_MemoryErase:
            hal_fprintf( STREAM_LCD, "Er: 0x%08x\r", (UINT32)data );
            break;

            
        ////////////////////////////////////////////////////////////////////////////////////
        // State_CryptoXXX - Start and result of Crypto signature check
        ////////////////////////////////////////////////////////////////////////////////////
        case State_CryptoStart:
            hal_fprintf( STREAM_LCD,     "Chk signature \r" );
            hal_printf( "Chk signature \r" );
            break;
        // The data parameter is a boolean that represents signature PASS/FAILURE
        case State_CryptoResult:
            if((bool)data)
            {
                hal_fprintf( STREAM_LCD, "Signature PASS\r\n\r\n" );
                hal_printf( "Signature PASS\r\n\r\n" );
            }
            else
            {
                hal_fprintf( STREAM_LCD, "Signature FAIL\r\n\r\n" );
                hal_printf( "Signature FAIL\r\n\r\n"  );
            }
            DebuggerPort_Flush(HalSystemConfig.DebugTextPort);
            break;

        ////////////////////////////////////////////////////////////////////////////////////
        // State_Launch - The host has requested to launch an application at a given address, 
        //                or a timeout has occured and TinyBooter is about to launch the 
        //                first application it finds in FLASH.
        //
        // The data parameter is a UINT32 value representing the launch address
        ////////////////////////////////////////////////////////////////////////////////////
        case State_Launch:
            if(NULL != data)
            {
                CPU_GPIO_EnableOutputPin(LED1, FALSE);
                hal_fprintf( STREAM_LCD, "Starting application at 0x%08x\r\n", (UINT32)data );
                // copy the native code from the Load area to execute area.
                // set the *retAddres to real execute address after loading the data
                // *retData =  exeAddress 
               *retData =(void*) ((UINT32)data | 1); // set Thumb bit!
            }
            break;
    }
            
}
void CLR_Debug::Emit( const char *text, int len )
{
    NATIVE_PROFILE_CLR_DIAGNOSTICS();
    static char s_buffer[ 128 ];
    static int  s_chars = 0;

    if(len == -1) len = (int)hal_strlen_s( text );

#if defined(PLATFORM_WINDOWS)
    if(s_redirectedString)
    {
        s_redirectedString->append( text, len );
        return;
    }

    if(s_CLR_RT_fTrace_RedirectOutput.size())
    {
        static HANDLE hFile = INVALID_HANDLE_VALUE;
        static int    lines = 0;
        static int    num   = 0;

        if(hFile == INVALID_HANDLE_VALUE)
        {
            std::wstring file = s_CLR_RT_fTrace_RedirectOutput;

            if(s_CLR_RT_fTrace_RedirectLinesPerFile)
            {
                WCHAR rgBuf[ 64 ];

                swprintf( rgBuf, ARRAYSIZE(rgBuf), L".%08d", num++ );

                file.append( rgBuf );
            }

            hFile = ::CreateFileW( file.c_str(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0 );

            lines = 0;
        }

        if(hFile != INVALID_HANDLE_VALUE)
        {
            DWORD dwWritten;

            ::WriteFile( hFile, text, (DWORD)len, &dwWritten, NULL );

            if(s_CLR_RT_fTrace_RedirectLinesPerFile)
            {
                while((text = strchr( text, '\n' )) != NULL)
                {
                    lines++;
                    text++;

                    if(text[ 0 ] == 0)
                    {
                        if(lines > s_CLR_RT_fTrace_RedirectLinesPerFile)
                        {
                            ::CloseHandle( hFile ); hFile = INVALID_HANDLE_VALUE;
                        }

                        break;
                    }
                }
            }

            return;
        }
    }
#endif

    while(len > 0)
    {
        int avail = MAXSTRLEN(s_buffer) - s_chars;

        if(len < avail) avail = len;

        memcpy( &s_buffer[ s_chars ], text, avail );

        s_chars += avail;
        text    += avail;
        len     -= avail;
        s_buffer[ s_chars ] = 0;

        if(s_chars > 80 || strchr( s_buffer, '\n' ))
        {
            ::Watchdog_ResetCounter();

#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_WINCE)
            HAL_Windows_Debug_Print( s_buffer );
#endif

            if(CLR_EE_DBG_IS( Enabled ) && !CLR_EE_DBG_IS( Quiet ))
            {
                CLR_EE_DBG_EVENT_BROADCAST( CLR_DBG_Commands::c_Monitor_Message, s_chars, s_buffer, WP_Flags::c_NonCritical | WP_Flags::c_NoCaching );
            }

            if(!CLR_EE_DBG_IS( Enabled ) || HalSystemConfig.DebugTextPort != HalSystemConfig.DebuggerPorts[ 0 ])
            {
#if !defined(PLATFORM_WINDOWS) && !defined(PLATFORM_WINCE)
                DebuggerPort_Write( HalSystemConfig.DebugTextPort, s_buffer, s_chars ); // skip null terminator
                DebuggerPort_Flush( HalSystemConfig.DebugTextPort );                    // skip null terminator
#endif
            }

            s_chars = 0;
        }
    }
}
void CLR_Debug::Flush()
{
    NATIVE_PROFILE_CLR_DIAGNOSTICS();
    DebuggerPort_Flush( HalSystemConfig.DebugTextPort );
}
////////////////////////////////////////////////////////////////////////////////
// The TinyBooter_OnStateChange method is an event handler for state changes in 
// the TinyBooter.  It is designed to help porting kit users control the tinybooter
// execution and allow them to add diagnostics.
////////////////////////////////////////////////////////////////////////////////
void TinyBooter_OnStateChange(TinyBooterState state, void* data, void ** retData)
{
	switch (state)
	{
		////////////////////////////////////////////////////////////////////////////////////
		// State_EnterBooterMode - TinyBooter has entered upload mode
		////////////////////////////////////////////////////////////////////////////////////
	case State_EnterBooterMode:
		hal_fprintf(STREAM_LCD, "Waiting\r");
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_ButtonPress - A button was pressed while Tinybooter 
		// The data parameter is a pointer to the timeout value for the booter mode.
		////////////////////////////////////////////////////////////////////////////////////
	case State_ButtonPress:
		if (NULL != data)
		{
			UINT32 down, up;
			INT32* timeout_ms = (INT32*)data;

			// wait forever if a button was pressed
			*timeout_ms = -1;

			// process buttons
			while (Buttons_GetNextStateChange(down, up))
			{
				// leave a way to exit boot mode incase it was accidentally entered
				if (0 != (down & BUTTON_ENTR))
				{
					// force an enumerate and launch
					*timeout_ms = 0;
				}
			}
		}
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_ValidCommunication - TinyBooter has received valid communication from the host
		// The data parameter is a pointer to the timeout value for the booter mode.
		////////////////////////////////////////////////////////////////////////////////////
	case State_ValidCommunication:
		if (NULL != data)
		{
			INT32* timeout_ms = (INT32*)data;

			// if we received any com/usb data then let's change the timeout to at least 20 seconds
			if (*timeout_ms != -1 && *timeout_ms < 20000)
			{
				*timeout_ms = 20000;
			}
		}
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_Timeout - The default timeout for TinyBooter has expired and TinyBooter will 
		// perform an EnumerateAndLaunch
		////////////////////////////////////////////////////////////////////////////////////
	case State_Timeout:
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_MemoryXXX - Identifies memory accesses.
		////////////////////////////////////////////////////////////////////////////////////
	case State_MemoryWrite:
		hal_fprintf(STREAM_LCD, "Wr: 0x%08x\r", (UINT32)data);
		break;
	case State_MemoryErase:
		hal_fprintf(STREAM_LCD, "Er: 0x%08x\r", (UINT32)data);
		break;


		////////////////////////////////////////////////////////////////////////////////////
		// State_CryptoXXX - Start and result of Crypto signature check
		////////////////////////////////////////////////////////////////////////////////////
	case State_CryptoStart:
		hal_fprintf(STREAM_LCD, "Chk signature \r");
		hal_printf("Chk signature \r");
		break;
		// The data parameter is a boolean that represents signature PASS/FAILURE
	case State_CryptoResult:
		if ((bool)data)
		{
			hal_fprintf(STREAM_LCD, "Signature PASS\r\n\r\n");
			hal_printf("Signature PASS\r\n\r\n");
		}
		else
		{
			hal_fprintf(STREAM_LCD, "Signature FAIL\r\n\r\n");
			hal_printf("Signature FAIL\r\n\r\n");
		}
		DebuggerPort_Flush(HalSystemConfig.DebugTextPort);
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_Launch - The host has requested to launch an application at a given address, 
		//                or a timeout has occured and TinyBooter is about to launch the 
		//                first application it finds in FLASH.
		//
		// The data parameter is a UINT32 value representing the launch address
		////////////////////////////////////////////////////////////////////////////////////
	case State_Launch:
		UINT32 address = (UINT32)data;

		if (NULL != data)
		{
			hal_fprintf(STREAM_LCD, "Starting application at 0x%08x\r\n", address);
			debug_printf("Starting application at 0x%08x\r\n", address);

			if (address == CODE_BASEADDRESS || address == EXCODE_BASEADDRESS)
			{
				BlockStorageDevice *device;
				ByteAddress ByteAddress;
				UINT32 physicalAddress = CODE_BASEADDRESS;

				if (BlockStorageList::FindDeviceForPhysicalAddress(&device, physicalAddress, ByteAddress))
				{
					BlockStorageStream stream;

					if (stream.Initialize(BlockUsage::CODE, device))
					{
						if (stream.CurrentAddress() != CODE_BASEADDRESS)
						{
							hal_fprintf(STREAM_LCD, "Warn: at wrong offset: 0x%08x\r\n", (UINT32)stream.CurrentAddress());
							debug_printf("Warn: at wrong offset: 0x%08x\r\n", (UINT32)stream.CurrentAddress());
							stream.Seek(CODE_BASEADDRESS - stream.CurrentAddress(), BlockStorageStream::SeekCurrent);
						}

						BYTE *dst;
						dst = (BYTE *)EXCODE_BASEADDRESS;

						stream.Read(&dst, CODE_SIZE);

						if (retData != NULL)
						{
							*retData = (void*)EXCODE_BASEADDRESS;
						}

						CPU_DrainWriteBuffers();
					}
				}
			}
			else if (retData != NULL)
			{
				*retData = (void*)data;
			}
		}
		break;
	}

}