Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - ricardoheleno

Pages: [1]
1
Many thanks Mark!

I'm stumbled with your post back to TI. I think I would never be able to solve such a problem...
The warning raises no problem for me :)

I will try to progressively solve the other issues you've mentioned in the .doc file.

I'll let know about my progress.

Thank you!

Regards,
Ricardo


2
Mark,

I don't really know much about memory architecture, but if I understood, You need to know the end of the .bss to define the beginning of your heap right?
(my guess is that you are managing dynamic memory allocation with your own routines and you can't find the heap start pointer)..

At page 110 of ARM Optimizing C/C++ Compiler v4.7 User's Guide :
http://focus.ti.com/lit/ug/spnu151f/spnu151f.pdf

it says that:
Quote
    – For EABI only, the .bss section reserves space for uninitialized global and static variables.
     – The .stack section reserves memory for the C/C++ software stack.
    – The .sysmem section reserves space for dynamic memory allocation. The reserved space is used
        by dynamic memory allocation routines, such as malloc, calloc, realloc, or new.
If a C/C++ program
        does not use these functions, the compiler does not create the .sysmem section.


The assembler creates the default sections .text, .bss, and .data. The C/C++ compiler, however, does not
use the .data section. You can instruct the compiler to create additional sections by using the
CODE_SECTION and DATA_SECTION pragmas (see Section 5.9.2 and Section 5.9.5).



meaning that .sysmem should contain the reference to heap start address..


possible work around:

          Considering the malloc, calloc, realloc issue (my guess is that you don't really use this functions on your code because of fragmentation issues), you could use a dummy malloc  some where in the code to force the compiler to create the .sysmem section, and then free the memory. unfortunately this option will increase the rom code size :S


even tough  --heap_size=size option is used, the compiler will not create create the .sysmem section unless the malloc() routines are used... cehck this thread:
http://e2e.ti.com/support/development_tools/compiler/f/343/p/56922/202947.aspx#202947

(CCS4 Heap size can be set under Project->Properties->C/C++ Build->Linker->Basic Options, under --heap_size, as well as in the linker *.cmd file)


When .sysmem section is created, it will have the pointer to the beginning of the heap, just as well as the variable _sys_memory will have:
http://e2e.ti.com/support/development_tools/compiler/f/343/p/57581/204672.aspx#204672



the access to _sys_memory values can be tricky as stated here:
http://e2e.ti.com/support/development_tools/compiler/f/343/p/56922/202947.aspx#202947

and should be done this way:
Quote

You have to be a little tricky to access these values in C code.  An unadorned identifier in C code refers to the contents of an object, but in the linker command file, it represents the address of an object.

When the linker creates a symbol that really represents an address, such as __STACK_END, if you just declare it as a non-pointer in C code, you get an object which lives at the end of the stack; simply using this symbol unadorned will give you a garbage value.  The address of this object is equal to the value the linker assigned to __STACK_END, so most likely you will always want to take the address of it:

extern unsigned char _STACK_END; /* Probably contains garbage. */

#define STACK_END_ADDRESS  (&_STACK_END)

When the linker creates a symbol that is just a plain number and not an address, such as __STACK_SIZE, there is no C-accessible object, but you still need to take the address of the linker-generated symbol, and you'll also need to cast it to an integer type:

extern unsigned char _STACK_SIZE; /* Fake object; no storage for this is allocated anywhere.  Its type does not matter. */

#define STACK_SIZE ((unsigned)&_STACK_SIZE)
with this said, I think

unfortunately I can test this assumptions because I still have code composer installed :(



hope it helps,

regards,
Ricardo
 

  


3
You will probably like to look at a startup code from one code example for the board EK-LM3S8962 given with stellarisware... it also contains inline assemby instructions

file:
startup_css.c

Code: [Select]
//*****************************************************************************
//
// startup_ccs.c - Startup code for use with TI's Code Composer Studio.
//
// Copyright (c) 2009-2011 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 6852 of the EK-LM3S8962 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;

//*****************************************************************************
//
// External declarations for the interrupt handlers used by the application.
//
//*****************************************************************************
extern void lwIPEthernetIntHandler(void);
extern void SysTickHandler(void);

//*****************************************************************************
//
// 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
    FaultISR,                               // The hard fault handler
    IntDefaultHandler,                      // The MPU fault handler
    IntDefaultHandler,                      // The bus fault handler
    IntDefaultHandler,                      // The usage fault handler
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    IntDefaultHandler,                      // SVCall handler
    IntDefaultHandler,                      // Debug monitor handler
    0,                                      // Reserved
    IntDefaultHandler,                      // The PendSV handler
    SysTickHandler,                         // The SysTick handler
    IntDefaultHandler,                      // GPIO Port A
    IntDefaultHandler,                      // GPIO Port B
    IntDefaultHandler,                      // GPIO Port C
    IntDefaultHandler,                      // GPIO Port D
    IntDefaultHandler,                      // GPIO Port E
    IntDefaultHandler,                      // UART0 Rx and Tx
    IntDefaultHandler,                      // UART1 Rx and Tx
    IntDefaultHandler,                      // SSI0 Rx and Tx
    IntDefaultHandler,                      // I2C0 Master and Slave
    IntDefaultHandler,                      // PWM Fault
    IntDefaultHandler,                      // PWM Generator 0
    IntDefaultHandler,                      // PWM Generator 1
    IntDefaultHandler,                      // PWM Generator 2
    IntDefaultHandler,                      // Quadrature Encoder 0
    IntDefaultHandler,                      // ADC Sequence 0
    IntDefaultHandler,                      // ADC Sequence 1
    IntDefaultHandler,                      // ADC Sequence 2
    IntDefaultHandler,                      // ADC Sequence 3
    IntDefaultHandler,                      // Watchdog timer
    IntDefaultHandler,                      // Timer 0 subtimer A
    IntDefaultHandler,                      // Timer 0 subtimer B
    IntDefaultHandler,                      // Timer 1 subtimer A
    IntDefaultHandler,                      // Timer 1 subtimer B
    IntDefaultHandler,                      // Timer 2 subtimer A
    IntDefaultHandler,                      // Timer 2 subtimer B
    IntDefaultHandler,                      // Analog Comparator 0
    IntDefaultHandler,                      // Analog Comparator 1
    IntDefaultHandler,                      // Analog Comparator 2
    IntDefaultHandler,                      // System Control (PLL, OSC, BO)
    IntDefaultHandler,                      // FLASH Control
    IntDefaultHandler,                      // GPIO Port F
    IntDefaultHandler,                      // GPIO Port G
    IntDefaultHandler,                      // GPIO Port H
    IntDefaultHandler,                      // UART2 Rx and Tx
    IntDefaultHandler,                      // SSI1 Rx and Tx
    IntDefaultHandler,                      // Timer 3 subtimer A
    IntDefaultHandler,                      // Timer 3 subtimer B
    IntDefaultHandler,                      // I2C1 Master and Slave
    IntDefaultHandler,                      // Quadrature Encoder 1
    IntDefaultHandler,                      // CAN0
    IntDefaultHandler,                      // CAN1
    IntDefaultHandler,                      // CAN2
    lwIPEthernetIntHandler,                 // Ethernet
    IntDefaultHandler                       // Hibernate
};

//*****************************************************************************
//
// 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.
    //
    __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)
    {
    }
}

I've read somewhere that
extern void _c_int00(void);   is intrinsics for      void main(void);

And I think you can probably edit ResetISR(void) to make a call to your external start routine, or even replace the Reset Handler in the interrupt vector for your start routine.




some code using Predefined Macro Names for Cross compiler definitions of interrupt service routine
part of the code from a code composer example.
I also found that Code Composer always predefines the macro __TI_COMPILER_VERSION__

Code: [Select]
#ifdef __GNUC__

#define portSET_INTERRUPT_MASK() \
__asm volatile \
( \
" mov r0, %0 \n" \
" msr basepri, r0 \n" \
::"i"(portSYSCALL_INTERRUPT_PRIORITY):"r0" \
)

#elif defined(__ARMCC_VERSION)

extern void portSET_INTERRUPT_MASK(void);

#elif defined(__IAR_SYSTEMS_ICC__)

#define portSET_INTERRUPT_MASK() \
__asm \
( \
" mov r0, #191 \n" \
" msr basepri, r0 \n" \
)

#else

#error Unknown compiler!

#endif



I hope it helps ..

regards,
Ricardo

4
Hi Mark,

I've found a post at TI forum that might be interesting...
http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/p/72596/357765.asp

Double checked in chapter 5.8 at page 88 from ARM Optimizing C/C++ Compiler:
http://focus.ti.com/lit/ug/spnu151f/spnu151f.pdf

Quote

5.8 The asm Statement

      The C/C++ compiler can embed assembly language instructions or directives directly into the assembly
  language output of the compiler. This capability is an extension to the C/C++ language—the asm
  statement. The asm (or __asm) statement provides access to hardware features that C/C++ cannot
  provide. The asm statement is syntactically like a call to a function named asm, with one string constant
  argument:

                   asm(" assembler text ");

      The compiler copies the argument string directly into your output file. The assembler text must be
  enclosed in double quotes. All the usual character string escape codes retain their definitions. For
  example, you can insert a .byte directive that contains quotes as follows:

                   asm("STR: .byte \"abc\"");

      The inserted code must be a legal assembly language statement. Like all assembly language statements,
  the line of code inside the quotes must begin with a label, a blank, a tab, or a comment (asterisk or
  semicolon). The compiler performs no checking on the string; if there is an error, the assembler detects it.
  For more information about the assembly language statements, see the ARM Assembly Language Tools
  User's Guide.

      The asm statements do not follow the syntactic restrictions of normal C/C++ statements. Each can appear
  as a statement or a declaration, even outside of blocks. This is useful for inserting directives at the very
  beginning of a compiled module.

      Use the alternate statement __asm("assembler text") if you are writing code for strict ANSI/ISO C mode
  (using the --strict_ansi option).



looks like you have to put a space character before the assembler instruction. you can only omit the space when using a label.

your code:

        __asm("cpsid   i");
        __asm("cpsie   i");
        __asm("wfi");

should work if you change to this:

        asm(" cpsid   i");
        asm(" cpsie   i");
        asm(" wfi");

the  __asm("")  should work to but I don't how to implement the --strict_ansi option. (probably on the command line)

you will probably like looking at the code:
Quote
Quoted from PaulT @ http://e2e.ti.com/support/development_tools/compiler/f/343/p/60654/217174.aspx#217174


Header File

Code: [Select]
#ifndef PORTMACRO_H
#define PORTMACRO_H

#ifdef __cplusplus
extern "C" {
#endif

#define portSET0()                        \
    __asm volatile                                        \
    (                                                    \
        "    mov r0, #(5 << 5)                        \n"    \
        "    msr basepri, r0                            \n" \
        :::"r0"                                            \
    )

#define portSET1()                        \
    __asm volatile                                        \
    (                                                    \
        "    mov r0, #(5 << 5)                        \n"    \
        "    msr basepri, r0                            \n" \
        ::"i"(interruptMask):"r0"                                            \
    )

#define portSET2()                        \
    __asm volatile                                        \
    (                                                    \
        "    mov r0, %0                                \n"    \
        "    msr basepri, r0                            \n" \
        ::"i"(interruptMask):"r0"                                            \
    )

#define portSET3()                        \
    __asm volatile                                        \
    (                                                    \
        "    mov r0,  #(5 << 5)                        \n"    \
        "    msr basepri, r0                            \n" \
        ::"i"(interruptMask):"r0"                                            \
    )

#define portSET4()                        \
    __asm volatile                                        \
    (                                                    \
        "    mov r0,  #[mask]                        \n"    \
        "    msr basepri, r0                            \n" \
        ::[mask]"i"(interruptMask):"r0"                    \
    )

#ifdef __cplusplus
}
#endif

#endif /* PORTMACRO_H */


and the C File

Code: [Select]
#include "portmacro.h"

void foo()
{
    int interruptMask = (5 << 5);
    portSET0();
    portSET1();
    portSET2();
    portSET3();
    portSET4();
}


The command line is

Code: [Select]
E:/Program Files/Texas Instruments/ccsv4/tools/compiler/tms470/bin/cl470" -mv7M3 -g -O2 --gcc --define=ccs --define=PART_LM3S6432 --include_path="E:/Program Files/Texas Instruments/ccsv4/tools/compiler/tms470/include" --include_path="E:/Projects/CCS4/LuminaryMicro/include" --diag_warning=225 -me --gen_func_subsections --abi=eabi --code_state=16 -k --ual --preproc_with_compile --preproc_dependency="source/port.pp" --obj_directory="source"  "../source/port.c"

The compiler fails on the line portSET4().

Generated asm output

Code: [Select]
   .dwpsn    file "../source/port.c",line 6,column 2,is_stmt
    mov r0, #(5 << 5)                      
    msr basepri, r0                          
    .dwpsn    file "../source/port.c",line 7,column 2,is_stmt
    mov r0, #(5 << 5)                      
    msr basepri, r0                          
    .dwpsn    file "../source/port.c",line 8,column 2,is_stmt
    mov r0, %0                              
    msr basepri, r0                          
    .dwpsn    file "../source/port.c",line 9,column 2,is_stmt
    mov r0,  #(5 << 5)                      
    msr basepri, r0                          
    .dwpsn    file "../source/port.c",line 11,column 1,is_stmt
$C$DW$2    .dwtag  DW_TAG_TI_branch
    .dwattr $C$DW$2, DW_AT_low_pc(0x00)
    .dwattr $C$DW$2, DW_AT_TI_return
        BX        LR
If portSET4() is commented out then it fails in the assembler. "port.asm", ERROR!   at line 60: [E0200] Bad term in expression
        mov r0, %0                              

Generated asm output is identical.

 

Regards,

Paul



______________
By the way,
this morning my laptop hard drive crashed and burned after a chekdisk procedure... (never thought that chkdsk routine could actually kill an HD.)

the only good thing is that finally found that regular backups pays off! only lost a half week of work :)
Meaning with all this that I'm out of the game by now, (waiting for warranty). Meanwhile I will try to get my old computer running CCSv4 with my 704MB of RAM (I hope the 1GB requirement to be a myth). I will also keep track of your developments.

Once again, thank you for your help!

Regards,
Ricardo

5
Thank you Mark,

I'm still "fighting" with Code Composer Project definitions :(

About the comparative,
Well, for example, when buying EKS-LM38962 (89$ us dolares) we get a full Code Composer version to use with that board.. The EKS-LM3S8962 is also a standard 20 pin JTAG for that works at least with Stellaris CortexM3 MCU'S.
There are also other stellaris evaluation and development kits offering Code Composer Studio..

I'm new to Code Composer, and until now I simply hate it. In fact I'm only using it because it's free with my EKS-LM3S8962.

My preference goes to Keil MDK and IAR.

About the uTasker,
I'm still trying to compile it under CCS.. I will let you know about my progress!

thank you for your help,
Ricardo

6
I'm a new on uTasker. I'm trying to use TI code composer CCSv4 to compile uTasker 1.4

I'm basically building the demo application for LM3Sxxxx. For now I'm still trying to find wich routine is the main routine for the project...

Have anyone ever tried to accomplish this?

Thank you all for your attention,
Ricardo



Pages: [1]