XC8 pconfig.h not selecting chip - c

I am working with XC8 1.20 and a PIC18F66K80 and having some trouble with using the pwm.h library. Whenever I open pwm.h, the only functions that are actually being generated (IE, the #ifdef compile time conditionals are returning true) are for PWM1. After tracing through the code, I came to the pconfig.h file and went down to the section regarding the 18F66K80, and it was all being ignored.
The conditional that was returning false is:
#ifdef __18F66K80
In fact, there were no sections that were being compiled. It was like I had no chip selected, even though the project was targeting the 18F66K80. I went into the compiler macro options and add __18F66K80 as a defined macro, and this block suddenly was compiling, giving me access to PWM2-5.
My question is - what is the correct way to tell pconfig.h what chip I am using? My project settings clearly show the PIC18F66K80 as the target device, but pconfig.h was acting like I had no chosen device. By adding this macro, it appears to work, but I have a feeling this is a hack and not the right way to do things.

Related

Compiling Error with interrupt service routines for ATtiny using xc8

I am working on a project using an ATtiny 202 and I am nearly done with my programming, but I have run into a large problem. I can't create any ISRs, because I always get a compiler error.
I am using the newest version of MPLABX IDE (5.35) (yes it is for pic and avr mcus) and the second newest version of the xc8 compiler (v2.10). I cannot use the newest version of the compiler, because that is for some reason missing the device header for the ATtiny 202. (I had a different thread about that problem a while ago)
I have created the ISRs exactly like described in the XC8 Manual, and the IDE doesn't mark it as a problem either, but when I then try to compile the program I always get a compiler error.
Here is one of my ISRs:
void __interrupt (RTC_PIT_vect_num) pit_int(void){
onPIT(); //Run the function
RTC.PITINTFLAGS = 0x0; //and clear the interrupt flags
}
The IDE marks the RTC_PIT_vect_num blue and correctly recognizes it, as it is defined in the device header.
When I try to compile it, I get this error message, and the build fails:
main.c:864:19: error: expected declaration specifiers or '...' before numeric constant
void __interrupt (RTC_PIT_vect_num) pit_int(void){
^
I dont know what exactly the problem is and how to solve it.
For comparison, here is an example from the "XC8 User Guide for AVR", page 83:
void __interrupt(SPI_STC_vect_num) spi_Isr(void) {
process(SPI_SlaveReceive());
return;
}
As you can see, the structure of the function is exactly the same as in my own ISR.
Does someone have an idea what the problem is or may be and how to fix it?
Fixed:
I had posted this question on the microchip forum as well, as no one here seemed to be able to help.
So I figured out that the problem was that in the project properties under
XC8 Global Options -> XC8 Compiler -> Option categories: Preprocessing and messages
the option "Use CCI Syntax" was disabled. This needs to be enabled for the __interrupt to work.

Qt Creator ClangCodeModel can't parse or autocomplete conditional nested includes?

I'm starting an embedded AVR project in C with QtCreator.
I believe I have everything setup and working correctly; I can write code that #include's headers from avr-libc, build with a custom makefile, and the binary is automatically flashed onto the chip for me. Unfortunately, even though my code compiles without any warnings from avr-gcc, QtCreator's ClangCodeModel plugin does not recognize a subset of the #define'd port and register names--it claims that there are errors, and autocompletion does not work.
I think I've identified the problem:
The boilerplate #include in avr projects is #include <avr/io.h>. io.h itself #include's a number of other headers unconditionally, no-matter-what, such as headers that define register names common to all AVR devices. And code completion does work correctly with the names defined in those headers. However, it also conditionally includes one other header based on which specific AVR device you are targetting. There are many hundreds of AVR devices out there, each one having its own header file that defines port and register names. io.h determines which one to include like this:
#if defined (__AVR_AT94K__)
# include <avr/ioat94k.h>
#elif defined (__AVR_AT43USB320__)
# include <avr/io43u32x.h>
#elif defined (__AVR_AT43USB355__)
# include <avr/io43u35x.h>
#elif defined (__AVR_AT76C711__)
# include <avr/io76c711.h>
.
.
.
and so on. I reason that the correct header must actually be included since compiling throws no errors, even though ClangCodeModel does show error tags. By that I mean, I can write code that references a device-specific register name and compile without problems, but ClangCodeModel does not recognize that register name.
EDIT: Note that if I actually directly #include <avr/iom328p.h> at the top of main.c, ClangCodeModel parses the header just fine and autocompletion works. Unfortunately, I can't actually leave it like that. From <avr/io.h>:
This header file includes the apropriate IO definitions for the
device that has been specified by the -mmcu= compiler
command-line switch. This is done by diverting to the appropriate
file <avr/ioXXXX.h> which should
never be included directly. Some register names common to all
AVR devices are defined directly within <avr/common.h>,
which is included in <avr/io.h>,
but most of the details come from the respective include file.
and from <avr/iom328p.h>:
/* This file should only be included from <avr/io.h>, never directly. */
From the ClangCodeModel documentation:
The feedback you get through warning and error markers is the same as
a compiler will give you, not an incomplete set or a close
approximation, as when using the built-in Qt Creator code model.
That doesn't seem to be the case. To me, that claim implies ClangCodeModel would go ahead and evaluate the #if defined (__MY_AVR__), and parse the correct device-specific header, which isn't happening here.
It is essential to me that code completion works since embedded projects require typing esoteric register and port name macros all day long.
What am I missing?
makefile, and the makefile referenced at the bottom include.
The general <avr/io.h>.
The device-specific header <avr/iom328p.h> which has all the names I need, and ClangCodeModel is failing to parse.
Contents of QtCreator's MyProjectName.includes (I added these lines manually).
You should add
#define __AVR_ATmega328__
to your MyProjectName.config file.
QtCreator's code model cannot get all compiler defines, because your Makefile is not generated by qmake, cmake, or qbs.

How do you include standard CUDA libraries to link with NVRTC code?

Specifically, my issue is that I have CUDA code that needs <curand_kernel.h> to run. This isn't included by default in NVRTC. Presumably then when creating the program context (i.e. the call to nvrtcCreateProgram), I have to send in the name of the file (curand_kernel.h) and also the source code of curand_kernel.h? I feel like I shouldn't have to do that.
It's hard to tell; I haven't managed to find an example from NVIDIA of someone needing standard CUDA files like this as a source, so I really don't understand what the syntax is. Some issues: curand_kernel.h also has includes... Do I have to do the same for each of these? I am not even sure the NVRTC compiler will even run correctly on curand_kernel.h, because there are some language features it doesn't support, aren't there?
Next: if you've sent in the source code of a header file to nvrtcCreateProgram, do I still have to #include it in the code to be executed / will it cause an error if I do so?
A link to example code that does this or something like it would be appreciated much more than a straightforward answer; I really haven't managed to find any.
You have to send the "filename" and the source of each header separately.
When the preprocessor does its thing, it'll use any #include filenames as a key to find the source for the header, based on the collection that you provide.
I suspect that, in this case, the compiler (driver) doesn't have file system access, so you have to give it the source in much the same way that you would for shader includes in OpenGL.
So:
Include your header's name when calling nvrtcCreateProgram. The compiler will, internally, generate the equivalent of a std::map<string,string> containing the source of each header indexed by the given name.
In your kernel source, use #include "foo.cuh" as usual.
The compiler will use foo.cuh as an index or key into its internal map (created when you called nvrtcCreateProgram), and will retrieve the header source from that collection
Compilation proceeds as normal.
One of the reasons that nvrtc provides only a "subset" of features is that the compiler plays in a somewhat sandboxed environment, without necessarily having all of the supporting tools and utilities lying around that you have with offline compilation. So, you have to manually handle a lot of the stuff that the normal nvcc + (gcc | MSVC| clang) combination provides.
A possible, but non-ideal, solution would be to preprocess the file that you need in your IDE, save the result and then #include that. However, I bet there is a better way to do that. if you just want curand, consider diving into the library and extracting the part you need (blech) or using another GPU-friendly rand implementation. On older CUDA versions, I just generated a big array of random floats on the host, uploaded it to the GPU, and sampled it in the kernels.
This related link may be helpful.
You do not need to load curand_kernel.h yourself and add it to the include "aliases" mechanism.
Instead, you can simply add the CUDA include directory to your (set of) include paths, e.g. by adding --include-path=/usr/local/cuda/include to your NVRTC compiler options.
(I do this in my GPU-kernel-runner test harness, by default, to be on the safe side.)

Compile-time test if function is optimized out

I'm writing a small operating system for microcontrollers in C (not C++, so I can't use templates). It makes heavy use of some gcc features, one of the most important being the removal of unused code. The OS doesn't load anything at runtime; the user's program and the OS source are compiled together to form a single binary.
This design allows gcc to include only the OS functions that the program actually uses. So if the program never uses i2c or USB, support for those won't be included in the binary.
The problem is when I want to include optional support for those features without introducing a dependency. For example, a debug console should provide functions to debug i2c if it's being used, but including the debug console shouldn't also pull in i2c if the program isn't using it.
The methods that come to mind to achieve this aren't ideal:
Have the user explicitly enable the modules they need (using #define), and use #if to only include support for them in the debug console if enabled. I don't like this method, because currently the user doesn't have to do this, and I'd prefer to keep it that way.
Have the modules register function pointers with the debug module at startup. This isn't ideal, because it adds some runtime overhead and means the debug code is split up over several files.
Do the same as above, but using weak symbols instead of pointers. But I'm still not sure how to actually accomplish this.
Do a compile-time test in the debug code, like:
if(i2cInit is used) {
debugShowi2cStatus();
}
The last method seems ideal, but is it possible?
This seems like an interesting problem. Here's an idea, although it's not perfect:
Two-pass compile.
What you can do is first, compile the program with a flag like FINDING_DEPENDENCIES=1. Surround all the dependency checks with #ifs for this (I'm assuming you're not as concerned about adding extra ifs there.)
Then, when the compile is done (without any optional features), use nm or similar to detect the usage of functions/features in the program (such as i2cInit), and format this information into a .h file.
#ifndef FINDING_DEPENDENCIES
#include "dependency_info.h"
#endif
Now the optional dependencies are known.
This still doesn't seem like a perfect solution, but ultimately, it's mostly a chicken-and-the-egg problem. When compiling, the compiler doesn't know what symbols are going to be gc'd out. You basically need to get this information from the linker stage and feed it back to the compilation stage.
Theoretically, this might not increase build times much, especially if you used a temp file for the generated h, and then only replaced it if it was different. You'd need to use different object dirs, though.
Also this might help (pre-strip, of course):
How can I view function names and parameters contained in an ELF file?

System calls not working in Atmel AVR Studio (with ASF)

I am not getting answers on the AVR Freaks forum and wonder if someone here could help me.
The answer might lie in this SO question, but I am not sure why it would be necessary.
Basically, I have my fist ever Atmel project (AVR studio 6, UC3 processor). The code compiles and links and I can load it to the Atmel board and step through in the debugger.
However, when I try to step over (or run until a breakpoint on the line after) a (valid) call to sprintf(), malloc() or memcpy() (there may be more, which I have not yet discovered), the IDE never returns to the next line of my code, just seeming to hang, or run forever.
[Note] Compiler optimization is off
Do I need to set some linker options (e.g link static (which I tried & it didn't help)? Or build with some library?
What confuses me is that the code compilers and links - what is being linked when I call these standard functions? If I need something else I would expect a compiler or linker error, but get none - so why won't my code run?
Sorry for such a stupid n00nb question, but it is my first micro-controller project.
I discovered that the CPU on my board is an Engineering Sample and not supported by Atmel Studio without a new io.h file.
I sort of figured that out from this question: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=106652
Sorry to have troubled you.
what is being linked when I call these standard functions?
The AVR-libc, the implementation of the C standard library ported to the AVR platform.
so why won't my code run?
Compiler errors and runtime errors are not even related. Both of these lines are valid C and they compile, however, on most systems, I'd expect them to dump core:
int x = 1 / 0;
*(int *)0 = 41;
So it might be either:
a bug in the standard library (very unlikely), or
a bug in the online debugger (very unlikely), or
maybe you just expect something that is not supposed to happen?
Instead of trying to step over, what happens if you set a breakpoint at next line after the line you want to step over?
Also, does the operation change if you turn off compiler optimization?

Resources