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.

printf, scanf with DSP bios and F28335 control card.

I need to create a DSP/BIOS console application which runs on the F28335 control card and uses both printf & scanf.  I would like to start with an automatically generated project, and make the minimum modifications necessary to get printf/scanf working.

Starting with the "Hello" DSP/Bios CCS 4.2 generated project, I was unable to get printf to work.  In generating the project I specfified the F28355 and used automatic for the linker file and run time support fields.    I modified the automatically provided hello.c to add printf output as follows:

#include <stdio.h>

#include "hellocfg.h"

/*
 *  ======== main ========
 */
Void main()
{
    LOG_printf(&trace, "hello world!");
    printf("Hello PRINTF\n");
    fflush(stdout);

    /* fall into DSP/BIOS idle loop */
    return;
}

I would like instructions for creating a DSP/BIOS project supporting printf.

John

  • John,

    I just tried printing with both SYS/BIOS and DSP/BIOS and I was able to print to the trace as well as system logs, but my regular printf statement failed.  I'm not a Bios expert but I suspect that there is no buffer associated with printf by default.  I checked the raw logs and it appears that when I call printf I get a bunch of errors.  Beyond this I'm afraid I won't be of much help, but I would recommend you start out by reading the documentation on DSP/Bios and/or Sys/Bios (Sys/bios is simply a newer version of DSP bios) that is available here:

    http://processors.wiki.ti.com/index.php/Category:DSPBIOS

    http://processors.wiki.ti.com/index.php/Category:SYSBIOS

    If you are unable to find what you need there, let me know and I will move this post into the DSP/Bios forum.

    Trey

  • John --

    I assume you are using DSP/BIOS.  Can you please specify the version?

    I suspect that the problem is related to not having a heap configured in your BIOS configuration.   printf() internally calls malloc().  If malloc() fails, the printf() will silently fail.

    Check this dialog box and make sure that the "No Dynamic Memory Heaps" check box is unchecked and you have a valid memory segment specified (not MEM_NULL).

    Regards,
    -Karl-

     

     

     

  • I changed to sys/bios.  I can print to the console window using System_printf(...). 

    Now I need to be able to do text input. I tried using scanf but get the following link error.

    "C:/tibin/ccsv4/tools/compiler/C2000 Code Generation Tools 5.2.11/bin/cl2000" --silicon_version=28 -g --diag_warning=225 --large_memory_model --unified_memory --float_support=fpu32 --printf_support=nofloat -z -m"SysBiosPrintf.map" --stack_size=0x300 --heap_size=0x400 --warn_sections -i"C:/tibin/ccsv4/tools/compiler/C2000 Code Generation Tools 5.2.11/lib" -i"C:/tibin/ccsv4/tools/compiler/C2000 Code Generation Tools 5.2.11/include" --reread_libs --rom_model -o "SysBiosPrintf.out" -l"./configPkg/linker.cmd" "./hello.obj" -l"libc.a"

    <Linking>

    "C:/Users/jsotack/Documents/workspace/SysBiosPrintf/Debug/configPkg/package/cfg/hello_p28FP_x.xdl", line 136: error:

    placement fails for object ".const", size 0x124e (page 0). Available

    ranges:

    L47SARAM size: 0x4000 unused: 0x29c max hole: 0x29c

    error: errors encountered during linking; "SysBiosPrintf.out" not built

     

    I am guessing this means there is not enough sampace (0x124e needed vs 0x29C available).

    Any recommendations on obtaining getchar or better yet, scanf type input would be appreciated.

    John

     

     

  • John,

    You are completely correct.  The linker was unable to place all of the symbols in the const section because it ran out of memory.  I can't say for certain, but I would bet that you still have plenty of memory left and just need to re-allocate how things are linked.

    From your console listing it looks like the file you need to modify will be "./configPkg/linker.cmd", although Bios may have a more elegant way of modifying the linker command file.

    Karl, care to comment?

    Trey

  • Thank you for your rapid response.

    The application in its current form simple prompted for a parameter and attempted to print what was entered back to the screen.  If I recall correctly the processor has 64Kbytes  onboard RAM and 512Kbytes so memory should not be a problem.  I think I need to read up on generating the memory map.

    It looks like the tools create memory segments for each block of flash and RAM.  I would rather have continuos segements treated as a single larger block.

     

    John

  • No problem,

    Linker command files are actually a lot easier than people make them out to be.  The assembly language tools user guide is a great place to start.  You can find it by searching for spru513d in the keyword search on the ti.com homepage.

    Grouping segments together is pretty easy if you know the syntax.  I'm not sure exactly what your LCF looks like because it was probably generated by Bios, but typically you can do something like this:

        .text   :   >> C0 | C1 | C2 | C3

    This tells the linker to allocate the text section into each of the memory regions starting with C0.  If C0 becomes full the linker continues with C1 and so forth.  Take a look at page 197 in that guide for more info.  Try doing something like that and I bet you can get your code to compile.

    Trey

     

  • I have since encountered a different issue where an array required 16K bytes and thus would not fit in a single section.  The "|" operater apparently allows the linker to place an object fully in any of a number of segments.  However, it may not span multiple segments.

     

    My solution was to follow what a TI provided cmd file did with  L0, 1, 2, 3 and combine 4-7 into one section as follows:

    L_4567_SARAM :

    origin = 0x00C000, length = 0x004000

    I can see the logic in treating treating L0-3 separately from L4-7 due to the code security module interactions.  Is there a reason to treat L4-L7 like four individual 4K word segments rather than one contiguous segment of 0x4000?

    John

  • John,

    The "|" operator tells the linker to try to use multiple memories if neccesarry, its the ">" or ">>" operator that tell the linker to keep the section in a single memory (>) or to split the section across multiple memories (>>).  If you were still having trouble when trying to use >> I suspect that the linker won't allow you to allocate continuous data sections (like your large buffer) across memory, but will allow discontinuous sections (like .text) to be split.

    Combining memories into a larger single memory is a perfectly acceptable solution, and we commonly do this here at TI.

    Each of the memories has different properites which is why we split them up.  Here is a quick breakdown:

    M0-M1 Non Secure RAM

    L0-L2 CLA Data RAM

    L3 CLA Program RAM

    L0-L4 Secure Memory

    L5-L8 Non-Secure DMA Accessable

    Feel free to combine and use memories as needed to suite your application.

    Trey

     

     

     

  • If there is no SW visible difference between L5-L8, why not lump them together in the example and CCS4 generated link cmd files?  Doing so might prevent people such as myself from needed to discovery and apply the solution manually.

    John 

  • John,

    They aren't contiguous so that users can split and combine them as neccesary for their application.  Tweaking a linker command file to suit an application is a standard part of embedded application development.  It is good that you are learning how to use the linker command file so that in the future if you need to move things around or get creative with sections you will know how to do so.

    Trey