USB CDC and SCI: Side-by-Side with the Freedom Board

In “A Shell for the Freedom KL25Z Board” I have presented an application which implements FreeRTOS, LED’s and a shell using the UART on the KL25Z over OpenSDA. So why not adding native USB CDC to the mix? Using both the USB and CDC with the same shell?

So what I have added is that the shell runs on both the SCI (over OpenSDA) and USB CDC (with the KL25Z). For this, the FSL USB CDC software stack is now part of the project:

Shell Project with USB CDC

Shell Project with USB CDC

All what is needed is to pass the right I/O handle to the routines so I can read/write from SCI and USB. For this I have defined my own other SHELL_stdio on top of the one inside the FSShell:

/* additional I/O handlers for USB. SCI is handled by the Shell */
static FSSH1_ConstStdIOType SHELL_stdio =
{
  (FSSH1_StdIO_In_FctType)SHELL_CDCReadChar, /* stdin */
  (FSSH1_StdIO_OutErr_FctType)SHELL_CDCSendChar, /* stdout */
  (FSSH1_StdIO_OutErr_FctType)SHELL_CDCSendChar, /* stderr */
  SHELL_CDCKeyPressed /* if input is not empty */
};

The I/O handlers are implement as below to use the USB CDC functions:

static void SHELL_CDCReadChar(unsigned char *c) {
  if (CDC1_GetChar(c)!=ERR_OK) {
    /* failed to receive character: return a zero character */
    *c = '\0';
  }
}

static void SHELL_CDCSendChar(unsigned char ch) {
  (void)CDC1_SendChar(ch);
}

static bool SHELL_CDCKeyPressed(void) {
  return (CDC1_GetCharsInRxBuf()!=0);
}

FSSH1_ConstStdIOType *SHELL_GetStdio(void) {
  return &SHELL_stdio;
}

In these I/O handlers I could easily implement an echo function, or logging things to an SD-card. Possibilities are unlimited.

To write a string to the SCI, I simply use the standard handler from the shell:

FSSH1_SendStr((unsigned char*)"Hello world to SCI!\r\n", FSSH1_GetStdio()->stdOut);

To use the USB CDC communication channel instead, I simply use the I/O handler defined above:

FSSH1_SendStr((unsigned char*)"Hello world to USB CDC!\r\n", SHELL_GetStdio()->stdOut);

Inside the Shell task, I have added the code to use the shell in parallel with USB CDC:

static portTASK_FUNCTION(ShellTask, pvParameters) {
  unsigned char cmd_buf[32];
  unsigned char cmd_buf_cdc[32];
  static unsigned char usb_tx_buf[USB1_DATA_BUFF_SIZE];

  (void)pvParameters; /* not used */
  cmd_buf[0] = '\0';
  cmd_buf_cdc[0] = '\0';
  FSSH1_Init();
  (void)FSSH1_ParseCommand((const unsigned char*)FSSH1_CMD_HELP, FSSH1_GetStdio(), ParseCommand);
  for(;;) {
    (void)FSSH1_ReadAndParseLine(cmd_buf, sizeof(cmd_buf), FSSH1_GetStdio(), ParseCommand /* local cmd parser */);
    (void)CDC1_App_Task(usb_tx_buf, sizeof(usb_tx_buf)); /* Call the USB application task */
    (void)FSSH1_ReadAndParseLine(cmd_buf_cdc, sizeof(cmd_buf_cdc), &SHELL_stdio, ParseCommand /* local cmd parser */);
    FRTOS1_vTaskDelay(50/portTICK_RATE_MS);
    LED2_Neg();
  }
}

That way I can talk to my application side-by-side both through SCI/OpenSDA CDC and native USB CDC:

Side by side shell with COM36 on OpenSDA and on COM22 with native KL25Z USB CDC

Side by side shell with COM36 on OpenSDA and on COM22 with native KL25Z USB CDC

The updated project and sources is available from this link.

Happy Siding 🙂

14 thoughts on “USB CDC and SCI: Side-by-Side with the Freedom Board

  1. Hello Erich,
    I thought I knew well FreeRTOS but obviously I was wrong
    I tried to add the Task4 with the same characteristics of Task3 (with the aim of making later a task dedicated to the native usb) but the program does not run
    In the following, the changes I’ve made
    After the creation of Task3

    if (FRTOS1_xTaskCreate(
    Task3, /* pointer to the task */
    (signed portCHAR *)”Task3″, /* task name for kernel awareness debugging */
    configMINIMAL_STACK_SIZE, /* task stack size */
    (void*)NULL, /* optional task startup argument */
    tskIDLE_PRIORITY, /* initial priority */
    (xTaskHandle*)NULL /* optional task handle to create */
    ) != pdPASS) {
    /*lint -e527 */
    for(;;){}; /* error! probably out of memory */
    /*lint +e527 */
    }
    I added the Task4
    if (FRTOS1_xTaskCreate(
    Task4, /* pointer to the task */
    (signed portCHAR *)”Task4″, /* task name for kernel awareness debugging */
    configMINIMAL_STACK_SIZE, /* task stack size */
    (void*)NULL, /* optional task startup argument */
    tskIDLE_PRIORITY, /* initial priority */
    (xTaskHandle*)NULL /* optional task handle to create */
    ) != pdPASS) {
    /*lint -e527 */
    for(;;){}; /* error! probably out of memory */
    /*lint +e527 */
    }
    FRTOS1_vTaskStartScheduler();
    and in the same file
    static portTASK_FUNCTION(Task4, pvParameters) {
    (void)pvParameters; /* parameter not used */
    for(;;) {
    LED1_Neg();
    FRTOS1_vTaskDelay(5000/portTICK_RATE_MS);
    }
    }
    I thought it might be a problem of stack and I tried to increase
    In this case another quirk that shows my lack of knowledge of FreeRTOS is as follows
    I changed in FreeRTOSConfig.h
    #define configTOTAL_HEAP_SIZE ((size_t)(8192+128))
    and with the same code I had the error message
    Freedom_Shell.elf section `._user_heap_stack’ will not fit in region `m_data’
    region `m_data’ overflowed by 512 bytes
    What do you think?
    Carlo

    Like

    • Hi Carlo,
      in MCU10.3beta, the linker file has a memory split at the address 0x2000’0000. This means that the 16 KByte RAM are in two blocks: one 12 KByte and one 4 KByte. That memory split exists for Cortex-M (Kinetis K family), but does not apply to the Cortex-M0+ (Kinetis-L family). I suggest that you a) disable linker file generation in Processor Expert and b) declare a single memory block in the linker file. That way you have 16 KByte of RAM available in a single block, and you can have a FreeRTOS heap beyond 12 KByte.

      Like

  2. Hi, Erich!
    First of all, congratulations for the great work you do here!
    I’ve been using the FSL_USB_Stack/FSL_USB_CDC_Device with the Freedom board succesfully for a while, but now, when I try to add it to a new project, CW throws me an “Error during adding component FSL_USB_Stack”… The old projects opens and compile right, just importing it brings the error… any thougs?
    Thank you!

    Like

    • Hi Celso,
      thanks :-).
      As for your problem, not sure what this could be. Maybe you could send me a screenshot or the project to my email address noted at the end of the About page?

      Like

  3. Updating…
    Looking at the “problems” view, there is some of the following error:

    FAILURE: at line 2: Command %set cannot be used in this type of script. It can be used in component script only. (file: Beans\FSL_USB_Stack\FSL_USB_Stack.chg)

    Thanks!

    Like

    • Hi Celso, ah, ok, now I know what this is. Simply close the project (Project > Close) and then re-open it again. Not sure what this is, but look like a bug in Processor Expert. I think I have submitted this one already, but I will follow up. But for now, after you have set the right USB Init component and set the processor type, you can close and re-open the project to get rid of the problem.

      Like

      • Hi, Erich! I’ve already tried that, but no deal… That occured before (back when I was still on 10.3 beta), but that time the bean was added to the project, and them when building it throws that errors… closing/reopening the project always did the drill… but now it doesn’t even import the bean… I’ll send you a screenshot of the error as soon as the (third) reinstallation of CW get done (tried just reinstall, install on another folder, now reinstalling after cleaning windows registry)… Thanks!

        Like

  4. Pingback: Freedom Robot solves the Maze | MCU on Eclipse

  5. Pingback: Debug External Processors with USBDM and Freedom Board | MCU on Eclipse

  6. Pingback: Hacking the Heating System for Cooling – Geothermal Drilling with extra Benefits | MCU on Eclipse

  7. Pingback: New P&E OpenSDA Firmware v114 | MCU on Eclipse

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.