Skip to content

Arm-Examples/Hello_World

Repository files navigation

Hello, World!

Simple "Hello World" example for Infineon XMC2Go development board. This example is configured to print Hello World once a second via semihosting to the Telnet console.

This application is generic and can be easily adapted to other target hardware. You can also swtich the underlying real-time operating system.

Other message output options can be configured as well (refer to Serial I/O via UART).

Quick Start

  1. Install Keil Studio for VS Code from the VS Code marketplace.

  2. Clone this Git repository into a VS Code workspace.

  3. The related tools and software packs are downloaded and installed. Review progress with View - Output - CMSIS Solution.

  4. In the CMSIS view, use the Action buttons to build, load and debug the example on the hardware.

  5. In the VS Code Panel, click on SERIAL MONITOR. Select the Monitor Mode "TCP" and set Host to localhost and Port to 4444. Observe the output:

    SEGGER J-Link GDB Server V9.10 - Terminal output channel
    Hello, World!
    Hello, World!
    Hello, World!
    ...

Change the Target Hardware

This application is a generic CMSIS example that will run on any target hardware. If you want to change to another development board/device, edit the following.

In the Hello.csolution.yml file, add the device's/board's CMSIS-Packs:

  packs:
    - pack: ARM::CMSIS
    - pack: Infineon::XMC1000_DFP # Change to the right CMSIS-Pack

Then, change the target-type:/- type to a new name and enter the correct device:/board: names:

  # List different hardware targets that are used to deploy the solution.
  target-types:
    - type: XMC1100-Q024x0064  # Change to a meaningful name
      target-set:
        - set:
          images:
            - project-context: Hello.Debug
          debugger:
            name: J-Link Server
            clock: 4000000
            protocol: swd
      device: XMC1100-Q024x0064  # Change to actual device
      board: XMC 2Go:V1          # Change to actual board

Exchange the RTOS

This example is using the CMSIS-RTOS v2 API with CMSIS-FreeRTOS as the underlying real-time operating system kernel. If you wish to change the kernel to Keil RTX5, do the following.

In the Hello.cproject.yml file, exchange:

    - component: CMSIS:RTOS2:FreeRTOS&Cortex-M
    - component: RTOS&FreeRTOS:Config&CMSIS RTOS2
    - component: RTOS&FreeRTOS:Core&Cortex-M
    - component: RTOS&FreeRTOS:Event Groups
    - component: RTOS&FreeRTOS:Timers
    - component: RTOS&FreeRTOS:Heap&Heap_4

with:

    - component: CMSIS:RTOS2:Keil RTX5&Source

In the same file, exchange the ARM::CMSIS-FreeRTOS pack with the ARM::CMSIS-RTX pack:

    - pack: ARM::CMSIS-RTX

Serial I/O via UART

While semihosting requires not hardware configuration and can be easily used for quick debugging, it is not recommended for production systems (due to intrusive and slow communication). A viable option is to use a UART (serial port) instead. The following explains how to use the on-chip UART which is available through the Segger J-Link debug adapter for printf output.

[!ATTENTION] The following is specific for the XMC2Go development board. If you have changed the target hardware, consult your board specific documentation to select the right software components and CMSIS-Packs.

Adding Software Components

To be able to redirect the output to the UART, you need to add the following software components in the Hello.cproject.yml file:

    - component: CMSIS-Compiler:CORE
    - component: CMSIS-Compiler:STDOUT:Custom
    - component: CMSIS Driver:USART
    - component: Device:RTE_Device
    - component: Device:XMClib:GPIO
    - component: Device:XMClib:SCU
    - component: Device:XMClib:UART

Also, add the ARM::CMSIS-Compiler pack to the list of packs: in the same file:

    - pack: ARM::CMSIS-Compiler

Adding User Code

In the CMSIS view, click on the + sign next to Application and select Add From Component Code Template:

Add code template

Then, select CMSIS-Compiler:STDOUT:Custom which adds a stdout_user.c file to the Application group. Add this code in the file:

#include "retarget_stdout.h"
#include "Driver_USART.h"

#include <stdint.h>

extern ARM_DRIVER_USART Driver_USART0;

static ARM_DRIVER_USART * const stdout_usart = &Driver_USART0;
static uint8_t stdout_usart_initialized;

#ifndef STDOUT_USART_BAUDRATE
#define STDOUT_USART_BAUDRATE 115200U
#endif

static int stdout_usart_ensure_initialized (void) {
  int32_t status;

  if (stdout_usart_initialized != 0U) {
    return 0;
  }

  status = stdout_usart->Initialize(NULL);
  if (status != ARM_DRIVER_OK) {
    return -1;
  }

  status = stdout_usart->PowerControl(ARM_POWER_FULL);
  if (status != ARM_DRIVER_OK) {
    return -1;
  }

  status = stdout_usart->Control(
    ARM_USART_MODE_ASYNCHRONOUS |
    ARM_USART_DATA_BITS_8       |
    ARM_USART_PARITY_NONE       |
    ARM_USART_STOP_BITS_1       |
    ARM_USART_FLOW_CONTROL_NONE,
    STDOUT_USART_BAUDRATE
  );
  if (status != ARM_DRIVER_OK) {
    return -1;
  }

  status = stdout_usart->Control(ARM_USART_CONTROL_TX, 1U);
  if (status != ARM_DRIVER_OK) {
    return -1;
  }

  stdout_usart_initialized = 1U;
  return 0;
}

/**
  Put a character to the stdout

  \param[in]   ch  Character to output
  \return          The character written, or -1 on write error.
*/
int stdout_putchar (int ch) {
  uint8_t c;

  if (stdout_usart_ensure_initialized() != 0) {
    return -1;
  }

  /* If caller prints bare '\n', emit CRLF on the wire. */
  if ((uint8_t)ch == (uint8_t)'\n') {
    (void)stdout_putchar('\r');
  }

  /* Serialize by waiting for any previous send to complete. */
  while (stdout_usart->GetStatus().tx_busy != 0U) {
  }

  c = (uint8_t)ch;
  if (stdout_usart->Send(&c, 1U) != ARM_DRIVER_OK) {
    return -1;
  }

  while (stdout_usart->GetStatus().tx_busy != 0U) {
  }

  return ch;
}

Device Configuration

The UART that is connected to the Segger J-Link uses the the ports P2.1 and P2.2 on the device. You need to configure this in the RTE_Device.h file.

  • In the CMSIS view, expand Device_RTE_Device and click on the RTE_Device.h file. This file is annotated for Configuration Wizard view which can be enabled by pressing the Open configuration wozard view button at the top right corner.
  • In this view, enable UART0 and set the UART0_TX_Pin to P2_1 and the UART0_RX_Pin to P2_2.
  • Save the file.

Build and Run

If you now build the application and run it on the target, you need to change the SERIAL MONITOR to the following:

  • Monitor Mode: Serial
  • Port: the Segger J-Link
  • Baud rate: 115200

Press Start Monitoring to view the printf massages.

More Examples

Similar examples which are pre-configured for the UART output are available on GitHub:

About

Simple "Hello, World!" example to get you started.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published