This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: Code Composer Studio
Hello,
I have a TMS320F28388D and docking station and attempting to blink an led using the FreeRTOS code here https://github.com/IvanZuy/freertos_c28x and modifying to suite my MCU. I am running into the error below and wondering if my assembler function definiton is correct as I beleive it is giving me issues. Can someone verify? The first picture is the function defintion in the .asm file and the other is the extern declaration in my port.c file.
portasm.asm(Another question, what does it meaning when "getSTF" is highlighted as a light blue color? I know the grey highlight signifies code that isn`t run):
port.c file:
Error I get:
I have also included the two files below:
//------------------------------------------------------------------------------------------------- // Author: Ivan Zaitsev, ivan.zaitsev@gmail.com // // This file follows the FreeRTOS distribution license. // // FreeRTOS is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License (version 2) as published by the // Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. // // *************************************************************************** // >>! NOTE: The modification to the GPL is included to allow you to !<< // >>! distribute a combined work that includes FreeRTOS without being !<< // >>! obliged to provide the source code for proprietary components !<< // >>! outside of the FreeRTOS kernel. !<< // *************************************************************************** // // FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. Full license text is available on the following // link: http://www.freertos.org/a00114.html //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- // Scheduler includes. //------------------------------------------------------------------------------------------------- #include "FreeRTOS.h" #include "task.h" //------------------------------------------------------------------------------------------------- // Implementation of functions defined in portable.h for the C28x port. //------------------------------------------------------------------------------------------------- // Constants required for hardware setup. #define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 ) #define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 ) #if defined(__TMS320C28XX_FPU32__) # define AUX_REGISTERS_TO_SAVE 19 // XAR + FPU registers # define XAR4_REGISTER_POSITION 6 // XAR4 position in AUX registers array # define STF_REGISTER_POSITION 10 // STF position in AUX registers array #else # define AUX_REGISTERS_TO_SAVE 9 // XAR registers only # define XAR4_REGISTER_POSITION 5 // XAR4 position in AUX registers array #endif extern uint32_t getSTF( void ); extern void vApplicationSetupTimerInterrupt( void ); // Each task maintains a count of the critical section nesting depth. Each // time a critical section is entered the count is incremented. Each time a // critical section is exited the count is decremented - with interrupts only // being re-enabled if the count is zero. // // ulCriticalNesting will get set to zero when the scheduler starts, but must // not be initialised to zero as this will cause problems during the startup // sequence. // ulCriticalNesting should be 32 bit value to keep stack alignment unchanged. volatile uint32_t ulCriticalNesting = portINITIAL_CRITICAL_NESTING; volatile uint16_t bYield = 0; volatile uint16_t bPreemptive = 0; //------------------------------------------------------------------------------------------------- // Initialise the stack of a task to look exactly as if // timer interrupt was executed. //------------------------------------------------------------------------------------------------- StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { uint16_t i; uint16_t base = 0; pxTopOfStack[base++] = 0x0080; // ST0. PSM = 0(No shift) pxTopOfStack[base++] = 0x0000; // T pxTopOfStack[base++] = 0x0000; // AL pxTopOfStack[base++] = 0x0000; // AH pxTopOfStack[base++] = 0xFFFF; // PL pxTopOfStack[base++] = 0xFFFF; // PH pxTopOfStack[base++] = 0xFFFF; // AR0 pxTopOfStack[base++] = 0xFFFF; // AR1 pxTopOfStack[base++] = 0x8A08; // ST1 pxTopOfStack[base++] = 0x0000; // DP pxTopOfStack[base++] = 0x0000; // IER pxTopOfStack[base++] = 0x0000; // DBGSTAT pxTopOfStack[base++] = ((uint32_t)pxCode) & 0xFFFFU; // PCL pxTopOfStack[base++] = ((uint32_t)pxCode >> 16) & 0x00FFU; // PCH pxTopOfStack[base++] = 0xAAAA; // Alignment pxTopOfStack[base++] = 0xBBBB; // Alignment // Fill the rest of the registers with dummy values. for(i = 0; i < (2 * AUX_REGISTERS_TO_SAVE); i++) { uint16_t low = 0x0000; uint16_t high = 0x0000; if(i == (2 * XAR4_REGISTER_POSITION)) { low = ((uint32_t)pvParameters) & 0xFFFFU; high = ((uint32_t)pvParameters >> 16) & 0xFFFFU; } #if defined(__TMS320C28XX_FPU32__) if(i == (2 * STF_REGISTER_POSITION)) { uint32_t stf = getSTF(); low = stf & 0xFFFFU; high = (stf >> 16) & 0xFFFFU; } #endif pxTopOfStack[base + i] = low; i++; pxTopOfStack[base + i] = high; } base += i; // Reserve place for ST1 which will be used in context switch // to set correct SPA bit ASAP. pxTopOfStack[base++] = 0x8A18; // ST1 with SPA bit set pxTopOfStack[base++] = 0x0000; // DP pxTopOfStack[base++] = 0x0000; // placeholder for 32 bit ulCriticalNesting pxTopOfStack[base++] = 0x0000; // Return a pointer to the top of the stack we have generated so this can // be stored in the task control block for the task. return pxTopOfStack + base; } //------------------------------------------------------------------------------------------------- void vPortEndScheduler( void ) { // It is unlikely that the TMS320 port will get stopped. // If required simply disable the tick interrupt here. } //------------------------------------------------------------------------------------------------- // See header file for description. //------------------------------------------------------------------------------------------------- BaseType_t xPortStartScheduler(void) { vApplicationSetupTimerInterrupt(); ulCriticalNesting = 0; #if(configUSE_PREEMPTION == 1) bPreemptive = 1; #else bPreemptive = 0; #endif portENABLE_INTERRUPTS(); portRESTORE_FIRST_CONTEXT(); // Should not get here! return pdFAIL; } //------------------------------------------------------------------------------------------------- void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); ulCriticalNesting++; } //------------------------------------------------------------------------------------------------- void vPortExitCritical( void ) { ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } }
main.c led code:
#include "f28x_project.h"//#include "F28x_Project.h" // Device Headerfile and Examples Include File #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #define DEVICE_GPIO_PIN_LED1 31 #define STACK_SIZE 256U #define RED 0xDEADBEAF #define BLUE 0xBAADF00D static StaticTask_t redTaskBuffer; static StackType_t redTaskStack[STACK_SIZE]; static StaticTask_t blueTaskBuffer; static StackType_t blueTaskStack[STACK_SIZE]; static StaticTask_t idleTaskBuffer; static StackType_t idleTaskStack[STACK_SIZE]; static SemaphoreHandle_t xSemaphore = NULL; static StaticSemaphore_t xSemaphoreBuffer; //------------------------------------------------------------------------------------------------- void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) { while(1); } //------------------------------------------------------------------------------------------------- static void blueLedToggle(void) { static uint32_t counter = 0; counter++; GPIO_WritePin(DEVICE_GPIO_PIN_LED1, counter & 1); } //------------------------------------------------------------------------------------------------- static void redLedToggle(void) { static uint32_t counter = 0; counter++; GPIO_WritePin(12, counter & 1); } //------------------------------------------------------------------------------------------------- static void ledToggle(uint32_t led) { if(RED == led) { redLedToggle(); } else if(BLUE == led) { blueLedToggle(); } } //------------------------------------------------------------------------------------------------- void vApplicationSetupTimerInterrupt( void ) { // Start the timer than activate timer interrupt to switch into first task. EALLOW; PieVectTable.TIMER2_INT = &portTICK_ISR; EDIS; ConfigCpuTimer(&CpuTimer2, configCPU_CLOCK_HZ / 1000000, // CPU clock in MHz 1000000 / configTICK_RATE_HZ); // Timer period in uS CpuTimer2Regs.TCR.all = 0x4000; // Enable interrupt and start timer IER |= M_INT14; } //------------------------------------------------------------------------------------------------- interrupt void timer1_ISR( void ) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken ); portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } //------------------------------------------------------------------------------------------------- static void setupTimer1( void ) { // Start the timer than activate timer interrupt to switch into first task. EALLOW; PieVectTable.TIMER1_INT = &timer1_ISR; EDIS; ConfigCpuTimer(&CpuTimer1, configCPU_CLOCK_HZ / 1000000, // CPU clock in MHz 100000); // Timer period in uS CpuTimer1Regs.TCR.all = 0x4000; // Enable interrupt and start timer IER |= M_INT13; } //------------------------------------------------------------------------------------------------- void LED_TaskRed(void * pvParameters) { for(;;) { if(xSemaphoreTake( xSemaphore, portMAX_DELAY ) == pdTRUE) { ledToggle((uint32_t)pvParameters); } } } //------------------------------------------------------------------------------------------------- void LED_TaskBlue(void * pvParameters) { for(;;) { ledToggle((uint32_t)pvParameters); vTaskDelay(250 / portTICK_PERIOD_MS); } } //------------------------------------------------------------------------------------------------- void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { *ppxIdleTaskTCBBuffer = &idleTaskBuffer; *ppxIdleTaskStackBuffer = idleTaskStack; *pulIdleTaskStackSize = STACK_SIZE; } //------------------------------------------------------------------------------------------------- void main(void) { // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the F2837xS_SysCtrl.c file. InitSysCtrl(); // Step 2. Initialize GPIO: // This example function is found in the F2837xS_Gpio.c file and // illustrates how to set the GPIO to it's default state. InitCpuTimers(); InitGpio(); GPIO_SetupPinMux(12, GPIO_MUX_CPU1, 0); GPIO_SetupPinMux(DEVICE_GPIO_PIN_LED1, GPIO_MUX_CPU1, 0); GPIO_SetupPinOptions(12, GPIO_OUTPUT, GPIO_PUSHPULL); GPIO_SetupPinOptions(DEVICE_GPIO_PIN_LED1, GPIO_OUTPUT, GPIO_PUSHPULL); GPIO_WritePin(12, 1); GPIO_WritePin(DEVICE_GPIO_PIN_LED1, 1); // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts DINT; // Initialize the PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the F2837xS_PieCtrl.c file. InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000; InitPieVectTable(); // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in F2837xS_DefaultIsr.c. // This function is found in F2837xS_PieVect.c. InitPieVectTable(); xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer ); setupTimer1(); // Enable global Interrupts and higher priority real-time debug events: EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // Create the task without using any dynamic memory allocation. xTaskCreateStatic(LED_TaskRed, // Function that implements the task. "Red LED task", // Text name for the task. STACK_SIZE, // Number of indexes in the xStack array. ( void * ) RED, // Parameter passed into the task. tskIDLE_PRIORITY + 2, // Priority at which the task is created. redTaskStack, // Array to use as the task's stack. &redTaskBuffer ); // Variable to hold the task's data structure. xTaskCreateStatic(LED_TaskBlue, // Function that implements the task. "Blue LED task", // Text name for the task. STACK_SIZE, // Number of indexes in the xStack array. ( void * ) BLUE, // Parameter passed into the task. tskIDLE_PRIORITY + 1, // Priority at which the task is created. blueTaskStack, // Array to use as the task's stack. &blueTaskBuffer ); // Variable to hold the task's data structure. vTaskStartScheduler(); }
Thanks,
John
If you remove the _ in _getSTF does the error go away? It looks like the FreeRTOS port was done before our compiler had EABI support, so there are probably a few things that need to be updated related to that to get it running on F2838x and other newer devices. There's a document that describes pretty thoroughly how to port code from COFF to EABI that should help:
https://software-dl.ti.com/ccs/esd/documents/C2000_c28x_migration_from_coff_to_eabi.html
Whitney
Yes the error goes away. I am now trying to establish ethernet communication and then using modbus. Can I be given support on how to accomplish this? Communication will be with an arduino
Hi John, thanks for your patience while I was out of the office. It looks like you've made some other threads on the Ethernet topic in the meantime, so I'll close this thread for now.
Whitney