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?
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?