When viewing .c files in MPLAB X V5.25 w/ XC8 V2.05, all of my register definitions have squiggly lines under them. I'm using Linux Mint 19. How can create a file path or where can I find the 4809.h file?
When viewing .c files in MPLAB X V5.25 w/ XC8 V2.05, all of my register definitions have squiggly lines under them. I'm using Linux Mint 19. How can create a file path or where can I find the 4809.h file?
>it's only the IDE that is unhappy with the symbols
It hasn't been happy for years.
So I tracked this down, since it was damnably inconsistent.
1) Chip-specific symbols (like USART_CHSIZE_gm )
There are actually two problems here:
- In order to support added-on "Packs", avr/io.h has a catch-all rule to find the right include file:
#elif defined (__AVR_ATtiny11__)
# include <avr/iotn11.h>
#elif defined (__AVR_M3000__)
# include <avr/iom3000.h>
#elif defined (__AVR_DEV_LIB_NAME__)
# define __concat__(a,b) a##b
# define __header1__(a,b) __concat__(a,b)
# define __AVR_DEVICE_HEADER__ <avr/__header1__(io,__AVR_DEV_LIB_NAME__).h>
# include __AVR_DEVICE_HEADER__
#else
# if !defined(__COMPILING_AVR_LIBC__)
# warning "device type not defined"This is apparently (and not surprisingly) not understood by whatever logic parses the source in the editor.
If you edit the source of io.h to add:
#elif defined (__AVR_ATmega4809__) # include <avr/iom4809.h>in an appropriate place, it will get happier (after you convince it to reparse everything.)
At least, if you're using avr-gcc. If you're using xc8, there's an additional problem. The compile command is something like:
"/Applications/microchip/xc8/v2.05/bin/xc8-cc" -mcpu=ATmega4809 -c -x c -D__ATmega4809__ -mdfp="/Applications/microchip/mplabx/v5.25/packs/Microchip/ATmega_DFP/2.0.12" -Wl,--gc-sections -Os ... main.c
Which works fine, but the IDE doesn't recognize -mdfp switch as creating a new include path, so when io.h ends up doing the #include <avr/iom4809.h> the IDE doesn't find it, so it can't see the 4809-specific defines. Adding an explict include path for the pack include directory fixes it (as does copying the .h to the "normal" avr directory.)
Grr. So - understood, might have workarounds, might be fixable...
The uint8_t issue is somewhat similar. It's not a problem using avr-gcc, but using xc8, the stdint.h file that gets included in a wrapper that the IDE parser doesn't seem to deal with very well:
#if __STDC_HOSTED__
:
# include_next <stdint.h>
#else
# include "stdint-gcc.h"
#endif
Perhaps it doesn't understand "include_next"?
I just tried this:
#if defined (__AVR_ATmega4809__) #include <avr/iom4809.h>
...and I'm not allowed to edit the io.h file.
Also, where can I find the iom4809.h file? I want to open it and see what is going on inside it.
For me using avr-gcc v8 for atmega4809 the critical flag is "-mmcu=atmega4809". That provides flag to pull in the appropriate device-specs file which makes the right definition for io.h (namely "-D__AVR_DEV_LIB_NAME__=m4809"). I am using gcc8 via command line on linux, though, not MPLAB.
For me using avr-gcc v8 for atmega4809 the critical flag is "-mmcu=atmega4809". That provides flag to pull in the appropriate device-specs file which makes the right definition for io.h (namely "-D__AVR_DEV_LIB_NAME__=m4809"). I am using gcc8 via command line on linux, though, not MPLAB.
I just switched to GCC and put this at the top of my main.c file.
#define __AVR_DEV_LIB_NAME__ m4809
#include <avr/io.h>
Problem solved.
Problem solved.
See also: "how to install packs in the default places in the AVR CLI Toolchain, so you don't need to clutter your command line with system-dependent pointers to the packs directories": https://www.avrfreaks.net/comment/2526416#comment-2526416
DaveHardy wrote:I think you mean "part of the problem solved". How's your linking to the CRT and lc, lm, lgcc etc going?Problem solved.
I don't even know what those are. Are those Windows acronyms? I'm on Linux Mint 19 here and can't figure out how to change my signature. How do I learn all of these darn acronyms?
My point was that the intended way to use "device packs" is to invoke avr-gcc with a -B option to tell it where the device pack is. That reads a file that will define __AVR_DEV_LIB_NAME__ but that same file does about 10 other things which you won't be doing by just adding a #define to a source file so I wondered if the missing bits had bitten you yet like it not being able to find the C libs for the device or the C run time (CRT) etc.
For example, on this Windows machine with AS7 if I build for 4809 the command the IDE gives to invoke the compiler (and linker) is:
Compile:::
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -x c -funsigned-char -funsigned-bitfields -DDEBUG
-I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.3.300\include" -Os -ffunction-sections -fdata-sections -fpack-struct
-fshort-enums -g2 -Wall -pedantic -mmcu=atmega4809 -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.3.300\gcc\dev\atmega4809"
-c -std=gnu99 -H -save-temps -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" ".././main.c"
Link:::
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-g++.exe" -o test.elf main.o -Wl,-Map="test.map" -Wl,--start-group -Wl,-lm -Wl,--end-group
-mmcu=atmega4809 -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.3.300\gcc\dev\atmega4809" -Wl,-print-gc-sections
If you look at the -B location you see:
C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATmega_DFP\1.3.300\gcc\dev\atmega4809>tree /f Folder PATH listing for volume OSDISK Volume serial number is 7AF3-B2D0 C:. ├───avrxmega3 │ crtatmega4809.o │ libatmega4809.a │ └───device-specs specs-atmega4809
Of particular interest is that specs-4809 file which contains:
C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATmega_DFP\1.3.300\gcc\dev\atmega4809\device-specs>type specs-atmega4809 # # Auto-generated specs for AVR device atmega4809 (core avrxmega3, 16-bit SP) # # Generated by : ./gcc/config/avr/gen-avr-mmcu-specs.c # Generated from : ./gcc/config/gcc.c # ./gcc/config/avr/specs.h # ./gcc/config/avr/avrlibc.h # Used by : avr-gcc compiler driver # Used for : building command options for sub-processes # # See <https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html> # for a documentation of spec files. # If you intend to use an existing device specs file as a starting point # for a new device spec file, make sure you are copying from a specs # file for a device from the same core architecture and SP width. # See <https://gcc.gnu.org/gcc-5/changes.html> for a description # of how to use such own spec files. *avrlibc_startfile: crtatmega4809.o%s *avrlibc_devicelib: %{!nodevicelib:-latmega4809} *cc1_n_flash: %{!mn-flash=*:-mn-flash=1} *cc1_rmw: %{mrmw} *cc1_errata_skip: %{!mskip-bug: -mno-skip-bug} *cc1_absdata: %{mabsdata} *asm_arch: -mmcu=avrxmega3 *asm_relax: %{mrelax:--mlink-relax} *asm_rmw: %{mrmw} *asm_errata_skip: %{!mskip-bug: -mno-skip-bug} *link_pmem_wrap: *link_relax: %{mrelax:--relax} *link_arch: %{mmcu=*:-m%*} *link_data_start: -Tdata 0x802800 *link_text_start: *self_spec: %{!mmcu=avr*: %<mmcu=* -mmcu=avrxmega3} %<mshort-calls %<msp8 # AVR-LibC's avr/io.h uses the device specifying macro to determine # the name of the device header. For example, -mmcu=atmega8a triggers # the definition of __AVR_ATmega8A__ and avr/io.h includes the device # header 'iom8a.h' by means of: # # ... # #elif defined (__AVR_ATmega8A__) # # include <avr/iom8a.h> # #elif ... # # If no device macro is defined, AVR-LibC uses __AVR_DEV_LIB_NAME__ # as fallback to determine the name of the device header as # # "avr/io" + __AVR_DEV_LIB_NAME__ + ".h" # # If you provide your own specs file for a device not yet known to # AVR-LibC, you can now define the hook macro __AVR_DEV_LIB_NAME__ # as needed so that # # #include <avr/io.h> # # will include the desired device header. For ATmega8A the supplement # to *cpp would read # # -D__AVR_DEV_LIB_NAME__=m8a *cpp: -D__AVR_ATmega4809__ -D__AVR_DEVICE_NAME__=atmega4809 -D__AVR_DEV_LIB_NAME__=m4809 %rename link old_link *link: %(old_link)--defsym=__RODATA_PM_OFFSET__=0x4000 # End of file
Within that you will see the
-D__AVR_DEV_LIB_NAME__=m4809
which is the equivalent of what you are doing but as you'll also see there is other stuff involved too and your simplistic solution is not doing this.
So I would suggest you get the packs and that will include the specs-4809 file and then use -B on the compiler/linker command lines to tell the tools where to find it and then it can read specs-4809 as intended.
So I would suggest you get the packs and that will include the specs-4809 file and then use -B on the compiler/linker command lines to tell the tools where to find it and then it can read specs-4809 as intended.
Thanks a lot for pointing me in the right direction. Just to clarify, a virtual terminal is the same thing as a CLI? You're compiling your projects with a terminal? There's a window at the bottom of MPLAB X that executes shell commands for me. I can see the -B you are referring to, but can't wrap my head around why it isn't linking or how to set it up. MPLAB X says I have DFP 1.3.300 installed for the megas. This is the output I get from the bottom window of MPLAB X when I build and clean a project. Any help is appreciated.
CLEAN SUCCESSFUL (total time: 51ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory '/home/dave/MPLABXProjects/SPI.X'
make -f nbproject/Makefile-default.mk dist/default/production/SPI.X.production.hex
make[2]: Entering directory '/home/dave/MPLABXProjects/SPI.X'
"/opt/microchip/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc" -mmcu=atmega4809 -I "/opt/microchip/mplabx/v5.25/packs/Microchip/ATmega_DFP/2.0.12"/include -B "/opt/microchip/mplabx/v5.25/packs/Microchip/ATmega_DFP/2.0.12"/gcc/dev/atmega4809 -x c -c -D__ATmega4809__ -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "build/default/production/spimain.o.d" -MT "build/default/production/spimain.o.d" -MT build/default/production/spimain.o -o build/default/production/spimain.o spimain.c -DXPRJ_default=default
"/opt/microchip/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc" -mmcu=atmega4809 -I "/opt/microchip/mplabx/v5.25/packs/Microchip/ATmega_DFP/2.0.12"/include -B "/opt/microchip/mplabx/v5.25/packs/Microchip/ATmega_DFP/2.0.12"/gcc/dev/atmega4809 -x c -c -D__ATmega4809__ -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "build/default/production/spi.o.d" -MT "build/default/production/spi.o.d" -MT build/default/production/spi.o -o build/default/production/spi.o spi.c -DXPRJ_default=default
"/opt/microchip/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc" -mmcu=atmega4809 -B "/opt/microchip/mplabx/v5.25/packs/Microchip/ATmega_DFP/2.0.12"/gcc/dev/atmega4809 -D__ATmega4809__ -Wl,-Map="dist/default/production/SPI.X.production.map" -o dist/default/production/SPI.X.production.elf build/default/production/spi.o build/default/production/spimain.o -DXPRJ_default=default -Wl,--defsym=__MPLAB_BUILD=1 -Wl,--gc-sections -Wl,--start-group -Wl,-lm -Wl,--end-group
"/opt/microchip/avr8-gnu-toolchain-linux_x86_64/bin"/avr-objcopy -O ihex "dist/default/production/SPI.X.production.elf" "dist/default/production/SPI.X.production.hex"
make[2]: Leaving directory '/home/dave/MPLABXProjects/SPI.X'
make[1]: Leaving directory '/home/dave/MPLABXProjects/SPI.X'
BUILD SUCCESSFUL (total time: 54ms)
Loading code from /home/dave/MPLABXProjects/SPI.X/dist/default/production/SPI.X.production.hex...
Loading completed
But that is already doing the packs/-B thing anyway so it should just have worked without intervention on your part. Wonder if the packs are up to date?