Hi,
thanks for the tip:
I did the following quick comparison:
int global_var;
typedef struct {
int x;
} structx;
structx struct_var;
structx array_of_struct[1];
__data structx* data_pointer_to_var;
structx* general_pointer_to_var;
global_var = 1;
struct_var.x=2;
array_of_struct[0].x=3;
data_pointer_to_var->x=4;
general_pointer_to_var->x=5;
(listing of the compiled code attached at the end of this mail)
Interestingly and satisfyingly the global var, member global struct and
member of global array of struct all produced the same small amount of
code.
Data pointer, as expected came close and general pointer was quite
long.
So data pointers are a good optio, but I think I will go with
something like this to optimize the interrupt performance:
typedef struct {
int run,cnt;
} structx;
structx objects[3]; // global object
void myinterrupt() { // interrupt to handle all three objects
#define OBJECT objects[0]
#include "interruptcode.c"
#define OBJECT objectst[1]
#include "interruptcode.c"
#define OBJECT objects[2]
#include "interruptcode.c"
#undef OBJECT
}
file: interruptcode.c
if (OBJECT.run)
OBJECT.cnt++;
This makes for small modifications to the existing code, allows easy
maintenance, and readable code,
and close to optimal performance. And is easily extendable.
When I need to access the global objects outside the interrut I can
write something like:
void clearCnt(int i) {
objects[i].cnt = 0;
}
br Kusti
001052 cfd9 movff 0xfd9, 0xfe5 MOVFF FSR2L,
POSTDEC1
001054 ffe5
001056 cfe1 movff 0xfe1, 0xfd9 MOVFF FSR1L,
FSR2L
001058 ffd9
00105a c000 movff 0, 0xfe5 MOVFF r0x00,
POSTDEC1
00105c ffe5
00105e c001 movff 0x1, 0xfe5 MOVFF r0x01,
POSTDEC1
001060 ffe5
001062 c002 movff 0x2, 0xfe5 MOVFF r0x02,
POSTDEC1
001064 ffe5
; .line 191;
main.c global_var = 1;
001066 0e01 movlw 0x1 MOVLW 0x01
001068 0100 movlb 0
BANKSEL _global_var
00106a 6f96 movwf 0x96, 0x1
MOVWF _global_var, B
00106c 0100 movlb 0
BANKSEL (_global_var + 1)
00106e 6b97 clrf 0x97, 0x1 CLRF (_global_var +
1), B
; .line 192;
main.c struct_var.x=2;
001070 0e02 movlw 0x2 MOVLW 0x02
001072 0100 movlb 0
BANKSEL _struct_var
001074 6f9e movwf 0x9e, 0x1
MOVWF _struct_var, B
001076 0100 movlb 0
BANKSEL (_struct_var + 1)
001078 6b9f clrf 0x9f, 0x1 CLRF (_struct_var +
1), B
; .line 193;
main.c array_of_struct[0].x=3;
00107a 0e03 movlw 0x3 MOVLW 0x03
00107c 0100 movlb 0
BANKSEL _array_of_struct
00107e 6fa0 movwf 0xa0, 0x1
MOVWF _array_of_struct, B
001080 0100 movlb 0
BANKSEL (_array_of_struct + 1)
001082 6ba1 clrf 0xa1, 0x1
CLRF (_array_of_struct + 1), B
; .line 194;
main.c data_pointer_to_var->x=4;
001084 c09c movff 0x9c, 0
MOVFF _data_pointer_to_var, r0x00
001086 f000
001088 c09d movff 0x9d, 0x1
MOVFF (_data_pointer_to_var + 1), r0x01
00108a f001
00108c c000 movff 0, 0xfe9 MOVFF r0x00,
FSR0L
00108e ffe9
001090 c001 movff 0x1, 0xfea MOVFF r0x01,
FSR0H
001092 ffea
001094 0e04 movlw 0x4 MOVLW 0x04
001096 6eee movwf 0xee, 0
MOVWF POSTINC0
001098 0e00 movlw 0 MOVLW 0x00
00109a 6eef movwf 0xef, 0 MOVWF INDF0
; .line 195;
main.c general_pointer_to_var->x=5;
00109c c08d movff 0x8d, 0
MOVFF _general_pointer_to_var, r0x00
00109e f000
0010a0 c08e movff 0x8e, 0x1
MOVFF (_general_pointer_to_var + 1), r0x01
0010a2 f001
0010a4 c08f movff 0x8f, 0x2
MOVFF (_general_pointer_to_var + 2), r0x02
0010a6 f002
0010a8 0e05 movlw 0x5 MOVLW 0x05
0010aa 6ee5 movwf 0xe5, 0
MOVWF POSTDEC1
0010ac 0e00 movlw 0 MOVLW 0x00
0010ae 6ef4 movwf 0xf4, 0 MOVWF PRODH
0010b0 c000 movff 0, 0xfe9 MOVFF r0x00,
FSR0L
0010b2 ffe9
0010b4 c001 movff 0x1, 0xff3 MOVFF r0x01,
PRODL
0010b6 fff3
0010b8 5002 movf 0x2, 0, 0 MOVF r0x02, W
0010ba ecbe call 0x137c, 0 CALL __gptrput2
>>> [email protected] 8.1.2009 12:51 >>>
Hi,
> I had quick peek at the generated code and noticed that pointer
access
> to a structure involved call to some support function to handle the
> generic pointer.
You could use __data pointers, which should be dereferenced inline.
They are also only two bytes each and thus help reducing the code
size (e.g., only 2 instead of 3 bytes passed as args saves 2
instructions).
Iff all data structures possibly pointed to by your
struct something *ptr;
reside in RAM (rather than Flash or EEPROM), you can designate your
pointer
as a pointer to RAM like so:
__data struct something *ptr;
Assignments to the pointer should not need special attention, except
for casts:
ptr = (struct something *)&blob;
might need to be rewritten to
ptr = (__data struct something *)&blob;
You can also no longer make this pointer reference string literals, as
these are (usually/always?) stored in Flash.
Maybe that helps?
> Now I'm slightly concerned that the pointer access seems rather
> expensive in terms of execution time (the interrupt will be
> called several thousand times per second). I'm thinking maybe I
should
> refactor the code to directly access global variables.
This will always be faster, of course.
Best regards,
Raphael
------------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It is the best place to buy or sell services for
just about anything Open Source.
http://p.sf.net/sfu/Xq1LFB
_______________________________________________
Sdcc-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user
------------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It is the best place to buy or sell services for
just about anything Open Source.
http://p.sf.net/sfu/Xq1LFB
_______________________________________________
Sdcc-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user