static inline of method in c, the h-file and the XC file

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

static inline of method in c, the h-file and the XC file

Post by lilltroll »

Have some problem with static inline and what to write in the c file and the h-file.

I have some c-methods that should be called from XC, but due to speed they also needs to be inlined in the code.

Everything works if I skip the the static e.g. only inline, (and the methods doesn't get inlined)
But adding static inline in the c-file makes the compiler complain:

Undefined reference to 'my method'

How should the static and the inline, (or do I need extern) look like in the c-file and the corresponding h-file, so it can be called from XC ?

Since I only need one LCD buffer inte the entire code, I use the short method without sending the reference/pointer to the buffer with the call to the methods.

Code: Select all

/*
 * Buf.c
 *
 */
#include "LCD_Comp_Def.h"

static int BUF0[LCD_WIDTH_PX];
static int BUF1[LCD_WIDTH_PX];

void init_Buf(void){
	int y;
	 for(y=0;y<LCD_WIDTH_PX;y++){
	  BUF0[y]=0;
	  BUF1[y]=0;
}
}

static inline int PULL(unsigned page,unsigned y){
	if(page)
		return BUF1[y];
	else
		return BUF0[y];
}


static inline void PUSH(unsigned page,unsigned y, int val){
	if(page)
		BUF1[y]=val;
	else
		BUF0[y]=val;
}



Probably not the most confused programmer anymore on the XCORE forum.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

The compiler is only able to inline a function if it can see the definition of the function. If you want a function to be inlined into multiple files you must put the implementation of that function in a header. The following post should explain how to do this:

http://www.xcore.com/forum/viewtopic.php?p=3055#p3055
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

I was reading that post, and got a little help of a computer science friend.

I moved the code to the .h file
But the problem is that the compiler includes it as a XC file, so "I get the violates parallel usage rules"

I tried to add something like

Code: Select all

#define __C__
in the h file, based on trial and error
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

...or

Is this way from the class-D code a "clean way" of overruling paralleled usages rules regarding array manipulation?

Code: Select all

#define CAST32(dst, src)       asm("mov %0, %1"     : "=r"(dst) : "r"(src));
#define LOAD32(dst, ptr)       asm("ldw %0, %1[0]"  : "=r"(dst) : "r"(ptr));
#define STORE32(src, ptr)      asm("stw %0, %1[0]"  :           : "r"(src), "r"(ptr));
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

The ASM way:

I got it working the ASM way, but I do not understand the ASM syntax:
TheXMOSXS1Architectur describes LDW as:

LDW d, b, i
d <- mem[b + i * Bpw]

But in the XDE it only take 2 operands, not the index :!: :?:
Right now I do the i * Bpw in another instruction, e. g. byte_index=4* int32_index

meaning that at least

ldc r0, 0x4
mul r0,r0,r1

becomes overhead

:oops: I forgot, there was an " XS1 Assembly Language Manual", that now became chapter 18 in
https://www.xmos.com/support/documentation-> Tools user guide
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

This works as a multi-linebuffer in XC:

Code: Select all

#define CAST32(dst, src)       asm("mov %0, %1"     : "=r"(dst) : "r"(src));
#define LOAD32(dst,index)       asm("ldw %0, %1[%2] "  : "=r"(dst) : "r"(ptrBUF),"r"(index) );
#define STORE32(src,index)      asm("stw %0, %1[%2]"   :           : "r"(src),"r"(ptrBUF), "r"(index)  );

static int BUF[PAGES][LCD_WIDTH_PX];
static unsigned ptrBUF;

static inline
int PULL(unsigned index){
	int val;
	LOAD32(val, index)
	return val;
	}

static inline
void PUSH(unsigned pageOffset,unsigned index, int val){
	STORE32(val, pageOffset+index)
	}

Code: Select all

 
void LcdFrameGen()
{
...
PUSH(pageOffset,10,LCD_YELLOW); //Draw yellow line @ x=10
...
}


void LcdFrameGen()
{
...	
CAST32(ptrBUF, BUF);
...
#pragma unsafe arrays
for(unsigned index=LCD_WIDTH_PX*page; index <LCD_WIDTH_PX*(page+1) ; index++)
 RGB_port<: PULL(index);
}
Probably not the most confused programmer anymore on the XCORE forum.
bearcat
Respected Member
Posts: 283
Joined: Fri Mar 19, 2010 4:49 am

Post by bearcat »

It took me a little time to figure out the different opcodes for inline assembly. I am not sure if the tools manual Chapter 18 listed those all along, or not. But that is the reference to go to now.

The shortened versions are easier to deal with instead of having to know every address mode.

I did not know about the psuedo instrutions of NOP and MOV. I may make use of those in the future.