Jump to content
Sign in to follow this  
TomF

Calling Code In A Different Module Fails

Recommended Posts

Hi,

 

In main.c and comms.c i have 2 functions that contain the exact same code. The functions are called "local()" in main.c, and "not_local" in comms.c

 

The code here sets a global var 'g_count' defined in comms.h to 4, then enables interrupts that decrement the variable until it reaches zero.

local() and not_local() wait for the variable to reach zero and return.

 

not_local() never returns, which is strange.

 

main.c

#include <system.h>
#include "comms.h"

//
// DEVICE:	PIC16F1826
// WDT:		Off.
//

#pragma CLOCK_FREQ 18432000		// 18.432 MHz

#pragma DATA _CONFIG1,	_FOSC_HS & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_ON & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF 
#pragma DATA _CONFIG2,	_WRT_ALL & _PLLEN_OFF & _STVREN_ON & _BORV_25 & _LVP_OFF

void local()
{
g_Count = 4;

set_bit(pie1, TXIE);

while(g_Count)
{
	toggle_bit(portb, 0);
	delay_us(100);
}
}

void interrupt()
{
if( test_bit(pie1, TXIE) && test_bit(pir1, TXIF) )
{
	if( g_Count )
	{
		g_Count--;
	}

	if( !g_Count )
	{
		clear_bit(pie1, TXIE);
	}
}
}

void Init()
{
porta = 0b00100011;
trisa = 0b11100100;

portb = 0b00000000;
trisb = 0b00100010;

ansela = 0;												// Digital IO
anselb = 0;												// Digital IO

wpua = 0;
wpub = 0;

// Config serial port.
clear_bit(txsta, SYNC);									// Choose async comms.
set_bit(rcsta, SPEN);									// Enable serial port (this doesnt turn on transmitter)
set_bit(intcon, PEIE);									// Enable periferal interrupts for serial port.
set_bit(txsta, TXEN);									// Enable the transmitter (will interrupt at once).
pir1 = 0x00;											// Clear all periferial pending interrupts.
set_bit(intcon, GIE);									// Globally enable interrupts.
set_bit(txsta, BRGH);									// Use 8-bit high-speed baud rates.
spbrgl = 19;											// 57600
}

void main()
{
Init();

for(;;)
{
	local();
	not_local();
}
}

 

comms.h
#ifndef __COMMS_H__
#define __COMMS_H__

static volatile unsigned char g_Count;

void not_local();

#endif



comms.c

#include <system.h>

#include "comms.h"

void not_local()
{
g_Count = 4;

set_bit(pie1, TXIE);

// This while loop never exits.
while(g_Count)
{
	toggle_bit(portb, 0);
	delay_us(100);
}
}

 

Any ideas why this happens? Is it a compiler bug?

Edited by TomF

Share this post


Link to post
Share on other sites

Ah ha!

the compiler is creating 2 different variables for g_Count, see this assembly codee:

 

gbl_13_g_Count				   EQU	0x00000020; bytes:1
gbl_14_g_Count				   EQU	0x00000021; bytes:1

:
:

ORG 0x0000000C
not_local_00000
; { not_local; function begin
MOVLW 0x04
MOVLB 0x00
MOVWF gbl_14_g_Count
MOVLB 0x01
BSF gbl_pie1,4
label2
MOVLB 0x00
MOVF gbl_14_g_Count, F
BTFSC STATUS,Z
RETURN
MOVLW 0x01
XORWF gbl_portb, F
MOVLW 0x64
MOVWF delay_us_00000_arg_del
CALL delay_us_00000
GOTO	label2
; } not_local function end

ORG 0x0000001B
local_00000
; { local; function begin
MOVLW 0x04
MOVLB 0x00
MOVWF gbl_13_g_Count
MOVLB 0x01
BSF gbl_pie1,4
label3
MOVLB 0x00
MOVF gbl_13_g_Count, F
BTFSC STATUS,Z
RETURN
MOVLW 0x01
XORWF gbl_portb, F
MOVLW 0x64
MOVWF delay_us_00000_arg_del
CALL delay_us_00000
GOTO	label3
; } local function end

 

local() operates on 'gbl_13_g_Count', whereas 'not_local()' operates on 'gbl_14_g_Count'

 

Im totally confused.

Share this post


Link to post
Share on other sites
Ah ha!

the compiler is creating 2 different variables for g_Count, see this assembly codee:

 

And that's exactly what your code instructs compiler to do. You declare variable in a header file and than include this header into multiple sources. Result will be o copy of this variable declared in every source file.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

Hi Pavel,

 

Thats not what i want.

 

I would like a global variable, e.g. only one variable, not 2 variables. Multiple sources need to access ONE variable.

 

What am i doing wrong?

Edited by TomF

Share this post


Link to post
Share on other sites

TomF,

 

I would like a global variable, e.g. only one variable, not 2 variables. Multiple sources need to access ONE variable.

 

What am i doing wrong?

Using the static keyword in a variable declaration makes that declaration private to the source code file code in which it appears.

 

For what you want to do:

1) declare you global var in once of your source files without the static keyword.

2) declare the variable again in the header file with the prefix "extern".

 

Then it should work as you want.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Thanks for that, yes, that worked. :P I hate global vars, and as you can see, i dont ever use them, but this time, i have to!

 

If the static keyword hides the variable, why does the compiler not complain that g_Count is undefined in main.c? Instead, the compiler creates a random variable and uses it.

Edited by TomF

Share this post


Link to post
Share on other sites

TomF,

...

If the static keyword hides the variable, why does the compiler not complain that g_Count is undefined in main.c? Instead, the compiler creates a random variable and uses it.

The variable is no random at all.

Each time you include your "comms.h" file in another source file you get another private instance of the static variable declare in the header file.

This is all perfectly valid and works just like other C compilers.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Hi Dave.

 

the lines:

 

#ifndef __COMMS_H__

#define __COMMS_H__

 

i thought were to stop a new instance being created when included, and the static keyword on a variable means private to the module? If thats the case, then creating a copy is incorrect and the compiler should complain that it cannot find the variable (becuase its static).

 

Im not usre what other compilers do as i dont have time to try this in HiTide

 

 

Im still not convinced that by including something you are creating a new instance, you are simply making the code visable to the file that included it, right?

 

<confused>

Share this post


Link to post
Share on other sites

TomF,

Im still not convinced that by including something you are creating a new instance, you are simply making the code visable to the file that included it, right?
If you include a file it is the same as all that code in the included file being in that file.

 

This:

#ifndef __COMMS_H__

#define __COMMS_H__

only prevent multiple inclusions in the same source file (can happen when some source include files include other files), each source file is handled individually, they have no knowledge of what other source files have included.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...