Reputation: 41
Im working on a project about active power and reactive power measurement kit with using PIC16F877A MCU. In the code, I use pow, sqrt and cos functions which are included in math.h library. when I execute the code I get these errors.
CLEAN SUCCESSFUL (total time: 104ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/BATUHAN/Desktop/bitirme/bitirme.X'
make -f nbproject/Makefile-default.mk dist/default/production/bitirme.X.production.hex
make[2]: Entering directory 'C:/Users/BATUHAN/Desktop/bitirme/bitirme.X'
"D:\Program Files\Microchip\xc8\v2.32\bin\xc8-cc.exe" -mcpu=16F877A -c -mdfp="D:/Program Files/Microchip/MPLABX/v5.50/packs/Microchip/PIC16Fxxx_DFP/1.2.33/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx32 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -o build/default/production/main.p1 main.c
::: advisory: (2049) C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack; using C90 libraries
main.c:72:20: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
pf=cos(pf_timer);
~^~~~~~~~~~~~~
main.c:77:20: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
pf=cos(360 - pf_timer); //guc faktoru degeri
~^~~~~~~~~~~~~~~~~~~
main.c:87:20: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
pf=cos(pf_timer);
~^~~~~~~~~~~~~
main.c:92:20: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
pf=cos(360 - pf_timer); //guc faktoru degeri
~^~~~~~~~~~~~~~~~~~~
main.c:132:25: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
CRMS = CRMS + pow(((ADC_Value*5/1024 - 2.5)/0.185),2); //akimin karesi alinarak toplaniyor
~ ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:139:25: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
VRMS = VRMS + pow((((ADC_Value*5/1024)-2.5)*325),2); //gerilimin karesi alinarak toplaniyor
~ ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:147:24: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
CRMS = sqrt(CRMS); //ve kare koku alinarak rms akim degeri hesaplaniyor
~ ^~~~~~~~~~
main.c:149:24: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
VRMS = sqrt(VRMS); //ve kare koku alinarak rms voltaj degeri hesaplaniyor
~ ^~~~~~~~~~
8 warnings generated.
"D:\Program Files\Microchip\xc8\v2.32\bin\xc8-cc.exe" -mcpu=16F877A -Wl,-Map=dist/default/production/bitirme.X.production.map -DXPRJ_default=default -Wl,--defsym=__MPLAB_BUILD=1 -mdfp="D:/Program Files/Microchip/MPLABX/v5.50/packs/Microchip/PIC16Fxxx_DFP/1.2.33/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -msummary=-psect,-class,+mem,-hex,-file -ginhx32 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -Wl,--memorysummary,dist/default/production/memoryfile.xml -o dist/default/production/bitirme.X.production.elf build/default/production/main.p1
::: advisory: (2049) C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack; using C90 libraries
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\fleq.c:4:: advisory: (1510) non-reentrant function "___fleq" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\flge.c:4:: advisory: (1510) non-reentrant function "___flge" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\flneg.c:15:: advisory: (1510) non-reentrant function "___flneg" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\fltol.c:43:: advisory: (1510) non-reentrant function "___fltol" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\sprcadd.c:10:: advisory: (1510) non-reentrant function "___fladd" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\sprcadd.c:242:: advisory: (1510) non-reentrant function "___flsub" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\sprcdiv.c:8:: advisory: (1510) non-reentrant function "___fldiv" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\sprcmul.c:8:: advisory: (1510) non-reentrant function "___flmul" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\Umul8_16.c:4:: advisory: (1510) non-reentrant function "__Umul8_16" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\xxtofl.c:10:: advisory: (1510) non-reentrant function "___xxtofl" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\evalpoly.c:4:: advisory: (1510) non-reentrant function "_eval_poly" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\floor.c:13:: advisory: (1510) non-reentrant function "_floor" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\frexp.c:254:: advisory: (1510) non-reentrant function "_frexp" appears in multiple call graphs and has been duplicated by the compiler
D:\Program Files\Microchip\xc8\v2.32\pic\sources\c90\common\sprcdiv.c:185:: error: (1360) no space for auto/param _main$903
(908) exit status = 1
nbproject/Makefile-default.mk:138: recipe for target 'dist/default/production/bitirme.X.production.hex' failed
make[2]: Leaving directory 'C:/Users/BATUHAN/Desktop/bitirme/bitirme.X'
nbproject/Makefile-default.mk:91: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/BATUHAN/Desktop/bitirme/bitirme.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[2]: *** [dist/default/production/bitirme.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUİLD FAILED (exit value 2, total time: 5s)
THE CODE I WROTE
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = ON // Data EEPROM Memory Code Protection bit (Data EEPROM code-protected)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = ON // Flash Program Memory Code Protection bit (All program memory code-protected)
#define _XTAL_FREQ 20000000
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ADC_Current RA0
#define ADC_Volt RA1
#define VZCD RB0
#define CZCD RB4
float pf_timer=0;
float pf=0;
float ADC_Value = 0;
float CRMS, VRMS, Current, Volt = 0;
int Rms_Count=0;
float Q=0, P=0;
_Bool timer_bit=0;
_Bool counter_bit=0;
_Bool pf_bit=1;
_Bool LEAD_LAG=0;
void __interrupt() KESME(void)
{
//TMR1 KESMESI
if(TMR1IF)
{
TMR1IF=0;
TMR1=15535;
timer_bit = timer_bit^1;
}
//INT (RB0) KESMESI
if(INTF)
{
INTF=0;
pf_bit=1;
pf_timer = TMR1;
}
//PORTB KESMESI
if(RBIF==1 && RB4==1 && pf_bit==1)
{
RBIF=0;
pf_bit=0;
if(TMR1 >= pf_timer)
{
pf_timer = TMR1 - pf_timer;
pf_timer = pf_timer*360/50000;
if(pf_timer <= 90)
{
pf=cos(pf_timer);
LEAD_LAG=0;
}
else if(pf_timer >= 270)
{
pf=cos(360 - pf_timer);
LEAD_LAG=1;
}
}
else if(TMR1 < pf_timer)
{
pf_timer =65535 - pf_timer + TMR1;
pf_timer = pf_timer*360/50000;
if(pf_timer <= 90)
{
pf=cos(pf_timer);
LEAD_LAG=0;
}
else if(pf_timer >= 270)
{
pf=cos(360 - pf_timer);
LEAD_LAG=1;
}
}
}
}
void main(void)
{
TRISA = 0XFF;
PORTA = 0X00;
TRISB = 0XFF;
PORTB = 0X00;
//ADC KONFIGURASYON BITLERI
ADCON0=0b01000001;
ADCON1=0b10000000;
//TIMER-1 KONFIGURASYON BITLERI
TMR1=15535;
INTCON=0b11011000;
INTEDG=1;
T1CON=0b00011110;
TMR1IE=1;
TMR1IF=0;
TMR1ON=1;
while(1)
{
//AKIM VE GERILIM OLCUMU
if(timer_bit)
{
counter_bit=0;
Rms_Count += 1;
ADCON0bits.CHS0=0;
GO_DONE = 1;
while(GO_DONE);
ADC_Value = (ADRESH*256 + ADRESL);
CRMS = CRMS + pow(((ADC_Value*5/1024 - 2.5)/0.185),2);
ADCON0bits.CHS0=1;
GO_DONE = 1;
while(GO_DONE);
ADC_Value = (ADRESH*256 + ADRESL);
VRMS = VRMS + pow((((ADC_Value*5/1024)-2.5)*325),2);
}
else if(!timer_bit)
{
if(!counter_bit)
{
CRMS = CRMS / Rms_Count;
CRMS = sqrt(CRMS);
VRMS = VRMS / Rms_Count;
VRMS = sqrt(VRMS);
Volt = VRMS;
Current = CRMS;
}
counter_bit=1;
CRMS=0;
Rms_Count=0;
VRMS=0;
}
}
return;
}
I tried switch to C90 standarts and nothing changed. How can I solve this problem.
Upvotes: 1
Views: 865
Reputation: 2592
TL;DR Basically you're out of memory. Compiled code doesn't fit into your uCs memory.
The main problem is that the cos()
function you're using the interrupt is duplicated by the compiler because it appears both in main code and the interrupt, and your uC supports only compiled stack model which doesn't support function reentrancy.
Unfortunately it doesn't end here. It appears that cos()
calls other library functions, like a chain reaction. These are all floating point functions, which have high memory footprints. And now these heavy floating point functions (which are many) are also duplicated, and they don't fit into the memory of your uC. This can be either RAM or Flash memory shortage, or both.
Try to remove cos()
(or any other floating point function) from your ISR by changing your program logic.
Warnings are not directly related with your compile error. You may go to project properties menu in MPLAB. Here you will see Link in C Library option under XC8 Global Options -> XC8 Linker -> Runtime. Select C90 instead of C99. You may also try using floating point version of the library functions, like using cosf()
instead of cos()
, but these may not be available on C90. Or you can manually cast to float to get rid of warnings.
Upvotes: 0
Reputation: 2520
Well, it looks like there is not much and clear information on what libraries the XC8 compiler supports specifically for the mid-range devices. The only brief information I could find in Microchip Developer Help site it is mentioned that:
Ensure that you are also using the C99 libraries as shown in the following figure, but note that currently, C99 compliant libraries are only available for projects targeting PIC18 devices and targeting Enhanced Mid-range devices that are using the compiled (non-reentrant) stack model.
However as the advisory states:
C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack
Considering this advise, it sholdn't be used neither baseline nor mid-range nor enhanced mid-range devices for the projects that use C99 compliant libraries as in your case. Baseline, mid-range and enhanced mid-range devices are any of those whose name starts with PIC10, PIC12* and PIC16 prefixes respectively.
So the road to take for your situation is to pick an advanced model of 8-bit PIC controllers, any model that starts with PIC18 prefix in its name should work. However I would recommend you relatively newer products. For example, instead of buying a PIC18F4550 which is relatively old, you can buy a PIC18F45K50 which is newer than it and may have some enhancements.
Now let me answer your other questions you asked in the comments:
Which PIC18F do you recommend to do enough for my project. In the circuitry there are 4-5 I/O pins and I will add a 2x16 LCD.
Well for this kind of requirement a model like PIC18F14K50 should do the job for your project since it has 20 pins. Or you can go with a 25K20 or a 25K22 both of which have 28 pins which would suffice for your requirement.
if I put the source codes of cos() and sqrt() functions and remove the
#include <math.h>
, will I still have the same architectural problem.
I am not sure for that since the problem here is the usage of reentrant or software stack which is a type of dynamically allocated memory for functions. Knowing this, I can say that if those functions are compiled with software stack model by XC8 then it will not work for PIC16F877A at all. As a matter of fact I see a conflict between the advisory of compiler and the quoted explanation from Microchip developer site regarding the usage of reentrant stack model. The advise of the compiler is kind of unclear on whether the reentrant stack model can be used with the enhanced mid-range devices, while in the developer site it stated kind of contrary. This encourages us to see the Compiled Stack and the Software stack definitions in the XC8 compiler manual.
Compiled Stack (Reentrant)
A compiled stack is one or more areas of memory that are designated for automatic storage duration objects. Objects allocated space in the compiled stack are assigned a static address which can be accessed via a compiler-allocated symbol. This is the most efficient way of accessing stack-based objects, since it does not use a stack pointer.
Software Stack (Non-reentrant)
A software stack is a dynamic allocation of memory that is used for automatic storage duration objects and which is indirectly accessed via a stack pointer. Although access of objects on a software stack can be slower, functions which use a software stack are reentrant. This form of stack is available only for Enhanced Mid-range and PIC18 devices.
Which clearly states that reentrant functions are only available for enhanced mid-range and PIC18 devices.
Finally if you can avoid using the same functions both in the main and in the interrupt, perhaps you can go with your PIC16F877A and compiler compiles your code with compiled stack model. Because the compiler duplicate the functions when they are used in both main and interrupt and this triggers the compilation of reentrant function stack model.
Upvotes: 0