This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Implementing a non-hanging USB listener

I'm working with an LPC1768(FBD100) and need to connect to a PC through a serial USB. As a starting point, I used the sample package USB virtual com port.

Installed packages:

My code:

#include "includes.h"


int main (void) {
MenuEntryVType* MenuEntry;
GUI_Init();
WM_SetCreateFlags(WM_CF_MEMDEV);

FRAMEWIN_SetDefaultSkinClassic();
PROGBAR_SetDefaultSkinClassic();
SCROLLBAR_SetDefaultSkinClassic();
FRAMEWIN_SetDefaultFont(StdFont);

InitOutputs();
InitADCs();
InitDAC();
InitPWM(100);
InitI2C();
GetConfig();


osDelay(1500);


// Works as expected ; new COMx device shows in dev manager.
USBD_Initialize (0U); // USB Device 0 Initialization
USBD_Connect (0U); // USB Device 0 Connect


// menu handling code
// actual functionality start servos, etc.)
// does not get executed. Why?
return 0;
}

Why does USBD_Connect() hang? no code gets executed past that point; the lpc1768 does connect, however, to the PC:

rl_usb.h contains the definitions of USBD_Initialize() and USBD_Connect():

/// \brief Initialize USB Device stack and controller
/// \param[in] device index of USB Device.
/// \return status code that indicates the execution status of the function as defined with \ref usbStatus.
extern usbStatus USBD_Initialize (uint8_t device);

/// \brief Activate pull-up on D+ or D- line to signal USB Device connection on USB Bus
/// \param[in] device index of USB Device.
/// \return status code that indicates the execution status of the function as defined with \ref usbStatus.
extern usbStatus USBD_Connect (uint8_t device);
 

These are function declarations; I don't know where the implementations are (likely in USB_CM3_L.lib).

Read/write functions are defined in USBD_User_CDC_ACM_UART_0.c

/*------------------------------------------------------------------------------
 * MDK Middleware - Component ::USB:Device
 * Copyright (c) 2004-2019 ARM Germany GmbH. All rights reserved.
 *------------------------------------------------------------------------------
 * Name:    USBD_User_CDC_ACM_UART_0.c
 * Purpose: USB Device Communication Device Class (CDC)
 *          Abstract Control Model (ACM) USB <-> UART Bridge User module
 * Rev.:    V1.0.3
 *----------------------------------------------------------------------------*/
/**
 * \addtogroup usbd_cdcFunctions
 *
 * USBD_User_CDC_ACM_UART_0.c implements the application specific
 * functionality of the CDC ACM class and is used to demonstrate a USB <-> UART
 * bridge. All data received on USB is transmitted on UART and all data
 * received on UART is transmitted on USB.
 *
 * Details of operation:
 *   UART -> USB:
 *     Initial reception on UART is started after the USB Host sets line coding
 *     with SetLineCoding command. Having received a full UART buffer, any
 *     new reception is restarted on the same buffer. Any data received on
 *     the UART is sent over USB using the CDC0_ACM_UART_to_USB_Thread thread.
 *   USB -> UART:
 *     While the UART transmit is not busy, data transmission on the UART is
 *     started in the USBD_CDC0_ACM_DataReceived callback as soon as data is
 *     received on the USB. Further data received on USB is transmitted on
 *     UART in the UART callback routine until there is no more data available.
 *     In this case, the next UART transmit is restarted from the
 *     USBD_CDC0_ACM_DataReceived callback as soon as new data is received
 *     on the USB.
 *
 * The following constants in this module affect the module functionality:
 *
 *  - UART_PORT:        specifies UART Port
 *      default value:  0 (=UART0)
 *  - UART_BUFFER_SIZE: specifies UART data Buffer Size
 *      default value:  512
 *
 * Notes:
 *   If the USB is slower than the UART, data can get lost. This may happen
 *   when USB is pausing during data reception because of the USB Host being
 *   too loaded with other tasks and not polling the Bulk IN Endpoint often
 *   enough (up to 2 seconds of gap in polling Bulk IN Endpoint may occur).
 *   This problem can be solved by using a large enough UART buffer to
 *   compensate up to a few seconds of received UART data or by using UART
 *   flow control.
 *   If the device that receives the UART data (usually a PC) is too loaded
 *   with other tasks it can also loose UART data. This problem can only be
 *   solved by using UART flow control.
 *
 *   This file has to be adapted in case of UART flow control usage.
 */
 
 
//! [code_USBD_User_CDC_ACM]
 
#include <stdbool.h>
#include "rl_usb.h"
 
#if defined(RTE_CMSIS_RTOS2)
  #include "cmsis_os2.h"
#if defined(RTE_CMSIS_RTOS2_RTX5)
  #include "rtx_os.h"
#endif
#endif
#if defined(RTE_CMSIS_RTOS)
  #include "cmsis_os.h"
#endif
 
#include "Driver_USART.h"
 
// UART Configuration ----------------------------------------------------------
 
#define  UART_PORT              1       // UART Port number
#define  UART_BUFFER_SIZE       512     // UART Buffer Size
 
//------------------------------------------------------------------------------
 
#define _UART_Driver_(n)        Driver_USART##n
#define  UART_Driver_(n)       _UART_Driver_(n)
extern   ARM_DRIVER_USART       UART_Driver_(UART_PORT);
#define  ptrUART              (&UART_Driver_(UART_PORT))
 
// External functions
#ifdef   USB_CMSIS_RTOS
extern   void                   CDC0_ACM_UART_to_USB_Thread (void const *arg) __attribute((noreturn));
#endif
 
// Local Variables
static            uint8_t       uart_rx_buf[UART_BUFFER_SIZE];
static            uint8_t       uart_tx_buf[UART_BUFFER_SIZE];
 
static   volatile int32_t       uart_rx_cnt         =   0;
static   volatile int32_t       usb_tx_cnt          =   0;
 
static   void                  *cdc_acm_bridge_tid  =   0U;
static   CDC_LINE_CODING        cdc_acm_line_coding = { 0U, 0U, 0U, 0U };
 
 
// Called when UART has transmitted or received requested number of bytes.
// \param[in]   event         UART event
//               - ARM_USART_EVENT_SEND_COMPLETE:    all requested data was sent
//               - ARM_USART_EVENT_RECEIVE_COMPLETE: all requested data was received
static void UART_Callback (uint32_t event) {
  int32_t cnt;
 
  if (event & ARM_USART_EVENT_SEND_COMPLETE) {
    // USB -> UART
    cnt = USBD_CDC_ACM_ReadData(0U, uart_tx_buf, UART_BUFFER_SIZE);
    if (cnt > 0) {
      ptrUART->Send(uart_tx_buf, (uint32_t)(cnt));
    }
  }
 
  if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) {
    // UART data received, restart new reception
    uart_rx_cnt += UART_BUFFER_SIZE;
    ptrUART->Receive(uart_rx_buf, UART_BUFFER_SIZE);
  }
}
 
// Thread: Sends data received on UART to USB
// \param[in]     arg           not used.
#ifdef USB_CMSIS_RTOS2
__NO_RETURN static void CDC0_ACM_UART_to_USB_Thread (void *arg) {
#else
__NO_RETURN        void CDC0_ACM_UART_to_USB_Thread (void const *arg) {
#endif
  int32_t cnt, cnt_to_wrap;
 
  (void)(arg);
 
  while (1) {
    // UART - > USB
    if (ptrUART->GetStatus().rx_busy != 0U) {
      cnt  = uart_rx_cnt;
      cnt += ptrUART->GetRxCount();
      cnt -= usb_tx_cnt;
      if (cnt >= UART_BUFFER_SIZE) {
        // Dump data received on UART if USB is not consuming fast enough
        usb_tx_cnt += cnt;
        cnt = 0U;
      }
      if (cnt > 0) {
        cnt_to_wrap = (int32_t)(UART_BUFFER_SIZE - ((uint32_t)usb_tx_cnt & (UART_BUFFER_SIZE - 1)));
        if (cnt > cnt_to_wrap) {
          cnt = cnt_to_wrap;
        }
        cnt = USBD_CDC_ACM_WriteData(0U, (uart_rx_buf + ((uint32_t)usb_tx_cnt & (UART_BUFFER_SIZE - 1))), cnt);
        if (cnt > 0) {
          usb_tx_cnt += cnt;
        }
      }
    }
    osDelay(10U);
  }
}
#ifdef USB_CMSIS_RTOS2
#ifdef USB_CMSIS_RTOS2_RTX5
static osRtxThread_t        cdc0_acm_uart_to_usb_thread_cb_mem               __SECTION(.bss.os.thread.cb);
static uint64_t             cdc0_acm_uart_to_usb_thread_stack_mem[512U / 8U] __SECTION(.bss.os.thread.stack);
#endif
static const osThreadAttr_t cdc0_acm_uart_to_usb_thread_attr = {
  "CDC0_ACM_UART_to_USB_Thread",
  0U,
#ifdef USB_CMSIS_RTOS2_RTX5
 &cdc0_acm_uart_to_usb_thread_cb_mem,
  sizeof(osRtxThread_t),
 &cdc0_acm_uart_to_usb_thread_stack_mem[0],
#else
  NULL,
  0U,
  NULL,
#endif
  512U,
  osPriorityNormal,
  0U,
  0U
};
#else
extern const osThreadDef_t os_thread_def_CDC0_ACM_UART_to_USB_Thread;
osThreadDef (CDC0_ACM_UART_to_USB_Thread, osPriorityNormal, 1U, 0U);
#endif
 
 
// CDC ACM Callbacks -----------------------------------------------------------
 
// Called when new data was received from the USB Host.
// \param[in]   len           number of bytes available to read.
void USBD_CDC0_ACM_DataReceived (uint32_t len) {
  int32_t cnt;
 
  (void)(len);
 
  if (ptrUART->GetStatus().tx_busy == 0U) {
    // Start USB -> UART
    cnt = USBD_CDC_ACM_ReadData(0U, uart_tx_buf, UART_BUFFER_SIZE);
    if (cnt > 0) {
      ptrUART->Send(uart_tx_buf, (uint32_t)(cnt));
    }
  }
}
 
// Called during USBD_Initialize to initialize the USB CDC class instance (ACM).
void USBD_CDC0_ACM_Initialize (void) {
  ptrUART->Initialize   (UART_Callback);
  ptrUART->PowerControl (ARM_POWER_FULL);
 
#ifdef USB_CMSIS_RTOS2
  cdc_acm_bridge_tid = osThreadNew (CDC0_ACM_UART_to_USB_Thread, NULL, &cdc0_acm_uart_to_usb_thread_attr);
#else
  cdc_acm_bridge_tid = osThreadCreate (osThread (CDC0_ACM_UART_to_USB_Thread), NULL);
#endif
}
 
 
// Called during USBD_Uninitialize to de-initialize the USB CDC class instance (ACM).
void USBD_CDC0_ACM_Uninitialize (void) {
 
  if (osThreadTerminate (cdc_acm_bridge_tid) == osOK) {
    cdc_acm_bridge_tid = NULL;
  }
 
  ptrUART->Control      (ARM_USART_ABORT_RECEIVE, 0U);
  ptrUART->PowerControl (ARM_POWER_OFF);
  ptrUART->Uninitialize ();
}
 
 
// Called upon USB Bus Reset Event.
void USBD_CDC0_ACM_Reset (void) {
  ptrUART->Control      (ARM_USART_ABORT_SEND,    0U);
  ptrUART->Control      (ARM_USART_ABORT_RECEIVE, 0U);
}
 
 
// Called upon USB Host request to change communication settings.
// \param[in]   line_coding   pointer to CDC_LINE_CODING structure.
// \return      true          set line coding request processed.
// \return      false         set line coding request not supported or not processed.
bool USBD_CDC0_ACM_SetLineCoding (const CDC_LINE_CODING *line_coding) {
  uint32_t data_bits = 0U, parity = 0U, stop_bits = 0U;
  int32_t  status;
 
  ptrUART->Control (ARM_USART_ABORT_SEND,    0U);
  ptrUART->Control (ARM_USART_ABORT_RECEIVE, 0U);
  ptrUART->Control (ARM_USART_CONTROL_TX,    0U);
  ptrUART->Control (ARM_USART_CONTROL_RX,    0U);
 
  switch (line_coding->bCharFormat) {
    case 0:                             // 1 Stop bit
      stop_bits = ARM_USART_STOP_BITS_1;
      break;
    case 1:                             // 1.5 Stop bits
      stop_bits = ARM_USART_STOP_BITS_1_5;
      break;
    case 2:                             // 2 Stop bits
      stop_bits = ARM_USART_STOP_BITS_2;
  }
 
  switch (line_coding->bParityType) {
    case 0:                             // None
      parity = ARM_USART_PARITY_NONE;
      break;
    case 1:                             // Odd
      parity = ARM_USART_PARITY_ODD;
      break;
    case 2:                             // Even
      parity = ARM_USART_PARITY_EVEN;
      break;
    default:
      return false;
  }
 
  switch (line_coding->bDataBits) {
    case 5:
      data_bits = ARM_USART_DATA_BITS_5;
      break;
    case 6:
      data_bits = ARM_USART_DATA_BITS_6;
      break;
    case 7:
      data_bits = ARM_USART_DATA_BITS_7;
      break;
    case 8:
      data_bits = ARM_USART_DATA_BITS_8;
      break;
    default:
      return false;
  }
 
  status = ptrUART->Control(ARM_USART_MODE_ASYNCHRONOUS  |
                            data_bits                    |
                            parity                       |
                            stop_bits                    |
                            ARM_USART_FLOW_CONTROL_NONE  ,
                            line_coding->dwDTERate       );

  if (status != ARM_DRIVER_OK) {
    return false;
  }
 
  // Store requested settings to local variable
  cdc_acm_line_coding = *line_coding;
 
  uart_rx_cnt = 0;
  usb_tx_cnt  = 0;
 
  ptrUART->Control (ARM_USART_CONTROL_TX, 1U);
  ptrUART->Control (ARM_USART_CONTROL_RX, 1U);
 
  ptrUART->Receive (uart_rx_buf, UART_BUFFER_SIZE);
 
  return true;
}
 
 
// Called upon USB Host request to retrieve communication settings.
// \param[out]  line_coding   pointer to CDC_LINE_CODING structure.
// \return      true          get line coding request processed.
// \return      false         get line coding request not supported or not processed.
bool USBD_CDC0_ACM_GetLineCoding (CDC_LINE_CODING *line_coding) {
 
  // Load settings from ones stored on USBD_CDC0_ACM_SetLineCoding callback
  *line_coding = cdc_acm_line_coding;
 
  return true;
}
 
 
// Called upon USB Host request to set control line states.
// \param [in]  state         control line settings bitmap.
//                - bit 0: DTR state
//                - bit 1: RTS state
// \return      true          set control line state request processed.
// \return      false         set control line state request not supported or not processed.
bool USBD_CDC0_ACM_SetControlLineState (uint16_t state) {
  // Add code for set control line state
 
  (void)(state);
 
  return true;
}
 
//! [code_USBD_User_CDC_ACM]

Is it possible to run the lpc1768 as a USB listener and also perform a set of tasks in parallel? If yes, how should I go about it?

Parents
  • These are the config files:

    startup_LPC17xx.s:

    ;/**************************************************************************//**
    ; * @file     startup_LPC17xx.s
    ; * @brief    CMSIS Cortex-M3 Core Device Startup File for
    ; *           NXP LPC17xx Device Series
    ; * @version  V1.10
    ; * @date     06. April 2011
    ; *
    ; * @note
    ; * Copyright (C) 2009-2011 ARM Limited. All rights reserved.
    ; *
    ; * @par
    ; * ARM Limited (ARM) is supplying this software for use with Cortex-M
    ; * processor based microcontrollers.  This file can be freely distributed
    ; * within development tools that are supporting such ARM based processors.
    ; *
    ; * @par
    ; * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
    ; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
    ; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
    ; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
    ; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
    ; *
    ; ******************************************************************************/
    
    ; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
    
    ; <h> Stack Configuration
    ;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    Stack_Size      EQU     0x00000200
    
                    AREA    STACK, NOINIT, READWRITE, ALIGN=3
    Stack_Mem       SPACE   Stack_Size
    __initial_sp
    
    
    ; <h> Heap Configuration
    ;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    Heap_Size       EQU     0x00000000
    
                    AREA    HEAP, NOINIT, READWRITE, ALIGN=3
    __heap_base
    Heap_Mem        SPACE   Heap_Size
    __heap_limit
    
    
                    PRESERVE8
                    THUMB
    
    
    ; Vector Table Mapped to Address 0 at Reset
    
                    AREA    RESET, DATA, READONLY
                    EXPORT  __Vectors
    
    __Vectors       DCD     __initial_sp              ; Top of Stack
                    DCD     Reset_Handler             ; Reset Handler
                    DCD     NMI_Handler               ; NMI Handler
                    DCD     HardFault_Handler         ; Hard Fault Handler
                    DCD     MemManage_Handler         ; MPU Fault Handler
                    DCD     BusFault_Handler          ; Bus Fault Handler
                    DCD     UsageFault_Handler        ; Usage Fault Handler
                    DCD     0                         ; Reserved
                    DCD     0                         ; Reserved
                    DCD     0                         ; Reserved
                    DCD     0                         ; Reserved
                    DCD     SVC_Handler               ; SVCall Handler
                    DCD     DebugMon_Handler          ; Debug Monitor Handler
                    DCD     0                         ; Reserved
                    DCD     PendSV_Handler            ; PendSV Handler
                    DCD     SysTick_Handler           ; SysTick Handler
    
                    ; External Interrupts
                    DCD     WDT_IRQHandler            ; 16: Watchdog Timer
                    DCD     TIMER0_IRQHandler         ; 17: Timer0
                    DCD     TIMER1_IRQHandler         ; 18: Timer1
                    DCD     TIMER2_IRQHandler         ; 19: Timer2
                    DCD     TIMER3_IRQHandler         ; 20: Timer3
                    DCD     UART0_IRQHandler          ; 21: UART0
                    DCD     UART1_IRQHandler          ; 22: UART1
                    DCD     UART2_IRQHandler          ; 23: UART2
                    DCD     UART3_IRQHandler          ; 24: UART3
                    DCD     PWM1_IRQHandler           ; 25: PWM1
                    DCD     I2C0_IRQHandler           ; 26: I2C0
                    DCD     I2C1_IRQHandler           ; 27: I2C1
                    DCD     I2C2_IRQHandler           ; 28: I2C2
                    DCD     SPI_IRQHandler            ; 29: SPI
                    DCD     SSP0_IRQHandler           ; 30: SSP0
                    DCD     SSP1_IRQHandler           ; 31: SSP1
                    DCD     PLL0_IRQHandler           ; 32: PLL0 Lock (Main PLL)
                    DCD     RTC_IRQHandler            ; 33: Real Time Clock
                    DCD     EINT0_IRQHandler          ; 34: External Interrupt 0
                    DCD     EINT1_IRQHandler          ; 35: External Interrupt 1
                    DCD     EINT2_IRQHandler          ; 36: External Interrupt 2
                    DCD     EINT3_IRQHandler          ; 37: External Interrupt 3
                    DCD     ADC_IRQHandler            ; 38: A/D Converter
                    DCD     BOD_IRQHandler            ; 39: Brown-Out Detect
                    DCD     USB_IRQHandler            ; 40: USB
                    DCD     CAN_IRQHandler            ; 41: CAN
                    DCD     DMA_IRQHandler            ; 42: General Purpose DMA
                    DCD     I2S_IRQHandler            ; 43: I2S
                    DCD     ENET_IRQHandler           ; 44: Ethernet
                    DCD     RIT_IRQHandler            ; 45: Repetitive Interrupt Timer
                    DCD     MCPWM_IRQHandler          ; 46: Motor Control PWM
                    DCD     QEI_IRQHandler            ; 47: Quadrature Encoder Interface
                    DCD     PLL1_IRQHandler           ; 48: PLL1 Lock (USB PLL)
                    DCD     USBActivity_IRQHandler    ; 49: USB Activity interrupt to wakeup
                    DCD     CANActivity_IRQHandler    ; 50: CAN Activity interrupt to wakeup
    
    
                    IF      :LNOT::DEF:NO_CRP
                    AREA    |.ARM.__at_0x02FC|, CODE, READONLY
    CRP_Key         DCD     0xFFFFFFFF
                    ENDIF
    
    
                    AREA    |.text|, CODE, READONLY
    
    
    ; Reset Handler
    
    Reset_Handler   PROC
                    EXPORT  Reset_Handler             [WEAK]
                    IMPORT  SystemInit
                    IMPORT  __main
                    LDR     R0, =SystemInit
                    BLX     R0
                    LDR     R0, =__main
                    BX      R0
                    ENDP
    
    
    ; Dummy Exception Handlers (infinite loops which can be modified)
    
    NMI_Handler     PROC
                    EXPORT  NMI_Handler               [WEAK]
                    B       .
                    ENDP
    HardFault_Handler\
                    PROC
                    EXPORT  HardFault_Handler         [WEAK]
                    B       .
                    ENDP
    MemManage_Handler\
                    PROC
                    EXPORT  MemManage_Handler         [WEAK]
                    B       .
                    ENDP
    BusFault_Handler\
                    PROC
                    EXPORT  BusFault_Handler          [WEAK]
                    B       .
                    ENDP
    UsageFault_Handler\
                    PROC
                    EXPORT  UsageFault_Handler        [WEAK]
                    B       .
                    ENDP
    SVC_Handler     PROC
                    EXPORT  SVC_Handler               [WEAK]
                    B       .
                    ENDP
    DebugMon_Handler\
                    PROC
                    EXPORT  DebugMon_Handler          [WEAK]
                    B       .
                    ENDP
    PendSV_Handler  PROC
                    EXPORT  PendSV_Handler            [WEAK]
                    B       .
                    ENDP
    SysTick_Handler PROC
                    EXPORT  SysTick_Handler           [WEAK]
                    B       .
                    ENDP
    
    Default_Handler PROC
    
                    EXPORT  WDT_IRQHandler            [WEAK]
                    EXPORT  TIMER0_IRQHandler         [WEAK]
                    EXPORT  TIMER1_IRQHandler         [WEAK]
                    EXPORT  TIMER2_IRQHandler         [WEAK]
                    EXPORT  TIMER3_IRQHandler         [WEAK]
                    EXPORT  UART0_IRQHandler          [WEAK]
                    EXPORT  UART1_IRQHandler          [WEAK]
                    EXPORT  UART2_IRQHandler          [WEAK]
                    EXPORT  UART3_IRQHandler          [WEAK]
                    EXPORT  PWM1_IRQHandler           [WEAK]
                    EXPORT  I2C0_IRQHandler           [WEAK]
                    EXPORT  I2C1_IRQHandler           [WEAK]
                    EXPORT  I2C2_IRQHandler           [WEAK]
                    EXPORT  SPI_IRQHandler            [WEAK]
                    EXPORT  SSP0_IRQHandler           [WEAK]
                    EXPORT  SSP1_IRQHandler           [WEAK]
                    EXPORT  PLL0_IRQHandler           [WEAK]
                    EXPORT  RTC_IRQHandler            [WEAK]
                    EXPORT  EINT0_IRQHandler          [WEAK]
                    EXPORT  EINT1_IRQHandler          [WEAK]
                    EXPORT  EINT2_IRQHandler          [WEAK]
                    EXPORT  EINT3_IRQHandler          [WEAK]
                    EXPORT  ADC_IRQHandler            [WEAK]
                    EXPORT  BOD_IRQHandler            [WEAK]
                    EXPORT  USB_IRQHandler            [WEAK]
                    EXPORT  CAN_IRQHandler            [WEAK]
                    EXPORT  DMA_IRQHandler            [WEAK]
                    EXPORT  I2S_IRQHandler            [WEAK]
                    EXPORT  ENET_IRQHandler           [WEAK]
                    EXPORT  RIT_IRQHandler            [WEAK]
                    EXPORT  MCPWM_IRQHandler          [WEAK]
                    EXPORT  QEI_IRQHandler            [WEAK]
                    EXPORT  PLL1_IRQHandler           [WEAK]
                    EXPORT  USBActivity_IRQHandler    [WEAK]
                    EXPORT  CANActivity_IRQHandler    [WEAK]
    
    WDT_IRQHandler
    TIMER0_IRQHandler
    TIMER1_IRQHandler
    TIMER2_IRQHandler
    TIMER3_IRQHandler
    UART0_IRQHandler
    UART1_IRQHandler
    UART2_IRQHandler
    UART3_IRQHandler
    PWM1_IRQHandler
    I2C0_IRQHandler
    I2C1_IRQHandler
    I2C2_IRQHandler
    SPI_IRQHandler
    SSP0_IRQHandler
    SSP1_IRQHandler
    PLL0_IRQHandler
    RTC_IRQHandler
    EINT0_IRQHandler
    EINT1_IRQHandler
    EINT2_IRQHandler
    EINT3_IRQHandler
    ADC_IRQHandler
    BOD_IRQHandler
    USB_IRQHandler
    CAN_IRQHandler
    DMA_IRQHandler
    I2S_IRQHandler
    ENET_IRQHandler
    RIT_IRQHandler
    MCPWM_IRQHandler
    QEI_IRQHandler
    PLL1_IRQHandler
    USBActivity_IRQHandler
    CANActivity_IRQHandler
    
                    B       .
    
                    ENDP
    
    
                    ALIGN
    
    
    ; User Initial Stack & Heap
    
                    IF      :DEF:__MICROLIB
    
                    EXPORT  __initial_sp
                    EXPORT  __heap_base
                    EXPORT  __heap_limit
    
                    ELSE
    
                    IMPORT  __use_two_region_memory
                    EXPORT  __user_initial_stackheap
    __user_initial_stackheap
    
                    LDR     R0, =  Heap_Mem
                    LDR     R1, =(Stack_Mem + Stack_Size)
                    LDR     R2, = (Heap_Mem +  Heap_Size)
                    LDR     R3, = Stack_Mem
                    BX      LR
    
                    ALIGN
    
                    ENDIF
    
    
                    END
    

    I played with the stack size according to:

    http://www.keil.com/pack/doc/mw/USB/html/usb_resource_requirements.html#usbd_res_req 

    I have a CDC (2 threads) and 4 threads totalling 6 * 512 = 3072 bytes but the behavior persists. 

    In 

    RTX_Conf_CM.c:

    ...
    #include "cmsis_os.h"
     
    
    /*----------------------------------------------------------------------------
     *      RTX User configuration part BEGIN
     *---------------------------------------------------------------------------*/
     
    //-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
    //
    // <h>Thread Configuration
    // =======================
    //
    //   <o>Number of concurrent running user threads <1-250>
    //   <i> Defines max. number of user threads that will run at the same time.
    //   <i> Default: 6; initially 5
    #ifndef OS_TASKCNT
     #define OS_TASKCNT     5
    #endif
     
    //   <o>Default Thread stack size [bytes] <64-4096:8><#/4>
    //   <i> Defines default stack size for threads with osThreadDef stacksz = 0
    //   <i> Default: 200
    #ifndef OS_STKSIZE
     #define OS_STKSIZE     50      // this stack size value is in words
    #endif
     
    //   <o>Main Thread stack size [bytes] <64-32768:8><#/4>
    //   <i> Defines stack size for main thread.
    //   <i> Default: 200
    #ifndef OS_MAINSTKSIZE
     #define OS_MAINSTKSIZE 512     // this stack size value is in words
    #endif
     
    //   <o>Number of threads with user-provided stack size <0-250>
    //   <i> Defines the number of threads with user-provided stack size.
    //   <i> Default: 0
    #ifndef OS_PRIVCNT
     #define OS_PRIVCNT     2
    #endif
     
    //   <o>Total stack size [bytes] for threads with user-provided stack size <0-1048576:8><#/4>
    //   <i> Defines the combined stack size for threads with user-provided stack size.
    //   <i> Default: 0
    #ifndef OS_PRIVSTKSIZE
     #define OS_PRIVSTKSIZE 512       // this stack size value is in words
    #endif
     
    //   <q>Stack overflow checking
    //   <i> Enable stack overflow checks at thread switch.
    //   <i> Enabling this option increases slightly the execution time of a thread switch.
    #ifndef OS_STKCHECK
     #define OS_STKCHECK    1
    #endif
     
    //   <q>Stack usage watermark
    //   <i> Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer.
    //   <i> Enabling this option increases significantly the execution time of osThreadCreate.
    #ifndef OS_STKINIT
    #define OS_STKINIT      0
    #endif
     
    //   <o>Processor mode for thread execution 
    //     <0=> Unprivileged mode 
    //     <1=> Privileged mode
    //   <i> Default: Privileged mode
    #ifndef OS_RUNPRIV
     #define OS_RUNPRIV     1
    #endif
     
    // </h>
     
    // <h>RTX Kernel Timer Tick Configuration
    // ======================================
    //   <q> Use Cortex-M SysTick timer as RTX Kernel Timer
    //   <i> Cortex-M processors provide in most cases a SysTick timer that can be used as 
    //   <i> as time-base for RTX.
    #ifndef OS_SYSTICK
     #define OS_SYSTICK     1
    #endif
    //
    //   <o>RTOS Kernel Timer input clock frequency [Hz] <1-1000000000>
    //   <i> Defines the input frequency of the RTOS Kernel Timer.  
    //   <i> When the Cortex-M SysTick timer is used, the input clock 
    //   <i> is on most systems identical with the core clock.
    #ifndef OS_CLOCK
     #define OS_CLOCK       100000000
    #endif
     
    //   <o>RTX Timer tick interval value [us] <1-1000000>
    //   <i> The RTX Timer tick interval value is used to calculate timeout values.
    //   <i> When the Cortex-M SysTick timer is enabled, the value also configures the SysTick timer.
    //   <i> Default: 1000  (1ms)
    #ifndef OS_TICK
     #define OS_TICK        1000
    #endif
     
    // </h>
     
    // <h>System Configuration
    // =======================
    //
    // <e>Round-Robin Thread switching
    // ===============================
    //
    // <i> Enables Round-Robin Thread switching.
    #ifndef OS_ROBIN
     #define OS_ROBIN       1
    #endif
     
    //   <o>Round-Robin Timeout [ticks] <1-1000>
    //   <i> Defines how long a thread will execute before a thread switch.
    //   <i> Default: 5
    #ifndef OS_ROBINTOUT
     #define OS_ROBINTOUT   5
    #endif
     
    // </e>
     
    // <e>User Timers
    // ==============
    //   <i> Enables user Timers
    #ifndef OS_TIMERS
     #define OS_TIMERS      1
    #endif
     
    //   <o>Timer Thread Priority
    //                        <1=> Low
    //     <2=> Below Normal  <3=> Normal  <4=> Above Normal
    //                        <5=> High
    //                        <6=> Realtime (highest)
    //   <i> Defines priority for Timer Thread
    //   <i> Default: High
    #ifndef OS_TIMERPRIO
     #define OS_TIMERPRIO   5
    #endif
     
    //   <o>Timer Thread stack size [bytes] <64-4096:8><#/4>
    //   <i> Defines stack size for Timer thread.
    //   <i> Default: 200
    #ifndef OS_TIMERSTKSZ
     #define OS_TIMERSTKSZ  50     // this stack size value is in words
    #endif
     
    //   <o>Timer Callback Queue size <1-32>
    //   <i> Number of concurrent active timer callback functions.
    //   <i> Default: 4
    #ifndef OS_TIMERCBQS
     #define OS_TIMERCBQS   4
    #endif
     
    // </e>
     
    //   <o>ISR FIFO Queue size<4=>   4 entries  <8=>   8 entries
    //                         <12=> 12 entries  <16=> 16 entries
    //                         <24=> 24 entries  <32=> 32 entries
    //                         <48=> 48 entries  <64=> 64 entries
    //                         <96=> 96 entries
    //   <i> ISR functions store requests to this buffer,
    //   <i> when they are called from the interrupt handler.
    //   <i> Default: 16 entries
    #ifndef OS_FIFOSZ
     #define OS_FIFOSZ      16
    #endif
     
    // </h>
     
    //------------- <<< end of configuration section >>> -----------------------
     
    // Standard library system mutexes
    // ===============================
    //  Define max. number system mutexes that are used to protect 
    //  the arm standard runtime library. For microlib they are not used.
    #ifndef OS_MUTEXCNT
     #define OS_MUTEXCNT    8
    #endif
    
    ...

    5 is the max no. of threads, OS_STKSIZE is set to 50. I'm not exactly sure but do these conflict with the thread stack size?

    Do you happen to have any config files for USB + threaded apps lying around? 

Reply
  • These are the config files:

    startup_LPC17xx.s:

    ;/**************************************************************************//**
    ; * @file     startup_LPC17xx.s
    ; * @brief    CMSIS Cortex-M3 Core Device Startup File for
    ; *           NXP LPC17xx Device Series
    ; * @version  V1.10
    ; * @date     06. April 2011
    ; *
    ; * @note
    ; * Copyright (C) 2009-2011 ARM Limited. All rights reserved.
    ; *
    ; * @par
    ; * ARM Limited (ARM) is supplying this software for use with Cortex-M
    ; * processor based microcontrollers.  This file can be freely distributed
    ; * within development tools that are supporting such ARM based processors.
    ; *
    ; * @par
    ; * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
    ; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
    ; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
    ; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
    ; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
    ; *
    ; ******************************************************************************/
    
    ; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
    
    ; <h> Stack Configuration
    ;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    Stack_Size      EQU     0x00000200
    
                    AREA    STACK, NOINIT, READWRITE, ALIGN=3
    Stack_Mem       SPACE   Stack_Size
    __initial_sp
    
    
    ; <h> Heap Configuration
    ;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    Heap_Size       EQU     0x00000000
    
                    AREA    HEAP, NOINIT, READWRITE, ALIGN=3
    __heap_base
    Heap_Mem        SPACE   Heap_Size
    __heap_limit
    
    
                    PRESERVE8
                    THUMB
    
    
    ; Vector Table Mapped to Address 0 at Reset
    
                    AREA    RESET, DATA, READONLY
                    EXPORT  __Vectors
    
    __Vectors       DCD     __initial_sp              ; Top of Stack
                    DCD     Reset_Handler             ; Reset Handler
                    DCD     NMI_Handler               ; NMI Handler
                    DCD     HardFault_Handler         ; Hard Fault Handler
                    DCD     MemManage_Handler         ; MPU Fault Handler
                    DCD     BusFault_Handler          ; Bus Fault Handler
                    DCD     UsageFault_Handler        ; Usage Fault Handler
                    DCD     0                         ; Reserved
                    DCD     0                         ; Reserved
                    DCD     0                         ; Reserved
                    DCD     0                         ; Reserved
                    DCD     SVC_Handler               ; SVCall Handler
                    DCD     DebugMon_Handler          ; Debug Monitor Handler
                    DCD     0                         ; Reserved
                    DCD     PendSV_Handler            ; PendSV Handler
                    DCD     SysTick_Handler           ; SysTick Handler
    
                    ; External Interrupts
                    DCD     WDT_IRQHandler            ; 16: Watchdog Timer
                    DCD     TIMER0_IRQHandler         ; 17: Timer0
                    DCD     TIMER1_IRQHandler         ; 18: Timer1
                    DCD     TIMER2_IRQHandler         ; 19: Timer2
                    DCD     TIMER3_IRQHandler         ; 20: Timer3
                    DCD     UART0_IRQHandler          ; 21: UART0
                    DCD     UART1_IRQHandler          ; 22: UART1
                    DCD     UART2_IRQHandler          ; 23: UART2
                    DCD     UART3_IRQHandler          ; 24: UART3
                    DCD     PWM1_IRQHandler           ; 25: PWM1
                    DCD     I2C0_IRQHandler           ; 26: I2C0
                    DCD     I2C1_IRQHandler           ; 27: I2C1
                    DCD     I2C2_IRQHandler           ; 28: I2C2
                    DCD     SPI_IRQHandler            ; 29: SPI
                    DCD     SSP0_IRQHandler           ; 30: SSP0
                    DCD     SSP1_IRQHandler           ; 31: SSP1
                    DCD     PLL0_IRQHandler           ; 32: PLL0 Lock (Main PLL)
                    DCD     RTC_IRQHandler            ; 33: Real Time Clock
                    DCD     EINT0_IRQHandler          ; 34: External Interrupt 0
                    DCD     EINT1_IRQHandler          ; 35: External Interrupt 1
                    DCD     EINT2_IRQHandler          ; 36: External Interrupt 2
                    DCD     EINT3_IRQHandler          ; 37: External Interrupt 3
                    DCD     ADC_IRQHandler            ; 38: A/D Converter
                    DCD     BOD_IRQHandler            ; 39: Brown-Out Detect
                    DCD     USB_IRQHandler            ; 40: USB
                    DCD     CAN_IRQHandler            ; 41: CAN
                    DCD     DMA_IRQHandler            ; 42: General Purpose DMA
                    DCD     I2S_IRQHandler            ; 43: I2S
                    DCD     ENET_IRQHandler           ; 44: Ethernet
                    DCD     RIT_IRQHandler            ; 45: Repetitive Interrupt Timer
                    DCD     MCPWM_IRQHandler          ; 46: Motor Control PWM
                    DCD     QEI_IRQHandler            ; 47: Quadrature Encoder Interface
                    DCD     PLL1_IRQHandler           ; 48: PLL1 Lock (USB PLL)
                    DCD     USBActivity_IRQHandler    ; 49: USB Activity interrupt to wakeup
                    DCD     CANActivity_IRQHandler    ; 50: CAN Activity interrupt to wakeup
    
    
                    IF      :LNOT::DEF:NO_CRP
                    AREA    |.ARM.__at_0x02FC|, CODE, READONLY
    CRP_Key         DCD     0xFFFFFFFF
                    ENDIF
    
    
                    AREA    |.text|, CODE, READONLY
    
    
    ; Reset Handler
    
    Reset_Handler   PROC
                    EXPORT  Reset_Handler             [WEAK]
                    IMPORT  SystemInit
                    IMPORT  __main
                    LDR     R0, =SystemInit
                    BLX     R0
                    LDR     R0, =__main
                    BX      R0
                    ENDP
    
    
    ; Dummy Exception Handlers (infinite loops which can be modified)
    
    NMI_Handler     PROC
                    EXPORT  NMI_Handler               [WEAK]
                    B       .
                    ENDP
    HardFault_Handler\
                    PROC
                    EXPORT  HardFault_Handler         [WEAK]
                    B       .
                    ENDP
    MemManage_Handler\
                    PROC
                    EXPORT  MemManage_Handler         [WEAK]
                    B       .
                    ENDP
    BusFault_Handler\
                    PROC
                    EXPORT  BusFault_Handler          [WEAK]
                    B       .
                    ENDP
    UsageFault_Handler\
                    PROC
                    EXPORT  UsageFault_Handler        [WEAK]
                    B       .
                    ENDP
    SVC_Handler     PROC
                    EXPORT  SVC_Handler               [WEAK]
                    B       .
                    ENDP
    DebugMon_Handler\
                    PROC
                    EXPORT  DebugMon_Handler          [WEAK]
                    B       .
                    ENDP
    PendSV_Handler  PROC
                    EXPORT  PendSV_Handler            [WEAK]
                    B       .
                    ENDP
    SysTick_Handler PROC
                    EXPORT  SysTick_Handler           [WEAK]
                    B       .
                    ENDP
    
    Default_Handler PROC
    
                    EXPORT  WDT_IRQHandler            [WEAK]
                    EXPORT  TIMER0_IRQHandler         [WEAK]
                    EXPORT  TIMER1_IRQHandler         [WEAK]
                    EXPORT  TIMER2_IRQHandler         [WEAK]
                    EXPORT  TIMER3_IRQHandler         [WEAK]
                    EXPORT  UART0_IRQHandler          [WEAK]
                    EXPORT  UART1_IRQHandler          [WEAK]
                    EXPORT  UART2_IRQHandler          [WEAK]
                    EXPORT  UART3_IRQHandler          [WEAK]
                    EXPORT  PWM1_IRQHandler           [WEAK]
                    EXPORT  I2C0_IRQHandler           [WEAK]
                    EXPORT  I2C1_IRQHandler           [WEAK]
                    EXPORT  I2C2_IRQHandler           [WEAK]
                    EXPORT  SPI_IRQHandler            [WEAK]
                    EXPORT  SSP0_IRQHandler           [WEAK]
                    EXPORT  SSP1_IRQHandler           [WEAK]
                    EXPORT  PLL0_IRQHandler           [WEAK]
                    EXPORT  RTC_IRQHandler            [WEAK]
                    EXPORT  EINT0_IRQHandler          [WEAK]
                    EXPORT  EINT1_IRQHandler          [WEAK]
                    EXPORT  EINT2_IRQHandler          [WEAK]
                    EXPORT  EINT3_IRQHandler          [WEAK]
                    EXPORT  ADC_IRQHandler            [WEAK]
                    EXPORT  BOD_IRQHandler            [WEAK]
                    EXPORT  USB_IRQHandler            [WEAK]
                    EXPORT  CAN_IRQHandler            [WEAK]
                    EXPORT  DMA_IRQHandler            [WEAK]
                    EXPORT  I2S_IRQHandler            [WEAK]
                    EXPORT  ENET_IRQHandler           [WEAK]
                    EXPORT  RIT_IRQHandler            [WEAK]
                    EXPORT  MCPWM_IRQHandler          [WEAK]
                    EXPORT  QEI_IRQHandler            [WEAK]
                    EXPORT  PLL1_IRQHandler           [WEAK]
                    EXPORT  USBActivity_IRQHandler    [WEAK]
                    EXPORT  CANActivity_IRQHandler    [WEAK]
    
    WDT_IRQHandler
    TIMER0_IRQHandler
    TIMER1_IRQHandler
    TIMER2_IRQHandler
    TIMER3_IRQHandler
    UART0_IRQHandler
    UART1_IRQHandler
    UART2_IRQHandler
    UART3_IRQHandler
    PWM1_IRQHandler
    I2C0_IRQHandler
    I2C1_IRQHandler
    I2C2_IRQHandler
    SPI_IRQHandler
    SSP0_IRQHandler
    SSP1_IRQHandler
    PLL0_IRQHandler
    RTC_IRQHandler
    EINT0_IRQHandler
    EINT1_IRQHandler
    EINT2_IRQHandler
    EINT3_IRQHandler
    ADC_IRQHandler
    BOD_IRQHandler
    USB_IRQHandler
    CAN_IRQHandler
    DMA_IRQHandler
    I2S_IRQHandler
    ENET_IRQHandler
    RIT_IRQHandler
    MCPWM_IRQHandler
    QEI_IRQHandler
    PLL1_IRQHandler
    USBActivity_IRQHandler
    CANActivity_IRQHandler
    
                    B       .
    
                    ENDP
    
    
                    ALIGN
    
    
    ; User Initial Stack & Heap
    
                    IF      :DEF:__MICROLIB
    
                    EXPORT  __initial_sp
                    EXPORT  __heap_base
                    EXPORT  __heap_limit
    
                    ELSE
    
                    IMPORT  __use_two_region_memory
                    EXPORT  __user_initial_stackheap
    __user_initial_stackheap
    
                    LDR     R0, =  Heap_Mem
                    LDR     R1, =(Stack_Mem + Stack_Size)
                    LDR     R2, = (Heap_Mem +  Heap_Size)
                    LDR     R3, = Stack_Mem
                    BX      LR
    
                    ALIGN
    
                    ENDIF
    
    
                    END
    

    I played with the stack size according to:

    http://www.keil.com/pack/doc/mw/USB/html/usb_resource_requirements.html#usbd_res_req 

    I have a CDC (2 threads) and 4 threads totalling 6 * 512 = 3072 bytes but the behavior persists. 

    In 

    RTX_Conf_CM.c:

    ...
    #include "cmsis_os.h"
     
    
    /*----------------------------------------------------------------------------
     *      RTX User configuration part BEGIN
     *---------------------------------------------------------------------------*/
     
    //-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
    //
    // <h>Thread Configuration
    // =======================
    //
    //   <o>Number of concurrent running user threads <1-250>
    //   <i> Defines max. number of user threads that will run at the same time.
    //   <i> Default: 6; initially 5
    #ifndef OS_TASKCNT
     #define OS_TASKCNT     5
    #endif
     
    //   <o>Default Thread stack size [bytes] <64-4096:8><#/4>
    //   <i> Defines default stack size for threads with osThreadDef stacksz = 0
    //   <i> Default: 200
    #ifndef OS_STKSIZE
     #define OS_STKSIZE     50      // this stack size value is in words
    #endif
     
    //   <o>Main Thread stack size [bytes] <64-32768:8><#/4>
    //   <i> Defines stack size for main thread.
    //   <i> Default: 200
    #ifndef OS_MAINSTKSIZE
     #define OS_MAINSTKSIZE 512     // this stack size value is in words
    #endif
     
    //   <o>Number of threads with user-provided stack size <0-250>
    //   <i> Defines the number of threads with user-provided stack size.
    //   <i> Default: 0
    #ifndef OS_PRIVCNT
     #define OS_PRIVCNT     2
    #endif
     
    //   <o>Total stack size [bytes] for threads with user-provided stack size <0-1048576:8><#/4>
    //   <i> Defines the combined stack size for threads with user-provided stack size.
    //   <i> Default: 0
    #ifndef OS_PRIVSTKSIZE
     #define OS_PRIVSTKSIZE 512       // this stack size value is in words
    #endif
     
    //   <q>Stack overflow checking
    //   <i> Enable stack overflow checks at thread switch.
    //   <i> Enabling this option increases slightly the execution time of a thread switch.
    #ifndef OS_STKCHECK
     #define OS_STKCHECK    1
    #endif
     
    //   <q>Stack usage watermark
    //   <i> Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer.
    //   <i> Enabling this option increases significantly the execution time of osThreadCreate.
    #ifndef OS_STKINIT
    #define OS_STKINIT      0
    #endif
     
    //   <o>Processor mode for thread execution 
    //     <0=> Unprivileged mode 
    //     <1=> Privileged mode
    //   <i> Default: Privileged mode
    #ifndef OS_RUNPRIV
     #define OS_RUNPRIV     1
    #endif
     
    // </h>
     
    // <h>RTX Kernel Timer Tick Configuration
    // ======================================
    //   <q> Use Cortex-M SysTick timer as RTX Kernel Timer
    //   <i> Cortex-M processors provide in most cases a SysTick timer that can be used as 
    //   <i> as time-base for RTX.
    #ifndef OS_SYSTICK
     #define OS_SYSTICK     1
    #endif
    //
    //   <o>RTOS Kernel Timer input clock frequency [Hz] <1-1000000000>
    //   <i> Defines the input frequency of the RTOS Kernel Timer.  
    //   <i> When the Cortex-M SysTick timer is used, the input clock 
    //   <i> is on most systems identical with the core clock.
    #ifndef OS_CLOCK
     #define OS_CLOCK       100000000
    #endif
     
    //   <o>RTX Timer tick interval value [us] <1-1000000>
    //   <i> The RTX Timer tick interval value is used to calculate timeout values.
    //   <i> When the Cortex-M SysTick timer is enabled, the value also configures the SysTick timer.
    //   <i> Default: 1000  (1ms)
    #ifndef OS_TICK
     #define OS_TICK        1000
    #endif
     
    // </h>
     
    // <h>System Configuration
    // =======================
    //
    // <e>Round-Robin Thread switching
    // ===============================
    //
    // <i> Enables Round-Robin Thread switching.
    #ifndef OS_ROBIN
     #define OS_ROBIN       1
    #endif
     
    //   <o>Round-Robin Timeout [ticks] <1-1000>
    //   <i> Defines how long a thread will execute before a thread switch.
    //   <i> Default: 5
    #ifndef OS_ROBINTOUT
     #define OS_ROBINTOUT   5
    #endif
     
    // </e>
     
    // <e>User Timers
    // ==============
    //   <i> Enables user Timers
    #ifndef OS_TIMERS
     #define OS_TIMERS      1
    #endif
     
    //   <o>Timer Thread Priority
    //                        <1=> Low
    //     <2=> Below Normal  <3=> Normal  <4=> Above Normal
    //                        <5=> High
    //                        <6=> Realtime (highest)
    //   <i> Defines priority for Timer Thread
    //   <i> Default: High
    #ifndef OS_TIMERPRIO
     #define OS_TIMERPRIO   5
    #endif
     
    //   <o>Timer Thread stack size [bytes] <64-4096:8><#/4>
    //   <i> Defines stack size for Timer thread.
    //   <i> Default: 200
    #ifndef OS_TIMERSTKSZ
     #define OS_TIMERSTKSZ  50     // this stack size value is in words
    #endif
     
    //   <o>Timer Callback Queue size <1-32>
    //   <i> Number of concurrent active timer callback functions.
    //   <i> Default: 4
    #ifndef OS_TIMERCBQS
     #define OS_TIMERCBQS   4
    #endif
     
    // </e>
     
    //   <o>ISR FIFO Queue size<4=>   4 entries  <8=>   8 entries
    //                         <12=> 12 entries  <16=> 16 entries
    //                         <24=> 24 entries  <32=> 32 entries
    //                         <48=> 48 entries  <64=> 64 entries
    //                         <96=> 96 entries
    //   <i> ISR functions store requests to this buffer,
    //   <i> when they are called from the interrupt handler.
    //   <i> Default: 16 entries
    #ifndef OS_FIFOSZ
     #define OS_FIFOSZ      16
    #endif
     
    // </h>
     
    //------------- <<< end of configuration section >>> -----------------------
     
    // Standard library system mutexes
    // ===============================
    //  Define max. number system mutexes that are used to protect 
    //  the arm standard runtime library. For microlib they are not used.
    #ifndef OS_MUTEXCNT
     #define OS_MUTEXCNT    8
    #endif
    
    ...

    5 is the max no. of threads, OS_STKSIZE is set to 50. I'm not exactly sure but do these conflict with the thread stack size?

    Do you happen to have any config files for USB + threaded apps lying around? 

Children
No data