adding debug log function

This commit is contained in:
hathach 2019-10-23 21:18:46 +07:00
parent 78bf82291e
commit 661515a807
6 changed files with 174 additions and 32 deletions

View File

@ -4,7 +4,7 @@
[![Build Status](https://travis-ci.org/hathach/tinyusb.svg?branch=master)](https://travis-ci.org/hathach/tinyusb) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT)
TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system. It is designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the stack's task function.
TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.
![tinyusb](https://user-images.githubusercontent.com/249515/49858616-f60c9700-fe27-11e8-8627-e76936352ff7.png)
@ -54,7 +54,7 @@ Support multiple device configurations by dynamically changing usb descriptors.
## OS Abtraction layer
TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context. It also uses semphore/mutex to access shared resource such as CDC FIFO. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box.
TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context task function. It also uses semphore/mutex to access shared resource such as CDC FIFO. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box.
- **No OS** : Disabling USB IRQ is used as way to provide mutex
- **FreeRTOS**
@ -84,6 +84,7 @@ TinyUSB is currently used by these other projects:
* [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader)
* [Adafruit SAMD Arduino](https://github.com/adafruit/ArduinoCore-samd)
* [CircuitPython](https://github.com/adafruit/circuitpython)
* [MicroPython](https://github.com/micropython/micropython)
* [TinyUSB Arduino Library](https://github.com/adafruit/Adafruit_TinyUSB_Arduino)
Let's me know if your project also uses TinyUSB and want to share.

View File

@ -214,8 +214,7 @@ int board_uart_read(uint8_t* buf, int len)
int board_uart_write(void const * buf, int len)
{
HAL_UART_Transmit(&UartHandle, (uint8_t*) buf, len, 0xffff);
// (void) buf; (void) len;
return 0;
return len;
}
#if CFG_TUSB_OS == OPT_OS_NONE

View File

@ -35,7 +35,7 @@
extern "C" {
#endif
//--------------------------------------------------------------------+
//--------------------------------------------------------------------+
// Macros Helper
//--------------------------------------------------------------------+
#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
@ -58,7 +58,7 @@
#define TU_BIT(n) (1U << (n))
//--------------------------------------------------------------------+
// INCLUDES
// Includes
//--------------------------------------------------------------------+
// Standard Headers
@ -77,7 +77,7 @@
#include "tusb_types.h"
//--------------------------------------------------------------------+
// INLINE FUNCTION
// Inline Functions
//--------------------------------------------------------------------+
#define tu_memclr(buffer, size) memset((buffer), 0, (size))
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
@ -203,6 +203,44 @@ static inline bool tu_bit_test (uint32_t value, uint8_t n) { return (value &
+ TU_BIN8(dlsb))
#endif
//--------------------------------------------------------------------+
// Debug Function
//--------------------------------------------------------------------+
// CFG_TUSB_DEBUG for debugging
// 0 : no debug
// 1 : print when there is error
// 2 : print out log
#if CFG_TUSB_DEBUG
void tu_print_mem(void const *buf, uint8_t size, uint16_t count);
#ifndef tu_printf
#define tu_printf printf
#endif
// Log with debug level 1
#define TU_LOG1 tu_printf
#define TU_LOG1_MEM tu_print_mem
// Log with debug level 2
#if CFG_TUSB_DEBUG > 1
#define TU_LOG2 TU_LOG1
#define TU_LOG2_MEM TU_LOG1_MEM
#endif
#endif // CFG_TUSB_DEBUG
#ifndef TU_LOG1
#define TU_LOG1(...)
#define TU_LOG1_MEM(...)
#endif
#ifndef TU_LOG2
#define TU_LOG2(...)
#define TU_LOG2_MEM(...)
#endif
#ifdef __cplusplus
}
#endif

View File

@ -39,7 +39,8 @@
typedef enum
{
DCD_EVENT_BUS_RESET = 1,
DCD_EVENT_INVALID = 0,
DCD_EVENT_BUS_RESET,
DCD_EVENT_UNPLUGGED,
DCD_EVENT_SOF,
DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
@ -49,7 +50,9 @@ typedef enum
DCD_EVENT_XFER_COMPLETE,
// Not an DCD event, just a convenient way to defer ISR function
USBD_EVENT_FUNC_CALL
USBD_EVENT_FUNC_CALL,
DCD_EVENT_COUNT
} dcd_eventid_t;
typedef struct TU_ATTR_ALIGNED(4)

View File

@ -192,6 +192,25 @@ void usbd_control_reset (uint8_t rhport);
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) );
//--------------------------------------------------------------------+
// Debugging
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG
static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
{
"INVALID" ,
"BUS_RESET" ,
"UNPLUGGED" ,
"SOF" ,
"SUSPEND" ,
"RESUME" ,
"SETUP_RECEIVED" ,
"XFER_COMPLETE" ,
"FUNC_CALL"
};
#endif
//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
@ -218,6 +237,8 @@ bool tud_remote_wakeup(void)
//--------------------------------------------------------------------+
bool usbd_init (void)
{
TU_LOG2("USBD Init\r\n");
tu_varclr(&_usbd_dev);
// Init device queue & task
@ -279,6 +300,8 @@ void tud_task (void)
if ( !osal_queue_receive(_usbd_q, &event) ) return;
TU_LOG2("USBD: event %s\r\n", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
switch ( event.event_id )
{
case DCD_EVENT_BUS_RESET:
@ -293,6 +316,8 @@ void tud_task (void)
break;
case DCD_EVENT_SETUP_RECEIVED:
TU_LOG2_MEM(&event.setup_received, 1, 8);
// Mark as connected after receiving 1st setup packet.
// But it is easier to set it every time instead of wasting time to check then set
_usbd_dev.connected = 1;
@ -307,29 +332,29 @@ void tud_task (void)
break;
case DCD_EVENT_XFER_COMPLETE:
// Only handle xfer callback in ready state
// if (_usbd_dev.connected && !_usbd_dev.suspended)
{
// Invoke the class callback associated with the endpoint address
uint8_t const ep_addr = event.xfer_complete.ep_addr;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const ep_dir = tu_edpt_dir(ep_addr);
TU_LOG2("Endpoint: 0x%02X, Bytes: %ld\r\n", ep_addr, event.xfer_complete.len);
_usbd_dev.ep_status[epnum][ep_dir].busy = false;
if ( 0 == epnum )
{
// Invoke the class callback associated with the endpoint address
uint8_t const ep_addr = event.xfer_complete.ep_addr;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const ep_dir = tu_edpt_dir(ep_addr);
_usbd_dev.ep_status[epnum][ep_dir].busy = false;
if ( 0 == epnum )
{
// control transfer DATA stage callback
usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
else
{
uint8_t const drv_id = _usbd_dev.ep2drv[epnum][ep_dir];
TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,);
usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
// control transfer DATA stage callback
usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
else
{
uint8_t const drv_id = _usbd_dev.ep2drv[epnum][ep_dir];
TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,);
usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
}
break;
case DCD_EVENT_SUSPEND:

View File

@ -43,11 +43,11 @@ bool tusb_init(void)
if (_initialized) return true;
#if TUSB_OPT_HOST_ENABLED
TU_VERIFY( usbh_init() ); // init host stack
TU_ASSERT( usbh_init() ); // init host stack
#endif
#if TUSB_OPT_DEVICE_ENABLED
TU_VERIFY ( usbd_init() ); // init device stack
TU_ASSERT ( usbd_init() ); // init device stack
#endif
_initialized = true;
@ -64,7 +64,83 @@ bool tusb_inited(void)
/* Debug
*------------------------------------------------------------------*/
#if CFG_TUSB_DEBUG
#include <ctype.h>
char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) };
static void dump_str_line(uint8_t const* buf, uint16_t count)
{
// each line is 16 bytes
for(int i=0; i<count; i++)
{
const char ch = buf[i];
tu_printf("%c", isprint(ch) ? ch : '.');
}
}
// size : item size in bytes
// count : number of item
// print offet or not (handfy for dumping large memory)
void tu_print_mem(void const *buf, uint8_t size, uint16_t count)
{
if ( !buf || !count )
{
tu_printf("NULL\n");
return;
}
uint8_t const *buf8 = (uint8_t const *) buf;
char format[] = "%00lX";
format[2] += 2*size;
const uint8_t item_per_line = 16 / size;
for(uint32_t i=0; i<count; i++)
{
uint32_t value=0;
if ( i%item_per_line == 0 )
{
// Print Ascii
if ( i != 0 )
{
tu_printf(" | ");
dump_str_line(buf8-16, 16);
tu_printf("\n");
}
// print offset or absolute address
tu_printf("%03lX: ", 16*i/item_per_line);
}
memcpy(&value, buf8, size);
buf8 += size;
tu_printf(" ");
tu_printf(format, value);
}
// fill up last row to 16 for printing ascii
const uint16_t remain = count%16;
uint8_t nback = (remain ? remain : 16);
if ( remain )
{
for(int i=0; i< 16-remain; i++)
{
tu_printf(" ");
for(int j=0; j<2*size; j++) tu_printf(" ");
}
}
tu_printf(" | ");
dump_str_line(buf8-nback, nback);
tu_printf("\n");
tu_printf("\n");
}
#endif
#endif // host or device enabled