NXP provides a software driver library for their Kinetis ARM Cortex-M0 and M4 devices, the ‘Kinetis SDK’, available from http://www.nxp.com/ksdk. The below link provides information about how download a KSDK package, how to install KSKD v2.0 project wizard in Kinetis Design Studio (KDS), and how to create a KSDK v2.0 project. Using Kinetis Design Studio v3.x with Kinetis SDK v2.0 NOTE: Before you continue with this document, it is important to download and install KSDK v2.0. The purpose of this document is to provide information that enables developers to start their first application using FreeRTOS and KSDK v2.0. Creating a new FreeRTOS with KSDK V2.0 application. The following steps show how to create a new FreeRTOS project in KDS using KSDK v2.0. 1. Open Kinetis Design Studio. 2. Go to 'File' menu and click on File->New->Kinetis SDK 2.x Project 3. Select a project name and the Kinetis SDK folder then click 'Next' 4. Select the processor or board to be used, in addition it is important to include all SDK drivers and add FreeRTOS to the project and click 'Finish' 5. In the project created you can see the following folder structure: 6. The main.c file is a template for main module created by new Kinetis SDK 2.0 Project Wizard, this contains a task responsible of printing "Hello world." message. 7. If you want to build and debug this example uncomment the next lines: #include "fsl_debug_console.h" and PRINTF("Hello world.\r\n"); 8. Build and debug. Developing the first FreeRTOS with KSDK V2.0 application. This section describes the creation of a simple application that blinks LEDs on the TWR-K64F120M board. After a new project is created, in the main function the following routines are called in order to initialize the board hardware: BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); By default only the UART0 is initialized in order to use it as debug console. Also in main it is created a task (hello_task) using xTaskCreate () function. xTaskCreate () creates a new task and adds it to the list of tasks that are ready to run; it contains the following parameters: pvTaskCode. Pointer to the task entry function. Tasks must be implemented to never return. pcName. A descriptive name for the task. This is mainly used to ease debugging. Max length defined by configMAX_TASK_NAME_LEN. usStackDepth. The size of the task stack specified as the number of variables the stack can hold - not the number of bytes. For example, if the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes will be allocated for stack storage. The stack depth multiplied by the stack width must not exceed the maximum value that can be contained in a variable of type size_t. pvParameters. Pointer that will be used as the parameter for the task being created. uxPriority. The priority at which the task should run. pvCreatedTask. Used to pass back a handle by which the created task can be referenced. Writing the application. The TWR-K64F120M contains 4 LED's connected to GPIO signals (optionally isolated using jumpers): — Green LED (D5) to PTE6 — Yellow LED (D6) to PTE7 — Orange LED (D7) to PTE8 — Blue LED (D9) to PTE9 For this example it is used the TWR-K64F120M board, however if you are using the FRDM-K64F the RGB LED is connected through GPIO signals: — RED to PTB22 — BLUE to PTB21 — GREEN to PTE26 To initialize the GPIO, enable the port clock, define a pin configuration, either input or output, in the pin_mux.c file, as is described in the below steps: Open the pin_mux.c file. 2. Enable the port clock. CLOCK_EnableClock(kCLOCK_PortE); 3. Configure these pins as GPIO signals. PORT_SetPinMux(PORTE, 6u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 7u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 8u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 9u, kPORT_MuxAsGpio); Then, in main function create 5 tasks, one to initialize the GPIO driver and the other to blink the LEDs. You can find the complete code at the end of this document. /* Create RTOS task */ xTaskCreate(init_task, "Init_task", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_blue, "Task_blue", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_orange, "Task_orange", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_yellow, "Task_yellow", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_green, "Task_green", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); Write the code of each task. 1. init_task function. In this function are initialized the GPIO pins as output using the gpio_pin_config_t structure then it is called the GPIO_PinInit() function for each GPIO pins. The GPIO_PinInit() parameters are: base. GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) pin. GPIO port pin number. config. GPIO pin configuration pointer. Finally call vTaskSuspend(), this function suspend the task. When a task is suspended, it will never get back to execution unless it is explicitly set in Ready state by another task. The code for init_task function is: gpio_pin_config_t ledB_config = { kGPIO_DigitalOutput, 0, }; gpio_pin_config_t ledO_config = { kGPIO_DigitalOutput, 0, }; gpio_pin_config_t ledG_config = { kGPIO_DigitalOutput, 0, }; gpio_pin_config_t ledY_config = { kGPIO_DigitalOutput, 0, }; /* Init output LED GPIO. */ GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PIN, &ledB_config); GPIO_PinInit(BOARD_LED_ORANGE_GPIO, BOARD_LED_ORANGE_GPIO_PIN, &ledO_config); GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, &ledG_config); GPIO_PinInit(BOARD_LED_YELLOW_GPIO, BOARD_LED_YELLOW_GPIO_PIN, &ledY_config); vTaskSuspend(NULL); 2. task_blue, task_orange, task_yellow, task green functions. It is necessary to write the code of each task. Each task uses LED_XXX_TOGGLE() and vTaskDelay (), to toggle a LED, this should be in a infinite loop. Below is the code for the task_blue function: while (1) { /* Toggle LED BLUE */ LED_BLUE_TOGGLE(); vTaskDelay( 500 ); } Finally build and debug the project. Enjoy! Complete Code main.c #include <string.h> #include "board.h" #include "pin_mux.h" #include "clock_config.h" #include "fsl_debug_console.h" /* FreeRTOS kernel includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "timers.h" /* Task priorities. */ #define task_PRIORITY (configMAX_PRIORITIES - 1) static void init_task(void *pvParameters) { /* Init output LED GPIO. */ gpio_pin_config_t ledB_config = { kGPIO_DigitalOutput, 0, }; gpio_pin_config_t ledO_config = { kGPIO_DigitalOutput, 0, }; gpio_pin_config_t ledG_config = { kGPIO_DigitalOutput, 0, }; gpio_pin_config_t ledY_config = { kGPIO_DigitalOutput, 0, }; /* Init output LED GPIO. */ GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PIN, &ledB_config); GPIO_PinInit(BOARD_LED_ORANGE_GPIO, BOARD_LED_ORANGE_GPIO_PIN, &ledO_config); GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, &ledG_config); GPIO_PinInit(BOARD_LED_YELLOW_GPIO, BOARD_LED_YELLOW_GPIO_PIN, &ledY_config); vTaskSuspend(NULL); } static void task_blue(void *pvParameters) { while (1) { /* Toggle LED BLUE */ LED_BLUE_TOGGLE(); vTaskDelay( 500 ); } } static void task_orange(void *pvParameters) { while (1) { /* Toggle LED ORANGE */ LED_ORANGE_TOGGLE(); vTaskDelay( 500 ); } } static void task_yellow(void *pvParameters) { while (1) { /* Toggle LED YELLOW */ LED_YELLOW_TOGGLE(); vTaskDelay( 500 ); } } static void task_green(void *pvParameters) { while (1) { /* Toggle LED GREEN */ LED_GREEN_TOGGLE(); vTaskDelay( 500 ); } } int main(void) { /* Init board hardware. */ BOARD_InitPins(); // This function initializes the pins used in this example BOARD_BootClockRUN(); BOARD_InitDebugConsole(); /* Create RTOS task */ xTaskCreate(init_task, "Init_task", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_blue, "Task_blue", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_orange, "Task_orange", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_yellow, "Task_yellow", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_green, "Task_green", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); vTaskStartScheduler(); for(;;) { /* Infinite loop to avoid leaving the main function */ __asm("NOP"); /* something to use as a breakpoint stop while looping */ } } Complete Code pin_mux.c #include "fsl_device_registers.h" #include "fsl_port.h" #include "pin_mux.h" /******************************************************************************* * Code ******************************************************************************/ /*! * @brief Initialize all pins used in this example * * @param disablePortClockAfterInit disable port clock after pin * initialization or not. */ void BOARD_InitPins(void) { /* Ungate the port clock */ CLOCK_EnableClock(kCLOCK_PortC); CLOCK_EnableClock(kCLOCK_PortE); /* Affects PORTC_PCR3 register */ PORT_SetPinMux(PORTC, 3u, kPORT_MuxAlt3); /* Affects PORTC_PCR4 register */ PORT_SetPinMux(PORTC, 4u, kPORT_MuxAlt3); PORT_SetPinMux(PORTE, 6u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 7u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 8u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 9u, kPORT_MuxAsGpio); }
View full article