1
\$\begingroup\$

I am using CCS 5.x on Windows 7. The TI board is LM4f232. The following code performs A to D conversion of the on-board accelerometer. I am trying to use printf to see my variable values, but it is failing.

    #include "utils/ustdlib.h"
    #include "inc/hw_types.h"
    #include "driverlib/adc.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/gpio.h"
    #include "stdio.h"

    #ifdef DEBUG
    void
    __error__(char *pcFilename, unsigned long ulLine)
    {
    }
    #endif

    int main(void)
    {

    unsigned long ulADC0_Value[3]; //holds ADC output values

    //Configure the system clock to 50MHz
    SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    //GPIO Configuration 
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6);

    //ADC Configuration starts here 
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
    ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH8);
    ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH9);
    ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH21 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, 0);

    //ADC measurement is made here 
    while(1)
    {
        //trigger ADC measurement 
       ADCProcessorTrigger(ADC0_BASE, 0);

       //wait for the conversion to complete 
       while(!ADCIntStatus(ADC0_BASE, 0, false))


       {


       }

            //transfer data from FIFO to local variable 
       ADCSequenceDataGet(ADC0_BASE, 0, ulADC0_Value);

       // this line creates problem 
        printf("values %l", ulADC0_Value[0]); 

            //Delay between samples 
        SysCtlDelay(SysCtlClockGet() / 12);
   }


   }

The following is the content of my startup_ccs.c file (some part is clipped)

//*****************************************************************************
//
// startup_ccs.c - Startup code for use with TI's Code Composer Studio.
//
// Copyright (c) 2011-2012 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 9107 of the EK-LM4F232 Firmware Package.
//
//*****************************************************************************

//*****************************************************************************
//
// Forward declaration of the default fault handlers.
//
//*****************************************************************************
void ResetISR(void);
static void NmiSR(void);
static void FaultISR(void);
static void IntDefaultHandler(void);

//*****************************************************************************
//
// External declaration for the reset handler that is to be called when the
// processor is started
//
//*****************************************************************************
extern void _c_int00(void);

//*****************************************************************************
//
// Linker variable that marks the top of the stack.
//
//*****************************************************************************
extern unsigned long __STACK_TOP;

//*****************************************************************************
//
// The vector table.  Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000 or at the start of
// the program if located at a start address other than 0.
//
//*****************************************************************************
#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
void (* const g_pfnVectors[])(void) =
{
    (void (*)(void))((unsigned long)&__STACK_TOP),
                                            // The initial stack pointer
    ResetISR,                               // The reset handler
    NmiSR,                                  // The NMI handler
     IntDefaultHandler,                      // FPU
    IntDefaultHandler,                      // PECI 0
    IntDefaultHandler,                      // LPC 0
    IntDefaultHandler,                      // GPIO Port R
    IntDefaultHandler,                      // GPIO Port S
    IntDefaultHandler,                      // PWM 1 Generator 0
    IntDefaultHandler,                      // PWM 1 Generator 1
    IntDefaultHandler,                      // PWM 1 Generator 2
    IntDefaultHandler,                      // PWM 1 Generator 3
    IntDefaultHandler                       // PWM 1 Fault
};

//*****************************************************************************
//
// This is the code that gets called when the processor first starts execution
// following a reset event.  Only the absolutely necessary set is performed,
// after which the application supplied entry() routine is called.  Any fancy
// actions (such as making decisions based on the reset cause register, and
// resetting the bits in that register) are left solely in the hands of the
// application.
//
//*****************************************************************************
void
ResetISR(void)
{
    //
    // Jump to the CCS C initialization routine.  This will enable the
    // floating-point unit as well, so that does not need to be done here.
    //
    __asm("    .global _c_int00\n"
          "    b.w     _c_int00");
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a NMI.  This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
//*****************************************************************************
static void
NmiSR(void)
{
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a fault
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
FaultISR(void)
{
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives an unexpected
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
IntDefaultHandler(void)
{
    //
    // Go into an infinite loop.
    //
    while(1)
    {
    }
}

Whenever I put printf:

 printf("values %lu", ulADC0_Value[0]);  

and even

printf("values %l", ulADC0_Value[0]); 

shown in my first code after ADCSequenceDataGet(), the program stops, and the control goes to the following section in startup_css.c:

/*****************************************************************************
//
// This is the code that gets called when the processor receives a fault
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
FaultISR(void)
{
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
}

I followed the instructions given here on printf support and increased the heap size to 500 bytes, but still I am not able to print the variable values on console. What is wrong with my code?

\$\endgroup\$
8
  • \$\begingroup\$ Your heap is 500 bytes but what about your stack? How big is that? Try using #include <stdio.h> instead of #include "stdio.h". Also try moving the call to SysCtlDelay above your printf. \$\endgroup\$ Mar 29, 2013 at 14:01
  • \$\begingroup\$ @embedded.kyle thanks for your suggestions and edits. Stack is by default 256 bytes, so I increased the stack to 512. Also moved SysCtlDelay above printf, but still same issue... \$\endgroup\$
    – gpuguy
    Mar 29, 2013 at 14:18
  • \$\begingroup\$ And the #include? The behavior is implementation defined but you may be pulling a different copy of stdio.h than the one you want. \$\endgroup\$ Mar 29, 2013 at 14:24
  • \$\begingroup\$ did that also, again the same problem. Under Expressions I get: ulADC0_Value unknown Error: identifier not found: ulADC0_Value. \$\endgroup\$
    – gpuguy
    Mar 29, 2013 at 14:32
  • \$\begingroup\$ What sort of debugging can you do? Have you been able to step inside the printf call and see what it attempts to do and where exactly the fault occurs? \$\endgroup\$
    – AngryEE
    Mar 29, 2013 at 15:30

1 Answer 1

2
\$\begingroup\$

I had the same problem. It took me 2 hours to find the solution.

--printf_support=minimal in the compile options is the root cause of some printf formats not working.

Change it to --printf_support=full and it will fix the problem.

It's explained on page 29 of MSP430 Optimizing C/C++ Compiler v21.6.0.LTS

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.