This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Lookup Assembler (Area - DATA) with Mixed C/Assembler

Hello,
I was wondering if someone could give me some assistance. I am current using the TM4C1294 - Tiva micro-controller and attempting to store a few lists which I would like to use in a Main.c file.
The lists are a little too big to store the data inside my program. (I also need to access the consistently within the nanosecond timeframe (<<100 ns).

The program consists of main.c (C & ASM), system_tm4c129.c,TM4C1294NCPDT.h & startup_TM4C129.s

I have attempted to store data in "startup_TM4C129.s" (Right at the end)

AREA Table, DATA, READONLY
STANDARD_COLOURS DCB 0,0,0,0 ;No Colour / OFF DCB 255,0,0,0 ;Green DCB 0,255,0,0 ;Red
And the list goes on....

The data can be successfully compiled however I am unsure about whether this data can make it past the complication stage (I doubt it).

I am trying to access this list from my main.c(within an assembly insertion) and all I can typically get is #29: expected an expression (LDR R5, =STANDARD_COLOURS). I have been editing the startup.s file but I can't seem to get this working.

I am trying to transfer the address of the table STANDARD_COLOURS(starup.s) to a register so that I can perform successive fast calculations in a consistent manner.

In the past (Solely Assembly program) I have been able to run through a data table but I may have complicated things by trying to use mixed assembly.

Any help would be greatly appreciated - I have spent a considerable amount of time but my expertise is definitely not in programming...

Parents
  • The lists are a little too big to store the data inside my program.

    So why are you trying so hard to put that data inside your program, then? Just because you spell them in asm doesn't make them any less part of your program!

    On a related note, neither the size of the data nor the access speed you need is a valid reason to switch to assembly for setting up the tables. Given you're not a great expert in programming, by your own words, chances are really quite slim that you could do any better in hand-written assembler than the C compiler would, if you just avoided getting in its way. Most likely you'll just have made your part of the job a lot harder than it needs to be.

Reply
  • The lists are a little too big to store the data inside my program.

    So why are you trying so hard to put that data inside your program, then? Just because you spell them in asm doesn't make them any less part of your program!

    On a related note, neither the size of the data nor the access speed you need is a valid reason to switch to assembly for setting up the tables. Given you're not a great expert in programming, by your own words, chances are really quite slim that you could do any better in hand-written assembler than the C compiler would, if you just avoided getting in its way. Most likely you'll just have made your part of the job a lot harder than it needs to be.

Children
  • The worrying part comes here:
    "I also need to access the consistently within the nanosecond timeframe (<<100 ns)"

    <<100 ns would mean much less than 100ns - or much faster than 10MHz.

    If the processor runs at 120MHz you still and with much faster than 10MHz mean 40MHz, then you only have three clock cycles per memory access.

    By the way - the speed of the memory accesses aren't affected by which source file the values are stored in. So it doesn't matter if the data is in an assembler or a C file or if you have the data in an external serial flash and on startup reads in all the data.

  • Thanks for the information

    I have been getting some timings from my scope.
    Entry into inline Assembly - 121 ns

    C-type FOR Loop 1 Cycle = 490 ns, 10 Cycles = 2236 ns, 100 Cycles = 20040 ns

    Toggle directly in C - 112.7 ns (GPIO->DATA = True, GPIO->Data = False etc)

    NOPs put into code (While still in inline assembly)
    0 = 79 ns
    1 = 115.6 ns
    10 = 207.8 ns
    100 = 642.1 ns

    So I have come to the realisation that I need to perform the operation required while in assembly. I have taken the advice of declaring my unsigned char "ARRAY" in C.

    After many hours googling I have not been successful in passing a c-defined array "reference" to be inline assembly. I have been able to serially print this list using c and also print the memory address of each array element.

    Would anyone happen to have a simple example of transferring a reference (C-defined) to inline assembly ?

    Thanks in advance.

  • C++ introduced references, which is just syntactic sugar for an alternative way to work with pointers. Remember that the array name represents the address of the array.

    Write a dummy C function and call - look at the disassembly and you would see exactly how the array address gets sent and how the C function picks up the parameters and makes use of them. That's your basic skeleton for your assembler function.

    Just remember that you should forget inline assembler and write a big enough block of your code as one or more functions in an assembler file.

  • Hi Per,
    Thank you very much for that valuable info (Sort of like teaching a man to fish so he can feed himself).

    I tried what you said. Seems like the register r0 gets loaded with a part of the program counter (and incremented along the way).

    The first address my declare variable would be located was 0x000004D8. I made some minor modifications and saw that my magic reference (0xA1,0xB2,0xC3,0xD4) got moved 8 Bytes.
    I will try and write a simple checker in ASM which locates the position of my reference and then adds another 8 Bytes (Data location).

    As for the inline assembler - Great idea (Hopefully I won't have to dip into ASM code for the next project :~) ). If C was fast enough in this application I would have been finished writing this program on the first day...

    I was starting to get a little desperate ... i.e. trying to use the function memcpy to store at an arbitrary point in memory and then retrieve from that location.

    Thanks for your help

    Martin

  • If you have global variables, then C and assembler can each access the variables just by having the variable exported from one of the source files. The linker will properly adjust the references to the variable.

  • I forgot to mention - ARM has the ABI well documented, i.e. which registers that are used for parameter passing and for passing return values. And which registers that must keep their content when a function returns.

    Keil and ARM have lots of useful documents that you might retrieve while you go hunting for the documentation of the processor instructions.