USB Device CDC +FreeRTOS

The problem is the following
1 – The hw platform is the STM32F4 DiscoverY Board
2 – On this platform turns perfectly an example of FreeRTOS with Atollic  environment
3-  I found on Internet an excellent demo (see on Google “stm32f4-discovery-usb-cdc-example.zip”), that implements the USB CDC class on the same board an with the same Atollic enviroment
The demo is running perfectly and performs the following functions:
- It flashes an LED with an action taken by main.c
- Replicates on the Tx line of all is sent by Rx line(it is enough to open a serial connection to 115200 bit / s)
- If you press the USER button, a message is transmitted (the message is  “terve” which in Finnish means “hello”)
4 – I tried to combine the 2 demos with the objective to flash the LED with a task created with FreeRTOS, but did not succeed: the communication stops working when calling the first function of FreeRTOS
5-Someone tried to do the same thing with better success?
Thanks in advance for your support
Carlo De Bonis

USB Device CDC +FreeRTOS

I tried to combine the 2 demos
How? Taking the FreeRTOS demo and adding in the USB demo or taking the USB demo and adding in the FreeRTOS demo. How are you managing the interrupts on the USB, or is it just polling? I don’t know the USB code you are talking about so don’t know how it works, so don’t know what to suggest to get it working with FreeRTOS.
stops working when calling the first function of FreeRTOS
FreeRTOS has a lot of functions and I don’t know which one you are calling first.

USB Device CDC +FreeRTOS

Thank you for your prompt replay.
I followed both the ways and in the end I privileged the way to start with the cdc demo and insert into it the FreeRTOS. After initializing usb function and before calling the first function of FreeRTOS that creates a queue  I added a delay of more than 30 seconds and I verified that until the delay expires, the communication works fine- Here’s the code:
  / / init usb
USBD_Init (& USB_OTG_dev,
# ifdef USE_USB_OTG_HS
USB_OTG_HS_CORE_ID,
# else
USB_OTG_FS_CORE_ID,
# endif
& USR_desc,
& USBD_CDC_cb,
& USR_cb);
   Delay (600000000);
   / * Create a pipe for MEMS-> TIM4 data exchange * /
   xQueue xQueueCreate = (1, QUEUESIZE * sizeof (uint8_t));
   xTaskCreate (vLEDTask, (signed portCHAR *) “LED3”, configMINIMAL_STACK_SIZE, (void *) LEDS , tskIDLE_PRIORITY, & xLED_Tasks );
   / * Start the scheduler. * /
   vTaskStartScheduler ();

USB Device CDC +FreeRTOS

I will add an element
When iI call the FreeRTOS the debugger falls here (file STM32F4XX_IT.C)
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

USB Device CDC +FreeRTOS

Step through the xQueueCreate() function and see when the fault occurs. The parameters of xQueueCreate() do not look right. You are creating space for 1 item in the queue, and that one item has a size of QUEUESIZE * sizeof (uint8_t). Is that what you intended. Is the USB code using interrupts? I suspect that will be the problem. You have to set interrupt priorities correctly when you have the kernel running, but you are not even getting as far as getting the kernel running so the first thing to do is just step through the code to see what happens.

USB Device CDC +FreeRTOS

The program executes correctly:
a) xQueue=xQueueCreate(1,queueSIZE*sizeof(uint8_t));
b) xTaskCreate( vLEDTask, ( signed portCHAR * ) “LED3”, configMINIMAL_STACK_SIZE, (void *)LEDS,tskIDLE_PRIORITY, &xLED_Tasks );
  /* Start the scheduler. */
c)  vTaskStartScheduler();
The crash i when in  vTaskStartScheduler() is launched
/* Start the first task. */
vPortStartFirstTask();
that is
void vPortStartFirstTask( void )
{
__asm volatile(
” ldr r0, =0xE000ED08 n” /* Use the NVIC offset register to locate the stack. */
” ldr r0,  n”
” ldr r0,  n”
” msr msp, r0 n” /* Set the msp back to the start of the stack. */
” cpsie i n” /* Globally enable interrupts. */
” svc 0 n” /* System call to start first task. */
” nop n”
);
}
if you go to the next step the debugger falla herevoid HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

USB Device CDC +FreeRTOS

Does vPortStartFirstTask() complete (can you step into the svc call)?  Or is the crash in that function?  If the crash is in that function, on which line? Regards.

USB Device CDC +FreeRTOS

1- The breakpoint is in line 182 vPortStartFirstTask(); /*
* See header file for description.
*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR.  Interrupts are disabled
here already. */
prvSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */
uxCriticalNesting = 0; /* Start the first task. */
**vPortStartFirstTask();
**
/* Should not get here! */
return 0;
}
2- When I am in line 182 (wth Atollic Enviroment)  I press F5 (Step Into) and the debugger iumps to
void vPortStartFirstTask( void )
{
__asm volatile(
” ldr r0, =0xE000ED08 n” /* Use the NVIC offset register to locate the stack. */
” ldr r0,  n”
” ldr r0,  n”
” msr msp, r0 n” /* Set the msp back to the start of the stack. */
” cpsie i n” /* Globally enable interrupts. */
” svc 0 n” /* System call to start first task. */
” nop n”
);
}
3- After with F5 the debugger jumps to
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}
It is not possible to follow the assembler code

USB Device CDC +FreeRTOS

- Put a break point at the start of vPortStartFirstTask(). - Run the application until the break point is hit. - Open up a disassembly view (using menu Window->Show View->Other->Debug->Disassembly) - Set the debugger to single step instructions, rather than lines of C code (this can normally be done using a speed button that appears on the task bar when a debug session is in progress, the speed button has a little “i” on it). - Then you can step through the assembly instructions. I suspect you will find that you get down to svc 0, and then either that the svc handler just isn’t installed, or that you then go into the svc handler function and will then have to follow it from there. Regards.

USB Device CDC +FreeRTOS

I followed your instructions and
1- with “Instruction stepping mode” I reached
    08002838:   svc 0
2- the next step  was
          HardFault_Handler:
08001dcc:   push {r7}
08001dce:   add r7, sp, #0
77         }
08001dd0:   b.n 0x8001dd0 <HardFault_Handler+4>
86       {
3 The svc handler is installed in port.c
void vPortSVCHandler( void )
{
__asm volatile (
” ldr r3, pxCurrentTCBConst2 n” /* Restore the context. */
” ldr r1, n” /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
” ldr r0, n” /* The first item in pxCurrentTCB is the task top of stack. */
” ldmia r0!, {r4-r11} n” /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
” msr psp, r0 n” /* Restore the task stack pointer. */
” mov r0, #0 n”
” msr basepri, r0 n”
” orr r14, #0xd n”
” bx r14 n”
” n”
” .align 2 n”
“pxCurrentTCBConst2: .word pxCurrentTCB n”
);
}
4- in stm32f4xx_it.c in agreement with FreeRTOS  SVC_Handler,  PendSV_Handler,SysTick_Handler(are commented)
#if 0
void SVC_Handler(void)
{
}
#endif
#if 0
void PendSV_Handler(void)
{
}
#endif
#if 0
void SysTick_Handler(void)
{
}
#endif

USB Device CDC +FreeRTOS

For a better understanding I use the same project with a define FLAGRTOS that can have 3 values
0 for demo CDC            : all is ok (link with P.C. + LED blinking)
1 for demo FreeRTOS  : all is ok led blinking
2 for demo CDC+ a big delay + calls to FreeRTOS functions (with this define there is link with P.C. until FreeRTOS is not invoked)
/**
*****************************************************************************
**
**  File        : main.c
**
**  Abstract    : main function.
**
**  Functions   : main
**
**  Environment : Atollic TrueSTUDIO(R)
**                STMicroelectronics STM32F4xx Standard Peripherals Library
**
**  Distribution: The file is distributed “as is,” without any warranty
**                of any kind.
**
**  (C)Copyright Atollic AB.
**  You may use this file as-is or modify it according to the needs of your
**  project. Distribution of this file (unmodified or modified) is not
**  permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the
**  rights to distribute the assembled, compiled & linked contents of this
**  file as part of an application binary file, provided that it is built
**  using the Atollic TrueSTUDIO(R) toolchain.
**
**
*****************************************************************************
*/ /* Includes */
#include “stm32f4xx.h”
#include “usbd_cdc_core.h”
#include “usbd_cdc.h”
#include “usbd_usr.h”
#include “usbd_desc.h”
/* FreeRTOS includes */
#include “FreeRTOS.h” // automaticamente include FreeRTOSConfig.h
#include “task.h”
#include “semphr.h”
#define FLAGRTOS 2
#define queueSIZE 6
#define DELAY 125     /* msec */ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); /* Task functions declarations */
static void vLEDTask( void *pvParameters );
/* initial arguments for vLEDTask task (which LED and what is the delay) */
static const int LEDS = {{LED3,DELAY*1},
   {LED4,DELAY*2},
   {LED5,DELAY*3},
   {LED6,DELAY*4}}; /* semaphores, queues declarations */
xSemaphoreHandle xSemaphoreSW  = NULL;
xQueueHandle xQueue;
xTaskHandle xLED_Tasks; /* Private macro */
/* Private variables */
/* Private function prototypes */
void Delay(__IO uint32_t nTick);
/* Private functions */
__ALIGN_BEGIN USB_OTG_CORE_HANDLE    USB_OTG_dev __ALIGN_END ; /**
**===========================================================================
**
**  Abstract: main program
**
**===========================================================================
*/
uint16_t cdc_DataTx (uint8_t* Buf, uint32_t Len);
int main(void)
{
  int i = 0;   STM32F4_Discovery_LEDInit(LED3);
  STM32F4_Discovery_LEDInit(LED4);
  STM32F4_Discovery_LEDInit(LED5);
  STM32F4_Discovery_LEDInit(LED6);
  STM32F4_Discovery_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);   STM32F4_Discovery_LEDOn(LED3);
  Delay(0xFFFF);
#if FLAGRTOS==0 // CDC only
     //usb init
  USBD_Init(&USB_OTG_dev,
#ifdef USE_USB_OTG_HS
  USB_OTG_HS_CORE_ID,
#else
  USB_OTG_FS_CORE_ID,
#endif
  &USR_desc,
  &USBD_CDC_cb,
  &USR_cb);
  while (1)
  {
if (i++ == 0x100000)
    {
    STM32F4_Discovery_LEDToggle(LEDGREEN);
    i=0;
    }
  }
#endif
#if FLAGRTOS==1 // FreeRTOS only   xQueue=xQueueCreate(1,queueSIZE*sizeof(uint8_t));
  xTaskCreate( vLEDTask, ( signed portCHAR * ) “LED3”, configMINIMAL_STACK_SIZE, (void *)LEDS,tskIDLE_PRIORITY, &xLED_Tasks );
  /* Start the scheduler. */
  vTaskStartScheduler();
  /* Will only get here if there was not enough heap space to create the idle task. */
  return 0;
#endif
#if FLAGRTOS==2 // FreeRTOS after about 30 seconds
  //usb init
  USBD_Init(&USB_OTG_dev,
#ifdef USE_USB_OTG_HS
  USB_OTG_HS_CORE_ID,
#else
  USB_OTG_FS_CORE_ID,
#endif
  &USR_desc,
  &USBD_CDC_cb,
  &USR_cb);
  Delay(600000000);
  /* create a pipe for MEMS->TIM4 data exchange */
  xQueue=xQueueCreate(1,queueSIZE*sizeof(uint8_t));
  xTaskCreate( vLEDTask, ( signed portCHAR * ) “LED3”, configMINIMAL_STACK_SIZE, (void *)LEDS,tskIDLE_PRIORITY, &xLED_Tasks );
  /* Start the scheduler. */
  vTaskStartScheduler();
  /* Will only get here if there was not enough heap space to create the idle task. */
  return 0;
#endif } void vLEDTask( void *pvParameters )
{
    volatile int *LED;
    LED = (int *) pvParameters; for( ;; )
{
    STM32F4_Discovery_LEDToggle(LEDGREEN);
    vTaskDelay(10000);
}
} void Delay(__IO uint32_t nTick)
{
  for(; nTick != 0; nTick-);
}
/*—————————————*/ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask; /* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
function is called if a stack overflow is detected. */
for( ;; );
}
void vApplicationIdleHook( void )
{
volatile size_t xFreeStackSpace; /* This function is called on each cycle of the idle task.  In this case it
does nothing useful, other than report the amout of FreeRTOS heap that
remains unallocated. */
xFreeStackSpace = xPortGetFreeHeapSize(); if( xFreeStackSpace > 100 )
{
/* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */
}
}

USB Device CDC +FreeRTOS

I explained the problem in the previous replies.
Does anyone have any idea of the crash  when you call the Service Call?
Thanks

USB Device CDC +FreeRTOS

I don’t know that there is anything more to add.  Your previous post contained a lot of source code, but no new information.  I think we got as far as SVC 0 giving a hardware fault, which would seem to mean that the NVIC had some strange configuration  - probably configured by your USB code.  The enabling of interrupts immediately prior to SVC 0 should prevent a hard fault so I have no explanation and only the suggestion to look and see what your USB code is doing to the NVIC.  I am not going to try and remotely debug somebody else’s USB driver. Regards.