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