Shop OBEX P1 Docs P2 Docs Learn Events
SD library in C - Page 2 — Parallax Forums

SD library in C

2»

Comments

  • jazzedjazzed Posts: 11,803
    edited 2013-12-04 10:20
    Maybe I'm very confused on how libraries work. I was under the impression that I could take a single function (or a bunch of functions) and put it in a library file (libPropWare.a). I could then write a program (SPI_Demo.c) which called a function within libPropWare.a and create an executable SPI_Demo.elf. I could also write a hundred other programs that called the same function(s) within libPropWare.a and I'd never have to re-compile libPropWare.a. ...


    You're not confused.

    This happens with SimpleIDE libraries.

    Sorry, but my time is very limited today so I can't help more than I have already.

    Perhaps David will help since he created common.mk.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-05 03:57
    jazzed wrote: »
    You're not confused.

    This happens with SimpleIDE libraries.

    Sorry, but my time is very limited today so I can't help more than I have already.

    Perhaps David will help since he created common.mk.
    I just noticed this. Can you post a zip file containing your code and Makefile and I'll try to figure out where it's going wrong?

    Oops. I just noticed that you've already provided a link to a GitHub repository. I'll pull the code and see if I can figure out what's going wrong.

    Edit: Sorry again. I guess I'm not sure what question I'm supposed to answer. What are you trying to do with common.mk that is giving you trouble?
  • ersmithersmith Posts: 6,054
    edited 2013-12-05 06:49
    The _load_start_xxx symbols are defined by the linker when building an executable. They will never appear in a library. That also means that pulling COG code out of a library can be tricky sometimes, because library files are only included when a symbol in them is referred to, and _load_start_xxx is not a symbol in any library file.

    The way around this is to refer to *some* symbol in the .o file you want linked. For example, you could place an initialization function that loads the COG in there. Or you could declare a mailbox variable that your main C code uses. Anything at all -- but it has to be an explicit symbol, not something like _load_start_xxx.

    Hope this helps.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-05 07:04
    ersmith wrote: »
    The _load_start_xxx symbols are defined by the linker when building an executable. They will never appear in a library. That also means that pulling COG code out of a library can be tricky sometimes, because library files are only included when a symbol in them is referred to, and _load_start_xxx is not a symbol in any library file.

    The way around this is to refer to *some* symbol in the .o file you want linked. For example, you could place an initialization function that loads the COG in there. Or you could declare a mailbox variable that your main C code uses. Anything at all -- but it has to be an explicit symbol, not something like _load_start_xxx.

    Hope this helps.
    I figured out a way around this for the drivers that are in the library. Now I just have to remember what I did! :-(
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-05 08:23
    ersmith wrote: »
    The _load_start_xxx symbols are defined by the linker when building an executable. They will never appear in a library. That also means that pulling COG code out of a library can be tricky sometimes, because library files are only included when a symbol in them is referred to, and _load_start_xxx is not a symbol in any library file.

    The way around this is to refer to *some* symbol in the .o file you want linked. For example, you could place an initialization function that loads the COG in there. Or you could declare a mailbox variable that your main C code uses. Anything at all -- but it has to be an explicit symbol, not something like _load_start_xxx.

    Hope this helps.

    If I understood that correctly (which I'm not 100% sure I did), I'm already doing that. libPropWare.a contains spi.c and spi_as.S. Those two files contain driver code for SPI comms, including the cog initialization (line 86 of spi.c). My demo application contains SPI_Demo.c and, within this file, I call SPIStart() from spi.c. I believe that call is what you're suggesting - something from outside the library calls an explicit label (that label is _SPIStart in this case) and then an internal function relative to the library file can start the cog.

    Uploading a zip file momentarily...
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-05 08:35
    I've removed the extra demo files and cleaned the Debug folder, so there are slightly fewer files in it now.

    Creation of the library can be done from within the Debug folder with "make -f../Makefile" (you'll need to set the PROPGCC_PREFIX variable in Makefile) and then the same command can be run from PropGCC_Demos/SPI/Debug with the same addition to PropGCC_Demos/SPI/Makefile. I did it this way so that it plays nicely with Eclipse and requires minimal changes to the default settings for any Eclipse CDT build.
  • ersmithersmith Posts: 6,054
    edited 2013-12-05 10:22
    If I understood that correctly (which I'm not 100% sure I did), I'm already doing that. libPropWare.a contains spi.c and spi_as.S. Those two files contain driver code for SPI comms, including the cog initialization (line 86 of spi.c). My demo application contains SPI_Demo.c and, within this file, I call SPIStart() from spi.c.
    Right, you have a reference to a function in spi.o, but you don't have any reference to spi_as.o (the file produced from spi_as.S) and so that file is *not* being pulled out of the library into your project. That's the difference between putting things into a library (.a file) and linking them all explicitly on the command line. The linker only takes the files from the library that are actually being used (that have references to them). Each .o file in the library is treated seperately for this purpose.

    The problem you're encountering is that you want spi_as.o to be linked, but the only reference to it is the implicit label _load_start_spi_as. That label doesn't actually exist anywhere in the object files, it is created by the linker when the spi_as_cog section is encountered. That leads to a chicken and egg problem -- the spi_as_cog section won't be included because there's no reference to anything in spi_as.o. You'll have to create some kind of dummy reference in spi_as.o to force it to be linked.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-05 13:53
    Okay, I'm understanding your point now, but unable to get it to work. There should be a label "led16" in spi_as.o (and I can see it in the map of libPropWare.a) so if I write a line in SPI_Demo.c that read "extern uint32_t led16[];", it should match to the label in spi_as.o correct?

    That's not working though. I thought maybe the compiler was optimizing that line out, so I stuck a simple "int x = *led16" at the top of SPI_Demo.c's main function and it didn't help any either. Perhaps it's still optimizing it out?

    Also, I've attached the map file of libPropWare.a for reference
    In archive libPropWare.a:
    
    PropWare.o:     file format elf32-propeller
    
    
    SYMBOL TABLE:
    00000000 l    d  .text	00000000 .text
    00000000 l    d  .data	00000000 .data
    00000000 l    d  .bss	00000000 .bss
    00000000 g       .text	00000000 0x40 _GPIOSwitchRead_Low
    00000000         *UND*	00000000 DIRA
    00000000         *UND*	00000000 OUTA
    00000000         *UND*	00000000 __clkfreq
    00000000         *UND*	00000000 CNT
    0000003e g       .text	00000000 0x40 _PropWareCountBits
    00000052 g       .text	00000000 0x40 _PropWareGetPinNum
    
    
    
    
    
    
    spi.o:     file format elf32-propeller
    
    
    SYMBOL TABLE:
    00000000 l    d  .text	00000000 .text
    00000000 l    d  .data	00000000 .data
    00000000 l    d  .bss	00000000 .bss
    00000000 l       .text	00000000 0x40 _SPIReadPar
    00000000 l       .data	00000000 0x40 _g_mailbox
    00000004 l       .data	00000000 0x40 _g_spiCog
    00000286 l       .text	00000000 0x40 .L40
    000002ab l       .text	00000000 0x40 .L43
    000002ad l       .text	00000000 0x40 .L39
    00000000         *UND*	00000000 __clkfreq
    00000000         *UND*	00000000 CNT
    0000005e g       .text	00000000 0x40 _SPIStop
    00000080 g       .text	00000000 0x40 _SPIIsRunning
    00000094 g       .text	00000000 0x40 _SPIWait
    000000c4 g       .text	00000000 0x40 _SPIWaitSpecific
    000000f7 g       .text	00000000 0x40 _SPISetMode
    0000012d g       .text	00000000 0x40 _SPISetBitMode
    00000169 g       .text	00000000 0x40 _SPISetClock
    000001ae g       .text	00000000 0x40 _SPIStart
    00000000         *UND*	00000000 _PropWareCountBits
    00000000         *UND*	00000000 __load_start_spi_as_cog
    00000000         *UND*	00000000 _PropWareGetPinNum
    000002b1 g       .text	00000000 0x40 _SPIGetClock
    000002f2 g       .text	00000000 0x40 _SPIShiftOut
    0000032d g       .text	00000000 0x40 _SPIShiftIn
    00000380 g       .text	00000000 0x40 _SPIShiftOut_fast
    000003a0 g       .text	00000000 0x40 _SPIShiftIn_fast
    000003f5 g       .text	00000000 0x40 _SPIShiftIn_sector
    
    
    
    
    
    
    spi_as.o:     file format elf32-propeller
    
    
    SYMBOL TABLE:
    00000000 l    d  .text	00000000 .text
    00000000 l    d  .data	00000000 .data
    00000000 l    d  .bss	00000000 .bss
    00000000 l    d  spi_as_cog	00000000 spi_as_cog
    000004a4 l       spi_as_cog	00000000 testLEDs
    00000490 l       spi_as_cog	00000000 negOne
    00000440 l       spi_as_cog	00000000 READ_CMD
    00000450 l       spi_as_cog	00000000 READ_CMD_ret
    000004f0 l       spi_as_cog	00000000 mosi
    000004cc l       spi_as_cog	00000000 mailbox
    000004f4 l       spi_as_cog	00000000 mosiPinNum
    000004f8 l       spi_as_cog	00000000 miso
    000004fc l       spi_as_cog	00000000 misoPinNum
    00000500 l       spi_as_cog	00000000 sclk
    0000003c l       spi_as_cog	00000000 LOOP
    000004d0 l       spi_as_cog	00000000 temp
    00000494 l       spi_as_cog	00000000 spiFuncBits
    000000d0 l       spi_as_cog	00000000 SEND
    00000170 l       spi_as_cog	00000000 READ
    00000270 l       spi_as_cog	00000000 SEND_fast
    000002f8 l       spi_as_cog	00000000 READ_fast
    000003d8 l       spi_as_cog	00000000 read_sector
    00000094 l       spi_as_cog	00000000 SET_MODE
    000000ac l       spi_as_cog	00000000 SET_BITMODE
    000000b8 l       spi_as_cog	00000000 SET_FREQ
    000000c4 l       spi_as_cog	00000000 GET_FREQ
    00000454 l       spi_as_cog	00000000 READ_DATA
    00000464 l       spi_as_cog	00000000 READ_DATA_ret
    000004e4 l       spi_as_cog	00000000 clkPhase
    000004e0 l       spi_as_cog	00000000 bitmode
    00000504 l       spi_as_cog	00000000 clkDelay
    000004ec l       spi_as_cog	00000000 data
    00000468 l       spi_as_cog	00000000 WRITE_DATA
    00000478 l       spi_as_cog	00000000 WRITE_DATA_ret
    000004e8 l       spi_as_cog	00000000 bitCount
    00000498 l       spi_as_cog	00000000 spiBitCountBits
    000000dc l       spi_as_cog	00000000 SEND_rd_data
    0000049c l       spi_as_cog	00000000 dataMask
    000004dc l       spi_as_cog	00000000 clock
    00000110 l       spi_as_cog	00000000 msb_first
    000004d8 l       spi_as_cog	00000000 loopIdx
    0000013c l       spi_as_cog	00000000 lsb_first
    00000168 l       spi_as_cog	00000000 SEND_complete
    000001a4 l       spi_as_cog	00000000 read_msb_first
    0000023c l       spi_as_cog	00000000 lsb_cpha1
    0000026c l       spi_as_cog	00000000 lsb_cpha1_ret
    000001e0 l       spi_as_cog	00000000 lsb_cpha0
    00000210 l       spi_as_cog	00000000 lsb_cpha0_ret
    000001b0 l       spi_as_cog	00000000 finish_lsb_first
    00000214 l       spi_as_cog	00000000 msb_cpha1
    00000238 l       spi_as_cog	00000000 msb_cpha1_ret
    000001b8 l       spi_as_cog	00000000 msb_cpha0
    000001dc l       spi_as_cog	00000000 msb_cpha0_ret
    0000027c l       spi_as_cog	00000000 SEND_rd_data_fast
    000002a8 l       spi_as_cog	00000000 msb_first_fast
    000002cc l       spi_as_cog	00000000 lsb_first_fast
    000002f0 l       spi_as_cog	00000000 SEND_complete_fast
    0000032c l       spi_as_cog	00000000 read_msb_first_fast
    000003ac l       spi_as_cog	00000000 lsb_post_fast
    000003d4 l       spi_as_cog	00000000 lsb_post_fast_ret
    00000360 l       spi_as_cog	00000000 lsb_pre_fast
    00000388 l       spi_as_cog	00000000 lsb_pre_fast_ret
    00000338 l       spi_as_cog	00000000 finish_lsb_first_fast
    0000038c l       spi_as_cog	00000000 msb_post_fast
    000003a8 l       spi_as_cog	00000000 msb_post_fast_ret
    00000340 l       spi_as_cog	00000000 msb_pre_fast
    0000035c l       spi_as_cog	00000000 msb_pre_fast_ret
    000003d8 l       spi_as_cog	00000000 read_sector_addr
    000004a0 l       spi_as_cog	00000000 sdSectorSize
    000003e8 l       spi_as_cog	00000000 beginSectorRead
    000003ec l       spi_as_cog	00000000 read_byte
    00000418 l       spi_as_cog	00000000 POST_CLOCK
    00000428 l       spi_as_cog	00000000 POST_CLOCK_ret
    0000042c l       spi_as_cog	00000000 PRE_CLOCK
    0000043c l       spi_as_cog	00000000 PRE_CLOCK_ret
    0000046c l       spi_as_cog	00000000 write_loop
    0000047c l       spi_as_cog	00000000 SEND_TO_LED
    000004d4 l       spi_as_cog	00000000 temp2
    0000048c l       spi_as_cog	00000000 SEND_TO_LED_ret
    000004a8 l       spi_as_cog	00000000 led16
    000004ac l       spi_as_cog	00000000 led17
    000004b0 l       spi_as_cog	00000000 led18
    000004b4 l       spi_as_cog	00000000 led19
    000004b8 l       spi_as_cog	00000000 led20
    000004bc l       spi_as_cog	00000000 led21
    000004c0 l       spi_as_cog	00000000 led22
    000004c4 l       spi_as_cog	00000000 led23
    000004c8 l       spi_as_cog	00000000 quarterSecond
    00000000         *UND*	00000000 dira
    00000000         *UND*	00000000 par
    00000000         *UND*	00000000 outa
    00000000         *UND*	00000000 cnt
    00000000         *UND*	00000000 ina
    
    
    
    
    
    
    sd.o:     file format elf32-propeller
    
    
    SYMBOL TABLE:
    00000000 l    d  .text	00000000 .text
    00000000 l    d  .data	00000000 .data
    00000000 l    d  .bss	00000000 .bss
    00000004 l     O .bss	00000001 _g_sd_firstByteResponse
    00000000 l     O .bss	00000004 _g_sd_cs
    00000173 l       .text	00000000 0x40 .L37
    00000231 l       .text	00000000 0x40 .L34
    00000263 l       .text	00000000 0x40 .L43
    000002dc l       .text	00000000 0x40 .L47
    000002de l       .text	00000000 0x40 .L33
    000003cf l       .text	00000000 0x40 .L66
    000003d1 l       .text	00000000 0x40 .L55
    00000490 l       .text	00000000 0x40 .L81
    00000492 l       .text	00000000 0x40 .L73
    0000022c l     O .bss	00000001 _g_sd_fatMod
    00000010 l     O .bss	00000004 _g_sd_fatStart
    00000224 l     O .bss	00000004 _g_sd_curFatSector
    00000024 l     O .bss	00000200 _g_sd_fat
    00000020 l     O .bss	00000004 _g_sd_fatSize
    000006ac l       .text	00000000 0x40 .L107
    000006ad l       .text	00000000 0x40 .L104
    00000014 l     O .bss	00000004 _g_sd_rootAddr
    0000000c l     O .bss	00000001 _g_sd_filesystem
    0000001c l     O .bss	00000004 _g_sd_rootAllocUnit
    00000005 l     O .bss	00000001 _g_sd_sectorsPerCluster_shift
    00000018 l     O .bss	00000004 _g_sd_firstDataAddr
    0000000e l     O .bss	00000002 _g_sd_entriesPerFatSector_Shift
    00000749 l       .text	00000000 0x40 .L113
    00000796 l       .text	00000000 0x40 .L115
    00000008 l     O .bss	00000004 _g_sd_rootDirSectors
    00000228 l     O .bss	00000004 _g_sd_dir_firstAllocUnit
    00000961 l       .text	00000000 0x40 .L119
    00000a3f l       .text	00000000 0x40 .L147
    00000a41 l       .text	00000000 0x40 .L144
    00000a71 l       .text	00000000 0x40 .L142
    00000ae6 l       .text	00000000 0x40 .L150
    00000b80 l       .text	00000000 0x40 .L160
    00000c71 l       .text	00000000 0x40 .L176
    00000ccf l       .text	00000000 0x40 .L174
    00000db3 l       .text	00000000 0x40 .L186
    00000e39 l       .text	00000000 0x40 .L194
    00000ed7 l       .text	00000000 0x40 .L234
    00000f29 l       .text	00000000 0x40 .L238
    00000f30 l       .text	00000000 0x40 .L231
    00000f50 l       .text	00000000 0x40 .L233
    00000f6a l       .text	00000000 0x40 .L236
    00000fc1 l       .text	00000000 0x40 .L235
    00000fc9 l       .text	00000000 0x40 .L232
    00000fe2 l       .text	00000000 0x40 .L237
    000010bc l       .text	00000000 0x40 .L240
    00001118 l       .text	00000000 0x40 .L242
    000011b5 l       .text	00000000 0x40 .L247
    0000128a l       .text	00000000 0x40 .L276
    000012f7 l       .text	00000000 0x40 .L263
    0000022d l     O .bss	00000001 _g_sd_fileID
    000014ce l       .text	00000000 0x40 .L282
    00000000 l       .data	00000000 0x40 .LC0
    00001659 l       .text	00000000 0x40 .L324
    00001667 l       .text	00000000 0x40 .L321
    00000008 l       .data	00000000 0x40 .LC1
    0000004c l       .data	00000000 0x40 .LC2
    00000058 l       .data	00000000 0x40 .LC3
    00000060 l       .data	00000000 0x40 .LC4
    00000064 l       .data	00000000 0x40 .LC5
    00000068 l       .data	00000000 0x40 .LC6
    0000006c l       .data	00000000 0x40 .LC7
    00000074 l       .data	00000000 0x40 .LC8
    0000007c l       .data	00000000 0x40 .LC9
    00000094 l       .data	00000000 0x40 .LC10
    000000b4 l       .data	00000000 0x40 .LC11
    000000d4 l       .data	00000000 0x40 .LC12
    000000f8 l       .data	00000000 0x40 .LC13
    000016b2 l       .text	00000000 0x40 .L356
    000017ad l       .text	00000000 0x40 .L345
    000017c2 l       .text	00000000 0x40 .L354
    0000182d l       .text	00000000 0x40 .L330
    0000183a l       .text	00000000 0x40 .L349
    00000000 g       .text	00000000 0x40 _SDfeof
    00000013 g       .text	00000000 0x40 _SDfseekr
    00000045 g       .text	00000000 0x40 _SDfseekw
    00000077 g       .text	00000000 0x40 _SDftellr
    0000007c g       .text	00000000 0x40 _SDftellw
    00000081 g       .text	00000000 0x40 _SDSendCommand
    00000000         *UND*	00000000 _SPIShiftOut
    000000bb g       .text	00000000 0x40 _SDGetResponse
    00000000         *UND*	00000000 __clkfreq
    00000000         *UND*	00000000 CNT
    00000000         *UND*	00000000 _SPIShiftIn
    00000133 g       .text	00000000 0x40 _SDStart
    00000000         *UND*	00000000 DIRA
    00000000         *UND*	00000000 OUTA
    00000000         *UND*	00000000 _SPIStart
    00000000         *UND*	00000000 _SPIWait
    00000000         *UND*	00000000 _SPISetClock
    000002e4 g       .text	00000000 0x40 _SDReadBlock
    00000000         *UND*	00000000 __MASK_0000FFFF
    00000000         *UND*	00000000 _SPIShiftIn_fast
    000003d7 g       .text	00000000 0x40 _SDWriteBlock
    00000000         *UND*	00000000 _SPIShiftOut_fast
    00000496 g       .text	00000000 0x40 _SDReadDataBlock
    000004f1 g       .text	00000000 0x40 _SDWriteDataBlock
    0000054c g       .text	00000000 0x40 _SDUnmount
    00000218       O *COM*	00000004 _g_sd_buf
    000005a4 g       .text	00000000 0x40 _SDReadDat16
    000005b6 g       .text	00000000 0x40 _SDReadDat32
    000005d9 g       .text	00000000 0x40 _SDWriteDat16
    000005e5 g       .text	00000000 0x40 _SDWriteDat32
    00000601 g       .text	00000000 0x40 _SDfclose
    000006b1 g       .text	00000000 0x40 _SDGetSectorFromPath
    000006b7 g       .text	00000000 0x40 _SDGetSectorFromAlloc
    000006d9 g       .text	00000000 0x40 _SDGetFATValue
    0000079a g       .text	00000000 0x40 _SDMount
    00000965 g       .text	00000000 0x40 _SDLoadSectorFromOffset
    00000a73 g       .text	00000000 0x40 _SDIncCluster
    00000ae8 g       .text	00000000 0x40 _SDLoadNextSector
    00000b84 g       .text	00000000 0x40 _SDGetFilename
    00000be7 g       .text	00000000 0x40 _SDFind
    00000000         *UND*	00000000 _strcmp
    00000cd5 g       .text	00000000 0x40 _SDchdir
    00000db9 g       .text	00000000 0x40 _SDReloadBuf
    00000e3b g       .text	00000000 0x40 _SDfgetc
    00000e81 g       .text	00000000 0x40 _SDfgets
    00000eb6 g       .text	00000000 0x40 _SDFindEmptySpace
    00001049 g       .text	00000000 0x40 _SDExtendFAT
    0000111a g       .text	00000000 0x40 _SDfputc
    000011b9 g       .text	00000000 0x40 _SDfputs
    000011d7 g       .text	00000000 0x40 _SDCreateFile
    000012f9 g       .text	00000000 0x40 _SD_Shell_touch
    00001325 g       .text	00000000 0x40 _SDfopen
    000014d2 g       .text	00000000 0x40 _SD_Shell_cat
    00000000         *UND*	00000000 ___files
    00000000         *UND*	00000000 _fputc
    0000150b g       .text	00000000 0x40 _SDPrintFileAttributes
    00001587 g       .text	00000000 0x40 _SDPrintFileEntry
    00000000         *UND*	00000000 _printf
    000015ca g       .text	00000000 0x40 _SD_Shell_ls
    0000166b g       .text	00000000 0x40 _SD_Shell
    00000000         *UND*	00000000 _memset
    00000000         *UND*	00000000 _puts
    00000000         *UND*	00000000 _gets
    
    
    
    
    
    
    l3g.o:     file format elf32-propeller
    
    
    SYMBOL TABLE:
    00000000 l    d  .text	00000000 .text
    00000000 l    d  .data	00000000 .data
    00000000 l    d  .bss	00000000 .bss
    00000000 l       .text	00000000 0x40 _L3GWrite8
    0000005c l       .text	00000000 0x40 _L3GRead8
    000000c0 l       .text	00000000 0x40 _L3GRead16
    00000138 l       .text	00000000 0x40 .L9
    00000283 l       .text	00000000 0x40 .L22
    000002f1 l       .text	00000000 0x40 .L27
    00000000 g       .bss	00000000 0x40 _g_l3g_alwaysSetMode
    00000000         *UND*	00000000 _SPISetMode
    00000000         *UND*	00000000 _SPISetBitMode
    00000004       O *COM*	00000004 _g_l3g_cs
    00000000         *UND*	00000000 OUTA
    00000000         *UND*	00000000 _SPIShiftOut
    00000000         *UND*	00000000 _SPIWait
    00000000         *UND*	00000000 _SPIShiftIn
    0000013c g       .text	00000000 0x40 _L3GStart
    00000000         *UND*	00000000 _SPIIsRunning
    00000000         *UND*	00000000 _SPIStart
    00000000         *UND*	00000000 DIRA
    000001a9 g       .text	00000000 0x40 _L3GAlwaysSetMode
    000001af g       .text	00000000 0x40 _L3GReadX
    000001ba g       .text	00000000 0x40 _L3GReadY
    000001c5 g       .text	00000000 0x40 _L3GReadZ
    000001d0 g       .text	00000000 0x40 _L3GRead
    000001df g       .text	00000000 0x40 _L3GReadAll
    00000287 g       .text	00000000 0x40 _L3G_ioctl
    
    
    
    
    
    
    mcp300x.o:     file format elf32-propeller
    
    
    SYMBOL TABLE:
    00000000 l    d  .text	00000000 .text
    00000000 l    d  .data	00000000 .data
    00000000 l    d  .bss	00000000 .bss
    000000da l       .text	00000000 0x40 .L8
    00000159 l       .text	00000000 0x40 .L11
    00000000 g       .text	00000000 0x40 _MCP300xStart
    00000001       O *COM*	00000001 _g_mcp300x_cs
    00000000         *UND*	00000000 DIRA
    00000000         *UND*	00000000 OUTA
    00000000         *UND*	00000000 _SPIIsRunning
    00000000         *UND*	00000000 _SPIStart
    00000000         *UND*	00000000 _SPISetMode
    00000000         *UND*	00000000 _SPISetBitMode
    00000059 g       .text	00000000 0x40 _MCP300xAlwaysSetMode
    00000000 g       .bss	00000000 0x40 _g_mcp300x_alwaysSetMode
    0000005f g       .text	00000000 0x40 _MCP300xRead
    00000000         *UND*	00000000 _SPIShiftOut
    00000000         *UND*	00000000 _SPIShiftIn
    000000de g       .text	00000000 0x40 _MCP300xReadDif
    
    
    
    
    
    
    hd44780.o:     file format elf32-propeller
    
    
    SYMBOL TABLE:
    00000000 l    d  .text	00000000 .text
    00000000 l    d  .data	00000000 .data
    00000000 l    d  .bss	00000000 .bss
    00000000 l       .text	00000000 0x40 _HD44780ClockPulse
    00000008 l     O .bss	00000004 _g_hd44780_en
    0000002d l       .text	00000000 0x40 _HD44780Write
    00000004 l     O .bss	00000004 _g_hd44780_rw
    00000018 l     O .bss	00000004 _g_hd44780_bitmode
    00000010 l     O .bss	00000001 _g_hd44780_dataLSBNum
    0000000c l     O .bss	00000004 _g_hd44780_dataMask
    00000095 l       .text	00000000 0x40 _HD44780Cmd
    00000000 l     O .bss	00000004 _g_hd44780_rs
    00000020 l     O .bss	00000001 _g_hd44780_curRow
    00000021 l     O .bss	00000001 _g_hd44780_curCol
    00000014 l     O .bss	00000004 _g_hd44780_dim
    0000001c l     O .bss	00000004 _g_hd44780_memMap
    0000022d l       .text	00000000 0x40 .L61
    00000248 l       .text	00000000 0x40 .L20
    0000025e l       .text	00000000 0x40 .L62
    00000262 l       .text	00000000 0x40 .L22
    00000271 l       .text	00000000 0x40 .L23
    00000289 l       .text	00000000 0x40 .L24
    00000290 l       .text	00000000 0x40 .L25
    0000029f l       .text	00000000 0x40 .L63
    000002b9 l       .text	00000000 0x40 .L27
    000002be l       .text	00000000 0x40 .L59
    000002c7 l       .text	00000000 0x40 .L29
    000002ce l       .text	00000000 0x40 .L30
    000002da l       .text	00000000 0x40 .L53
    000002df l       .text	00000000 0x40 .L56
    000002e4 l       .text	00000000 0x40 .L54
    000003a2 l       .text	00000000 0x40 .L41
    000003a6 l       .text	00000000 0x40 .L45
    000003a8 l       .text	00000000 0x40 .L9
    000004a1 l       .text	00000000 0x40 .L85
    000004a4 l       .text	00000000 0x40 .L76
    00000528 l       .text	00000000 0x40 .L89
    000005cf l       .text	00000000 0x40 .L127
    00000630 l       .text	00000000 0x40 .L120
    0000063a l       .text	00000000 0x40 .L129
    0000063e l       .text	00000000 0x40 .L118
    00000642 l       .text	00000000 0x40 .L117
    00000647 l       .text	00000000 0x40 .L116
    00000000         *UND*	00000000 OUTA
    00000000         *UND*	00000000 __clkfreq
    00000000         *UND*	00000000 CNT
    000000ab g       .text	00000000 0x40 _HD44780Clear
    000000d8 g       .text	00000000 0x40 _HD44780Start
    00000000         *UND*	00000000 _PropWareCountBits
    00000000         *UND*	00000000 DIRA
    000003aa g       .text	00000000 0x40 _HD44780Move
    00000418 g       .text	00000000 0x40 _HD44780_putchar
    000004a6 g       .text	00000000 0x40 _HD44780_puts
    000004b9 g       .text	00000000 0x40 _HD44780_int
    0000052c g       .text	00000000 0x40 _HD44780_uint
    0000057e g       .text	00000000 0x40 _HD44780_hex
    000005c4 g       .text	00000000 0x40 _HD44780_printf
    
  • ersmithersmith Posts: 6,054
    edited 2013-12-05 14:40
    Okay, I'm understanding your point now, but unable to get it to work. There should be a label "led16" in spi_as.o (and I can see it in the map of libPropWare.a) so if I write a line in SPI_Demo.c that read "extern uint32_t led16[];", it should match to the label in spi_as.o correct?
    No, that won't work (at least not as is). There are actually two issues:
    (1) led16 is not marked as ".global", and so its definition is local to that specific .o file (like a C "static" variable). It can't be referenced from outside.
    (2) There's another wrinkle: to avoid conflict with assembly language labels, C automatically prepends an underscore to variable names. So the C variable "foo" is actually "_foo" in assembly. You can override this with a __asm__ directive:
         extern int x __asm__("led16");
    
    will declare "x" as a C variable that matches an assembly variable named "led16" (exactly like that, no underscores). You'll still need to add a ".global led16" to the assembly language file.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-05 15:16
    Alright, I added "\t\t.global spiDummyVar" to the assembly and the new map looks like this... (spiDummyVar is at the very bottom)
    spi_as.o:     file format elf32-propeller
    
    SYMBOL TABLE:
    00000000 l    d  .text	00000000 .text
    00000000 l    d  .data	00000000 .data
    00000000 l    d  .bss	00000000 .bss
    00000000 l    d  spi_as_cog	00000000 spi_as_cog
    000004a4 l       spi_as_cog	00000000 testLEDs
    00000490 l       spi_as_cog	00000000 negOne
    00000440 l       spi_as_cog	00000000 READ_CMD
    00000450 l       spi_as_cog	00000000 READ_CMD_ret
    000004f0 l       spi_as_cog	00000000 mosi
    000004cc l       spi_as_cog	00000000 mailbox
    000004f4 l       spi_as_cog	00000000 mosiPinNum
    000004f8 l       spi_as_cog	00000000 miso
    000004fc l       spi_as_cog	00000000 misoPinNum
    00000500 l       spi_as_cog	00000000 sclk
    0000003c l       spi_as_cog	00000000 LOOP
    000004d0 l       spi_as_cog	00000000 temp
    00000494 l       spi_as_cog	00000000 spiFuncBits
    000000d0 l       spi_as_cog	00000000 SEND
    00000170 l       spi_as_cog	00000000 READ
    00000270 l       spi_as_cog	00000000 SEND_fast
    000002f8 l       spi_as_cog	00000000 READ_fast
    000003d8 l       spi_as_cog	00000000 read_sector
    00000094 l       spi_as_cog	00000000 SET_MODE
    000000ac l       spi_as_cog	00000000 SET_BITMODE
    000000b8 l       spi_as_cog	00000000 SET_FREQ
    000000c4 l       spi_as_cog	00000000 GET_FREQ
    00000454 l       spi_as_cog	00000000 READ_DATA
    00000464 l       spi_as_cog	00000000 READ_DATA_ret
    000004e4 l       spi_as_cog	00000000 clkPhase
    000004e0 l       spi_as_cog	00000000 bitmode
    00000504 l       spi_as_cog	00000000 clkDelay
    000004ec l       spi_as_cog	00000000 data
    00000468 l       spi_as_cog	00000000 WRITE_DATA
    00000478 l       spi_as_cog	00000000 WRITE_DATA_ret
    000004e8 l       spi_as_cog	00000000 bitCount
    00000498 l       spi_as_cog	00000000 spiBitCountBits
    000000dc l       spi_as_cog	00000000 SEND_rd_data
    0000049c l       spi_as_cog	00000000 dataMask
    000004dc l       spi_as_cog	00000000 clock
    00000110 l       spi_as_cog	00000000 msb_first
    000004d8 l       spi_as_cog	00000000 loopIdx
    0000013c l       spi_as_cog	00000000 lsb_first
    00000168 l       spi_as_cog	00000000 SEND_complete
    000001a4 l       spi_as_cog	00000000 read_msb_first
    0000023c l       spi_as_cog	00000000 lsb_cpha1
    0000026c l       spi_as_cog	00000000 lsb_cpha1_ret
    000001e0 l       spi_as_cog	00000000 lsb_cpha0
    00000210 l       spi_as_cog	00000000 lsb_cpha0_ret
    000001b0 l       spi_as_cog	00000000 finish_lsb_first
    00000214 l       spi_as_cog	00000000 msb_cpha1
    00000238 l       spi_as_cog	00000000 msb_cpha1_ret
    000001b8 l       spi_as_cog	00000000 msb_cpha0
    000001dc l       spi_as_cog	00000000 msb_cpha0_ret
    0000027c l       spi_as_cog	00000000 SEND_rd_data_fast
    000002a8 l       spi_as_cog	00000000 msb_first_fast
    000002cc l       spi_as_cog	00000000 lsb_first_fast
    000002f0 l       spi_as_cog	00000000 SEND_complete_fast
    0000032c l       spi_as_cog	00000000 read_msb_first_fast
    000003ac l       spi_as_cog	00000000 lsb_post_fast
    000003d4 l       spi_as_cog	00000000 lsb_post_fast_ret
    00000360 l       spi_as_cog	00000000 lsb_pre_fast
    00000388 l       spi_as_cog	00000000 lsb_pre_fast_ret
    00000338 l       spi_as_cog	00000000 finish_lsb_first_fast
    0000038c l       spi_as_cog	00000000 msb_post_fast
    000003a8 l       spi_as_cog	00000000 msb_post_fast_ret
    00000340 l       spi_as_cog	00000000 msb_pre_fast
    0000035c l       spi_as_cog	00000000 msb_pre_fast_ret
    000003d8 l       spi_as_cog	00000000 read_sector_addr
    000004a0 l       spi_as_cog	00000000 sdSectorSize
    000003e8 l       spi_as_cog	00000000 beginSectorRead
    000003ec l       spi_as_cog	00000000 read_byte
    00000418 l       spi_as_cog	00000000 POST_CLOCK
    00000428 l       spi_as_cog	00000000 POST_CLOCK_ret
    0000042c l       spi_as_cog	00000000 PRE_CLOCK
    0000043c l       spi_as_cog	00000000 PRE_CLOCK_ret
    0000046c l       spi_as_cog	00000000 write_loop
    0000047c l       spi_as_cog	00000000 SEND_TO_LED
    000004d4 l       spi_as_cog	00000000 temp2
    0000048c l       spi_as_cog	00000000 SEND_TO_LED_ret
    000004a8 l       spi_as_cog	00000000 led16
    000004ac l       spi_as_cog	00000000 led17
    000004b0 l       spi_as_cog	00000000 led18
    000004b4 l       spi_as_cog	00000000 led19
    000004b8 l       spi_as_cog	00000000 led20
    000004bc l       spi_as_cog	00000000 led21
    000004c0 l       spi_as_cog	00000000 led22
    000004c4 l       spi_as_cog	00000000 led23
    000004c8 l       spi_as_cog	00000000 quarterSecond
    00000000         *UND*	00000000 spiDummyVar
    00000000         *UND*	00000000 dira
    00000000         *UND*	00000000 par
    00000000         *UND*	00000000 outa
    00000000         *UND*	00000000 cnt
    00000000         *UND*	00000000 ina
    
    I notice its label is very different from all the others. For one, the address is 0, and two, it's got "*UND*", which to me means nothing. Googling that didn't help a lot either.

    I then added "extern int dummyVarToForceLoadOfSPI_AS_S __asm__("spiDummyVar");" and it didn't help. I added that line to SPI_Demo.c and set it to 1 in main() so that the compiler didn't optimize anything away.

    Still no luck.

    It is very cool to look through the map of the executable though and see exactly which functions are being pulled from libc.a without me knowing. It ought to help me optimize code size by 1) knowing that function X is being included when I don't want it, and 2) knowing that function Y must be included for function A, so I might as well take advantage of it everywhere else too.
  • ersmithersmith Posts: 6,054
    edited 2013-12-05 18:27

    I notice its label is very different from all the others. For one, the address is 0, and two, it's got "*UND*", which to me means nothing. Googling that didn't help a lot either.
    "**UND**" means "undefined". In the assembly file you have to both have the ".global" declaration (which says make the given symbol global") *and* a definition of the value for the symbol. This can be a label or an equate.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-06 10:06
    I didn't realize the expression following .global was supposed to be a symbol defined somewhere else. I thought .global would define a new global symbol.

    Top of the assembly file now looks like this
    .section spi_as_cog, "ax"
                            .compress off
    
                            org 0
    
                            .global _SPI_DUMMY_VAR
    _SPI_DUMMY_VAR          jmp #_SPI_DUMMY_VAR
    
                            or dira, testLEDs               '' DEBUG: LEDs used for debugging purposes, can be removed later
                            wrlong negOne, par              '' Inform parent cog that initialization has begun
    
    So that's good!

    SPI_Demo.elf's map contained
    spi_as_cog      0x000018fc      0x50c
                    0x000018fc                . = ALIGN (0x4)
                    0x000018fc                PROVIDE (__start_spi_as_cog, ABSOLUTE (.))
     spi_as_cog     0x000018fc      0x50c ../../../Debug/libPropWare.a(spi_as.o)
                    0x000018fc                _SPI_DUMMY_VAR
                    0x00001e08                PROVIDE (__stop_spi_as_cog, .)
    

    So I changed the top of spi.c to look like
    // Global variables
    extern uint32_t _start_spi_as_cog[];
    

    And fixed up SPI_Demo.c
    extern uint32_t SPI_DUMMY_VAR[];
    
    with a reference in main:
    in = SPI_DUMMY_VAR;
    

    And that worked, but now, new errors have popped up.
    OUTPUT(SPI_Demo.elf elf32-propeller)
    ../../../Debug/libPropWare.a(spi_as.o): In function `_SPI_DUMMY_VAR':
    (spi_as_cog+0x0): relocation truncated to fit: R_PROPELLER_SRC against symbol `_SPI_DUMMY_VAR' defined in spi_as_cog section in ../../../Debug/libPropWare.a(spi_as.o)
    ../../../Debug/libPropWare.a(spi_as.o): In function `_SPI_DUMMY_VAR':
    (spi_as_cog+0x4): relocation truncated to fit: R_PROPELLER_SRC against `testLEDs'
    ../../../Debug/libPropWare.a(sp........................
    ..........................
    ...........................
    

    Google tells me that this happens when the program is so large, it exceeds the addressable memory (like a 5 GB program running on a 32-bit system).
    Would this be the same error that shows up when a prop program exceeds it's 32kB max? Either case doesn't make sense since there's no way my program is that large.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-06 10:07
    Well I feel dumb lol. I wrote the jmp loop when I had it at the bottom of the file... I think I'll change it to a nop now :P
  • ersmithersmith Posts: 6,054
    edited 2013-12-06 13:09
    I think you need to have:
        .section spi_as.cog, "ax"
    
    instead of
        .section spi_as_cog, "ax"
    
    I think only sections that end in ".cog" are recognized as COG sections by the linker; "_cog" will be treated as a regular data section and linked into HUB memory (hence the overflows, the HUB addresses are too big to fit in the 9 bit fields in the PASM assembly).

    Eric
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-06 13:41
    I feel like this is now appropriate :D
    Happy+Dance.jpeg

    Thanks for your help and patience Eric!

    @David Betz: I'd still love to hear how you got around this in your libraries. Though I now have it working, it requires not only the "extern int dummyVar[]" at the top of the file, but I must also reference that variable in a useful fashion in the driver program (aka, "int x = dummyVar" as the first line of main() isn't good enough). This is horrible and ugly and I don't want to force users of PropWare to do this.

    I suppose one way to get around it is to move "extern __load_start_spi_as_cog[];" into spi.h and pass that address in as a parameter to SPIStart(). Probably prettier than the current solution, but not ideal.
    300 x 278 - 24K
  • ersmithersmith Posts: 6,054
    edited 2013-12-06 18:11
    The root of the problem is that you always need to include the assembly language section if you're linking the C interface. So there are a couple of more elegant ways to force this:

    (1) Do a partial link of spi.o (the C interface) and spi_as.o (the COG assembly code) using the -r option to propeller-elf-ld. Call the result something like spi_combined.o, and put that file in the library instead of spi.o and spi_as.o. That way the C and assembly are always pulled in together.

    (2) Even easier (but perhaps slightly less flexible): put the code to launch the COG in the assembly file, instead of in the C file. You'd do this by adding something like:
        '' function to start the SPI code in its own COG
        '' C interface is:
        '' int start_spi_cog(void *arg);
        '' returns the number of the COG, or -1 if no COGs are left
    
        .text
        .global    _start_spi_cog
    _start_spi_cog
        mviw   r7,#__load_start_spi_as_cog  '' linker magic for the start of the spi_as.cog section
        shl    r7, #2
        or     r7, #8  '' 8 means "first available cog
        shl    r0, #16 '' assumes bottom two bits of r0 are 0, i.e. arg must be long aligned
        or     r0, r7
        coginit    r0 wc,wr
        IF_B  neg    r0,#1  '' if C is set, return -1
        lret
    
    to the end of spi_as.S (after the .compress default). This is perfectly legal; the code is marked as .text, so the linker will know it should go in the HUB instead of in the COG memory.

    Then replace the cognew() in spi.c with something like:
    extern int start_spi_cog(void *arg);
    ...
    cogid = start_spi_cog(&g_mailbox);
    
    This has several advantages: it hides the whole _load_start_spi_as_cog stuff inside spi_as.s, and also provides a symbol (_start_spi_cog) that will force spi_as.o to be linked.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-08 00:05
    I'm getting undefined reference errors with your second suggestion. Namely:
    /home/david/External/Kits/Embedded/Parallax/Library/PropWare/lmm/libPropWare.a(spi_as.o): In function `_SPIStartCog':(.text+0x20): undefined reference to `__LMM_lret_ret'
    /home/david/External/Kits/Embedded/Parallax/Library/PropWare/lmm/libPropWare.a(spi_as.o): In function `_SPIStartCog':
    (.text+0x20): undefined reference to `__LMM_lret'
    

    I've seen similar errors before, and it happened when some files had been compiled in lmm mode, other files were compiled in cmm mode, and then the two different files were linked against each other in the executable. I checked as carefully as I could though to be sure that all files were compiled with the correct code and, as far as I can tell, it's setting the correct mode.

    I've created two more branches based on development: dev_asm_hack and dev_link_hack. Your second suggestion and my attempt at implementing it is pushed to dev_asm_hack and your first suggestion will be implemented momentarily in dev_link_hack.

    I've decided to remove the "Debug" folder from project root and go with a non-eclipse-based build system. "make" can now be run directly from the project root and it will build the library in cmm, xmm, and lmm modes. common.mk includes the proper version based on what "model" is set to.

    Slowly but surely, I feel this project is going in the right direction... I'd love to see it get used by lots, but even if it doesn't, I'm certainly learning a lot by building this from the ground up! Thanks for all the help!
  • ersmithersmith Posts: 6,054
    edited 2013-12-08 04:58
    I'm getting undefined reference errors with your second suggestion. Namely:
    /home/david/External/Kits/Embedded/Parallax/Library/PropWare/lmm/libPropWare.a(spi_as.o): In function `_SPIStartCog':(.text+0x20): undefined reference to `__LMM_lret_ret'
    /home/david/External/Kits/Embedded/Parallax/Library/PropWare/lmm/libPropWare.a(spi_as.o): In function `_SPIStartCog':
    (.text+0x20): undefined reference to `__LMM_lret'
    
    Ah, that was a bug in the assembler's handling of the "lret" macro. It's been fixed in the Google code repository, but I'm not sure if it's made it to release yet. You can replace lret with something like:
    #ifdef __PROPELLER_CMM__
        lret
    #else
        mov pc, lr
    #endif
    
    I've seen similar errors before, and it happened when some files had been compiled in lmm mode, other files were compiled in cmm mode, and then the two different files were linked against each other in the executable.
    As I'm sure you know, mixing LMM and CMM will fail in all kinds of ways :-). I think the most recent linker should explicitly warn you about that.

    Eric
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-08 12:06
    /* mviw expands to a jmp followed by a 32 bit constant, just like fcache */  {"mviw", 0x5c000000, 0xffffffff, PROPELLER_OPERAND_MVI, CCZCNR, PROP_1_LMM, COMPRESS_MVIW, PREFIX_MVIW},
    
    LMM mode now works great. CMM mode is broken though, throwing an undefined reference on "mviw r7, #__load_start...". Based on how you simply replaced lret, I thought I'd do the same with this instruction but I don't know what this "32 bit constant" is that opc.c is referring to. Why would any instruction be followed up with -1?
  • jazzedjazzed Posts: 11,803
    edited 2013-12-08 14:25
    /* mviw expands to a jmp followed by a 32 bit constant, just like fcache */  {"mviw", 0x5c000000, 0xffffffff, PROPELLER_OPERAND_MVI, CCZCNR, PROP_1_LMM, COMPRESS_MVIW, PREFIX_MVIW},
    
    LMM mode now works great. CMM mode is broken though, throwing an undefined reference on "mviw r7, #__load_start...". Based on how you simply replaced lret, I thought I'd do the same with this instruction but I don't know what this "32 bit constant" is that opc.c is referring to. Why would any instruction be followed up with -1?

    All of your libraries are built with CMM mode or LMM mode and nothing is mixed?
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-08 15:37
    I had no idea that assembly needed to be built with a memory model. After adding -m$(MODEL) to the assembler flags, it's working now. I guess for cmm mode, it makes sense.
  • ersmithersmith Posts: 6,054
    edited 2013-12-08 16:30
    I had no idea that assembly needed to be built with a memory model. After adding -m$(MODEL) to the assembler flags, it's working now. I guess for cmm mode, it makes sense.

    Indeed, CMM mode uses its own instruction set (which is interpreted by the CMM kernel). The assembly language is very similar, because CMM allows any LMM instruction to be encoded, but the binary output of the assembler is completely different in CMM mode.

    Glad you got that sorted out!
  • DavidZemonDavidZemon Posts: 2,973
    edited 2013-12-08 18:36
    With the library now working, I've merged it into master and updated the documentation. I think it's much better than before, but I'm sure there's room for improvement. Suggestions welcome as always. http://david.zemon.name/professional/PropWare/docs/html/
Sign In or Register to comment.