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.

CCS/TM4C123GH6PM: Need help creating and calling user defined functions

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL

Tool/software: Code Composer Studio

Hi,

I could use some assistance with the following issue.

Development environment:

IDE: CCS Version: 7.1.0.00016 running on Windows 7 Professional with SP1, including all current updates.

Driver Library: Stellaris® Peripheral Driver Library: Software Driver Model API’s

Target: LaunchPad EK-TM4C123GXL (processor on-board TM4C123GHPMI

I can’t find the “I” version listed in the CCSv7 Properties > CCS General > Device field, I selected the TM4C123GHPM. It works, my code builds, loads and runs as expected.

I have CCSv7 configured and am able to write C code to successfully use the PWM and GPIO peripherals.

However, I am not able to create and call user defined functions.  I had been able to do this easily when using uVision MDK-Lite.

I have searched TI’s documentation and the e2e Forum unsuccessfully for guidance on these issues, and have tried numerous “experiments” unsuccessfully which were similar to those I had used with uVision. 

My questions:

1)      How do I create, in C, user defined functions using CCSv7 Software Driver Model API’s?

2)      How do I call, in C, the user defined functions I create using CCSv7 Software Driver Model API’s?

3)      Some very simple example code to go with the answers would be of great help.

    • For example:Example code showing how to create and call a functions to turn on and off enabled GPIO ports used to drive LED’s.
    • I understand how to use the GPIO and PWM API functions.

Thanks, Bob

  • Can you show us an example that does not work? There is no issue with user functions that I can see:

    This should work fine:

    void myFunc();
    
    main()
    {
        myFunc();
    }
    
    void myFunc()
    {
       // I am too lazy to look up the actual function
       MAP_GPIO_Call_to_toggle_IO(Port, Pin);
    }

  • Hi Keith,
    I just got home from a day of travel. I'll give this a try tomorrow and let you know how it goes; I may have more questions!
    Thanks for your prompt response, Bob
  • Hi Keith,

    When I add my function code in main(), I get errors.  And, of course the program will not compile and run.

    When I comment my function code prototype, call and declaration out, as shown in the project inserted below, it compiles and runs.

    I can't find my error(s), hopefully you can.

    The following code is a simplified version of my full code, but it results in the same error as in the full project code when the user defined function snippets are included.

    /* Project name: Function define and Call Test-1
     *
     * Written by: Bob Samuel
     * Date: June 23, 2017
     *
     */
    
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    
    #include "driverlib/sysctl.c"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.c"
    #include "driverlib/gpio.h"
    #include "driverlib/debug.h"
    #include "driverlib/pin_map.h"
    
    
        /*------------------  User defined function prototype  ------------------------*/
    
    //void LED_Blink(); // This function blinks the on-board RGB LED
    
    
        /*------------------  SysCtlDelay math (SYSCLK)  ---------------------------*/
             //Subroutine to delay in units of seconds
             //SYSCLK set to 20 MHz = 1/20,000,000 = 0.00000005 Seconds (50ns) = 3 clock cycles * 50ns = 150ns per clock cycle
             //1 Second = 1,000,000,000ns / 150ns =~ 6666667 clock cycle: .5 second = 6666667/2 = 3333333: .25 second = 3333333/2 = 1666667: .125 second = 1666667/2 = 833334
    
    
    unsigned long Delay1 = 833334; // Number of Clock Cycles-1 (SysCtlDelay)
    unsigned long Delay2 = 833334;	// Number of Clock Cycles-2 (SysCtlDelay)
    
    
    int main()
    {
        /*------------------  Set-up System Clock (SYSCLK)  ------------------------*/
    
        SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ ); // SYSCLK set to 20 MHz (referred to as "ticks")
    
        /*------------------  Enable peripheral ports: GPIOF  -----------------------*/
    
        SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF ); // Enable GPIO: Port F
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF));  //This function determines if a particular peripheral is ready to be accessed.
    
    	 //Sets GPIO pins as OUTPUT
    
         GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    	
         /*------------------  User defined function call  ---------------------------*/
    /*
         {
        	 void LED_Blink(); // Function call
         }
    
    */
         /*------------------  User defined function declaration  ---------------------*/
    
    //void LED_Blink() // Function declaration
    
         /*------------------  Code to blink the on-board RGB LED  ---------------------*/
    	{
        int a;
    
        	for(a=0;a<2;a=a+1)
    
        	{
    
              GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, GPIO_PIN_1); // On board tri-color LED - Red
              SysCtlDelay(Delay1);
              GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, 0);
              SysCtlDelay(Delay2);
    
              GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, GPIO_PIN_2); // On board tri-color LED - Blue
              SysCtlDelay(Delay1);
              GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, 0);
              SysCtlDelay(Delay2);
    
              GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, GPIO_PIN_3); // On board tri-color LED - Green
              SysCtlDelay(Delay1);
              GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, 0);
              SysCtlDelay(Delay2);
        	}
    
    	}
    
    return(0);
    }
    
    

  • Robert Samuel said:
    When I add my function code in main(), I get errors.

    I see any obvious problem with the code. Can you post the complete output from the CCS Console when you get compile errors?

    Robert Samuel said:
    I can’t find the “I” version listed in the CCSv7 Properties > CCS General > Device field, I selected the TM4C123GHPM.

    This final "I" character in the TM4C123GHPMI part number indicates the temperate range of the part is –40°C to +85°C.

    The CCS device names don't include the temperate range component of the part numbers, so you selected the correct device in CCS.

  • Hi Chester,

     

    Thanks for the info about the temperature designation. I must have missed it on the data sheet.

     

    I have inserted the Console and Problems output and code below. The code is a simplified version of a larger project, but the results are the same when I define and call a function.

     

    Also, if you have any additional suggestions that would improve my code please feel free to make them.

     

    Thanks for your help.

     

    Bob


    /* Project name: Function define and Call Test-1 * * Written by: Bob Samuel * Date: June 23, 2017 * */ #include <stdint.h> #include <stdbool.h> #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "driverlib/sysctl.c" #include "driverlib/sysctl.h" #include "driverlib/gpio.c" #include "driverlib/gpio.h" #include "driverlib/debug.h" #include "driverlib/pin_map.h" /*------------------ User defined function ---------------------------*/ void LED_Blink(); // This function blinks the on-board RGB LED /*------------------ SysCtlDelay math (SYSCLK) ---------------------------*/ //Subroutine to delay in units of seconds //SYSCLK set to 20 MHz = 1/20,000,000 = 0.00000005 Seconds (50ns) = 3 clock cycles * 50ns = 150ns per clock cycle //1 Second = 1,000,000,000ns / 150ns =~ 6666667 clock cycle: .5 second = 6666667/2 = 3333333: .25 second = 3333333/2 = 1666667: .125 second = 1666667/2 = 833334 unsigned long Delay1 = 833334; // Number of Clock Cycles-1 (SysCtlDelay) unsigned long Delay2 = 833334; // Number of Clock Cycles-2 (SysCtlDelay) int main() { /*------------------ Set-up System Clock (SYSCLK) ------------------------*/ SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ ); // SYSCLK set to 20 MHz (referred to as "ticks") /*------------------ Enable peripheral ports: GPIOF -----------------------*/ SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF ); // Enable GPIO: Port F while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)); //This function determines if a particular peripheral is ready to be accessed. //Sets GPIO pins as OUTPUT GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); /*------------------ User defined function call ---------------------------*/ { void LED_Blink(); // Function call } /*------------------ User defined function declaration ---------------------*/ void LED_Blink() // Function declaration /*------------------ Code to blink the on-board RGB LED ---------------------*/ { int a; for(a=0;a<2;a=a+1) { GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, GPIO_PIN_1); // On board tri-color LED - Red SysCtlDelay(Delay1); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, 0); SysCtlDelay(Delay2); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, GPIO_PIN_2); // On board tri-color LED - Blue SysCtlDelay(Delay1); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, 0); SysCtlDelay(Delay2); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, GPIO_PIN_3); // On board tri-color LED - Green SysCtlDelay(Delay1); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, 0); SysCtlDelay(Delay2); } } return(0); }

  • Robert Samuel said:
    I have inserted the Console and Problems output and code below

    The LED_Blink function definition is nested inside the main function which is not valid ANSI C.

    The definition of the LED_Blink function should be moved outside of the main function.

  • Hi Chester,

    Good news and bad news!

    Good: I made the changes as you described, and the code did compile; no errors, the code builds.

    Bad: The target does not load and/or the code.

    Below are the Console and Debug window captures; they change with each successive click of the green Resume button as follows.

    Note that the Debug window information changes. There also appears to be a break-point being set.

    Also, I have included a copy of the modified code at the end of this post.

    I really appreciate your help.

    Thanks again, Bob 

    1. Before clicking Green resume button:

    2. After FIRST click of  Green resume button:

    3. After SECOND click of  Green resume button:

    4. The newly modified code:

    /* Project name: Function define and Call Test-1
     *
     * Written by: Bob Samuel
     * Date: June 23, 2017
     *
     */
    
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    
    #include "driverlib/sysctl.c"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.c"
    #include "driverlib/gpio.h"
    #include "driverlib/debug.h"
    #include "driverlib/pin_map.h"
    
    
        /*------------------  User defined function prototype  ---------------------------*/
    
    	void LED_Blink(); // This function blinks the on-board RGB LED
    
    
        /*------------------  SysCtlDelay math (SYSCLK)  ---------------------------*/
             //Subroutine to delay in units of seconds
             //SYSCLK set to 20 MHz = 1/20,000,000 = 0.00000005 Seconds (50ns) = 3 clock cycles * 50ns = 150ns per clock cycle
             //1 Second = 1,000,000,000ns / 150ns =~ 6666667 clock cycle: .5 second = 6666667/2 = 3333333: .25 second = 3333333/2 = 1666667: .125 second = 1666667/2 = 833334
    
    unsigned long Delay1 = 833334; // Number of Clock Cycles-1 (SysCtlDelay)
    unsigned long Delay2 = 833334;	// Number of Clock Cycles-2 (SysCtlDelay)
    
    
    /*------------------  User defined function declaration  ---------------------*/
    
    	 void LED_Blink() // Function declaration
    
    /*------------------  Code to blink the on-board RGB LED  ---------------------*/
    {
    int a;
    
    	for(a=0;a<1;a=a+1)
    
    	{
    
         GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, GPIO_PIN_1); // On board tri-color LED - Red
         SysCtlDelay(Delay1);
         GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, 0);
         SysCtlDelay(Delay2);
    
         GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, GPIO_PIN_2); // On board tri-color LED - Blue
         SysCtlDelay(Delay1);
         GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, 0);
         SysCtlDelay(Delay2);
    
         GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, GPIO_PIN_3); // On board tri-color LED - Green
         SysCtlDelay(Delay1);
         GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, 0);
         SysCtlDelay(Delay2);
    	}
    
    }
    
    
    int main(void)
    {
        /*------------------  Set-up System Clock (SYSCLK)  ------------------------*/
    
        SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ ); // SYSCLK set to 20 MHz (referred to as "ticks")
    
        /*------------------  Enable peripheral ports: GPIOF  -----------------------*/
    
        SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF ); // Enable GPIO: Port F
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF));  //This function determines if a particular peripheral is ready to be accessed.
    
    	 //Sets GPIO pins as OUTPUT
    
         GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    	
         /*------------------  User defined function call  ---------------------------*/
    
         {
        	 void LED_Blink(); // Function call
         }
    return(0);
    }
    
    
    

  • Robert Samuel said:
    /*------------------ User defined function call ---------------------------*/ { void LED_Blink(); // Function call }

    The main() function only makes a single call to the LED_Blink() function and then the main function returns. When the main function returns the program will end in an infinite loop in the loader_exit() function which explains your observed behaviour when using the Resume button in the debugger.

    An embedded program should usually run for ever. For your example of a blinking LED program the main function should call the LED_Blink function continuously in a loop. E.g. try:

         /*------------------  User defined function call  ---------------------------*/
    
         while (1)
         {
        	 void LED_Blink(); // Function call
         }

  • Hi Chester,

    I’ve tried placing the declaration both before and after int main(void), the code builds but does not load, or loads incorrectly. Whichever the case, the code does not run in the target, and I get similar Resume button responses to the ones I mentioned in my last post; sniped images are inserted below.

    I found that using while(1) causes the code to give the a warning and appears to stop at return(0): “#-112D statement is unreachable”.

    If I comment out while(1) no warning is given at return(0), no errors or warnings are shown anywhere in the code, however the code builds but does not load, or loads incorrectly thus the code does not run in the target.

    If I delete the deceleration and the call, and place the LED blinking code back into main the code runs in the target.

    A copy of the code is inserted below

    I’m stumped!

    Thanks for your help.

    Before clicking Resume: (By the way the Console no longer retains the complete text sequence.)

    After clicking Resume:

    /* Project name: Function define and Call Test-1
     *
     * Written by: Bob Samuel
     * Date: June 23, 2017
     *
     */
    
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    
    #include "driverlib/sysctl.c"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.c"
    #include "driverlib/gpio.h"
    #include "driverlib/debug.h"
    #include "driverlib/pin_map.h"
    
    
        /*------------------  User defined function prototype  ---------------------------*/
    
    	void LED_Blink(); // This function blinks the on-board RGB LED
    
    
        /*------------------  SysCtlDelay math (SYSCLK)  ---------------------------*/
             //Subroutine to delay in units of seconds
             //SYSCLK set to 20 MHz = 1/20,000,000 = 0.00000005 Seconds (50ns) = 3 clock cycles * 50ns = 150ns per clock cycle
             //1 Second = 1,000,000,000ns / 150ns =~ 6666667 clock cycle: .5 second = 6666667/2 = 3333333: .25 second = 3333333/2 = 1666667: .125 second = 1666667/2 = 833334
    
    unsigned long Delay1 = 833334; // Number of Clock Cycles-1 (SysCtlDelay)
    unsigned long Delay2 = 833334;	// Number of Clock Cycles-2 (SysCtlDelay)
    
    /*------------------  User defined function declaration  ---------------------*/
    
    	void LED_Blink() // Function declaration
    
     	/*------------------  Code to blink the on-board RGB LED  ---------------------*/
    {
    	int a;
    
    		for(a=0;a<3;a=a+1)
    
    			{
    
    			GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, GPIO_PIN_1); // On board tri-color LED - Red
    			SysCtlDelay(Delay1);
    			GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, 0);
    			SysCtlDelay(Delay2);
    
    			GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, GPIO_PIN_2); // On board tri-color LED - Blue
    			SysCtlDelay(Delay1);
    			GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, 0);
    			SysCtlDelay(Delay2);
    
    			GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, GPIO_PIN_3); // On board tri-color LED - Green
    			SysCtlDelay(Delay1);
    			GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, 0);
    			SysCtlDelay(Delay2);
    
    			}
    }
    
    
    int main(void)
    {
    
    	/*------------------  Set-up System Clock (SYSCLK)  ------------------------*/
    
    	SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ ); // SYSCLK set to 20 MHz (referred to as "ticks")
    
    
    
    	/*------------------  Enable peripheral ports: GPIOF  -----------------------*/
    
    	SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF ); // Enable GPIO: Port F
    	while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF));  //This function determines if a particular peripheral is ready to be accessed.
    
    	 //Sets GPIO pins as OUTPUT
    
    	 GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    
    
    	/*------------------  User defined function call  ---------------------------*/
    
    		 while(1)
    		 {
    	    	void LED_Blink(); // Function call
    		 }
    
    
     return(0); // THE WARNING MESSAGE NOTED ABOVE IS IN THE CODE'S MARGIN AND NOT CAPTURED
    }
    

  • Robert Samuel said:
    A copy of the code is inserted below

    I have run that code on a EK-TM4C123GXL and can repeat the problem of the LED not flashing when compiled with the TI ARM compiler.

    Realised that the problem is that in the function call the void qualifier is causing the compiler to eliminate the function call:

        /*------------------  User defined function call  ---------------------------*/
    
         while(1)
         {
             void LED_Blink(); // Function call
         }

    To fix this, change the code to remove the void qualifier (I missed this when I suggested my previous code change to add the while loop). I.e. change the function call to:

        /*------------------  User defined function call  ---------------------------*/
    
         while(1)
         {
             LED_Blink(); // Function call
         }

    With that change the program blinked the tri-color LED on the launchpad.

    Robert Samuel said:
    I found that using while(1) causes the code to give the a warning and appears to stop at return(0): “#-112D statement is unreachable”.

    That is valid compiler warning, since with the while(1) loop the program won't return from the main function. The return(0); can be removed to prevent the warning.

  • Hi Chester,

    Thank you for your time, help and prompt responses. It’s working now!

    As the result of your time and knowledge I have learned quite a number of important basic lessons about creating and using functions in C, and how the while(1) statement operates in main.

    Thanks again for your help.

    Bob