Difference: CallingCFunction (1 vs. 7)

Revision 72021-01-28 - PeterSchmid

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Calling C Functions from Forth and Vice Versa

Line: 147 to 147
  -- Peter Schmid - 2020-07-13
Deleted:
<
<

Comments

<--/commentPlugin-->
 \ No newline at end of file
Added:
>
>
Creative Commons License
This work by Peter Schmid is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
 \ No newline at end of file

Revision 62020-08-08 - PeterSchmid

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Calling C Functions from Forth and Vice Versa

Line: 17 to 17
 
r5 Variable register 2 Y DO Limit  
r6 Variable register 3 Y Top Of Stack TOS  
r7 Variable register 4 Y Data stack pointer SPS  
Changed:
<
<
r8 Variable register 5 Y TOS copy  
r9 Platform register (usage defined by platform in use) Y SPS copy  
>
>
r8 Variable register 5 Y unused  
r9 Platform register (usage defined by platform in use) Y unused  
 
r10 Variable register 7 Y unused  
r11 Variable register 8 Y unused  
r12 Intra-procedure-call scratch register N unused 6
Line: 57 to 57
 

Calling Forth Words from C Functions

Changed:
<
<
Data Stack Pointer SPS is in R7 and Top Of Stack TOS is in R6. R7 can't be a register variable, that's why R9 is used as a temporary storage.
>
>
Data Stack Pointer SPS is in R1 and Top Of Stack TOS is in R0 (first parameter).
  C function FS_include() from fs.c calls the Forth words FS_type and FS_evaluate.

Line: 65 to 65
  * @brief * Interprets the content of the file. * @param[in]
Added:
>
>
* forth_stack TOS (lower word) and SPS (higher word) * @param[in]
  * str filename (w/ or w/o null termination) * @param[in] * count string length * @return
Changed:
<
<
* None
>
>
* TOS (lower word) and SPS (higer word)
  */
Changed:
<
<
void FS_include(uint8_t *str, int count) {
>
>
uint64_t FS_include(uint64_t forth_stack, uint8_t *str, int count) {
  FIL fil; /* File object */ FRESULT fr; /* FatFs return code */
Added:
>
>
uint64_t stack; stack = forth_stack;
  memcpy(path, str, count); line[count] = 0;
Line: 83 to 88
  if (fr) { // open failed strcpy(line, "Err: file not found");
Changed:
<
<
FS_type((uint8_t*)line, strlen(line)); return;
>
>
stack = FS_type(stack, (uint8_t*)line, strlen(line));
  }

/* Read every line and interprets it */ while (f_gets(line, sizeof line, &fil)) { // line without \n

Changed:
<
<
FS_evaluate((uint8_t*)line, strlen(line)-1);
>
>
stack = FS_evaluate(stack, (uint8_t*)line, strlen(line)-1);
  }

/* Close the file */ f_close(&fil);

Added:
>
>
return stack;
 }
Line: 102 to 108
 
@ -----------------------------------------------------------------------------
		Wortbirne Flag_visible, "include"

Changed:
<
<
@ ( "filename" any -- any ) Interprets the content of the file. // void FS_include(uint8_t *str, int count)
>
>
@ ( any "filename" -- any ) Interprets the content of the file. // uint64_t FS_include (uint64_t forth_stack, uint8_t *str, int count);
 @ ----------------------------------------------------------------------------- include: push {lr} bl token @ ( -- c-addr len ) incl:
Changed:
<
<
movs r1, tos // len -> count
>
>
movs r3, tos // len -> count
  drop
Changed:
<
<
movs r0, tos // c-addr -> str
>
>
movs r2, tos // c-addr -> str
  drop
Changed:
<
<
movs r9, psp // get psp movs r8, tos // get tos
>
>
movs r0, tos // get tos movs r1, psp // get psp
  bl FS_include
Changed:
<
<
movs psp, r9 // update psp movs tos, r8 // update tos
>
>
movs tos, r0 // update tos movs psp, r1 // update psp
  pop {pc}

The C function FS_include() from fs.c calls the Forth word evaluate by the FS_evaluate() function.


Changed:
<
<
// void FS_evaluate(uint8_t* str, int count);
>
>
// uint64_t FS_evaluate(uint64_t forth_stack, uint8_t* str, int count);
 .global FS_evaluate FS_evaluate: push {r4-r7, lr}
Changed:
<
<
movs psp, r9 // get psp movs tos, r8 // get tos
>
>
movs tos, r0 // get tos movs psp, r1 // get psp
  pushdatos
Changed:
<
<
movs tos, r0 // str
>
>
movs tos, r2 // str
  pushdatos
Changed:
<
<
movs tos, r1 // count
>
>
movs tos, r3 // count
  bl evaluate
Changed:
<
<
movs r9, psp // update psp movs r8, tos // update tos
>
>
movs r0, tos // update tos movs r1, psp // update psp
  pop {r4-r7, pc}

Revision 52020-08-06 - PeterSchmid

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Calling C Functions from Forth and Vice Versa

Line: 17 to 17
 
r5 Variable register 2 Y DO Limit  
r6 Variable register 3 Y Top Of Stack TOS  
r7 Variable register 4 Y Data stack pointer SPS  
Changed:
<
<
r8 Variable register 5 Y unused  
r9 Platform register (usage defined by platform in use) Y unused  
>
>
r8 Variable register 5 Y TOS copy  
r9 Platform register (usage defined by platform in use) Y SPS copy  
 
r10 Variable register 7 Y unused  
r11 Variable register 8 Y unused  
r12 Intra-procedure-call scratch register N unused 6
Line: 57 to 57
 

Calling Forth Words from C Functions

Changed:
<
<
Data Stack Pointer SPS is in R7 and Top Of Stack TOS is in R6. R7 can't be a register variable, that's why R12 is used as a temporary storage.

register uint32_t TOS asm ("r6");
register uint32_t PSP asm ("r12");

TOS = TOS;
PSP = PSP;
>
>
Data Stack Pointer SPS is in R7 and Top Of Stack TOS is in R6. R7 can't be a register variable, that's why R9 is used as a temporary storage.
  C function FS_include() from fs.c calls the Forth words FS_type and FS_evaluate.

Line: 83 to 75
  FIL fil; /* File object */ FRESULT fr; /* FatFs return code */
Deleted:
<
<
register uint32_t TOS asm ("r6"); register uint32_t PSP asm ("r12");

TOS = TOS; PSP = PSP;

  memcpy(path, str, count); line[count] = 0;
Line: 116 to 102
 
@ -----------------------------------------------------------------------------
		Wortbirne Flag_visible, "include"

Changed:
<
<
@ ( "filename" -- ) Interprets the content of the file.
>
>
@ ( "filename" any -- any ) Interprets the content of the file.
 // void FS_include(uint8_t *str, int count) @ ----------------------------------------------------------------------------- include:
Changed:
<
<
push {r0-r3, lr} bl token // ( -- c-addr len )
>
>
push {lr} bl token @ ( -- c-addr len ) incl:
  movs r1, tos // len -> count drop movs r0, tos // c-addr -> str drop
Changed:
<
<
movs r12, psp // get psp
>
>
movs r9, psp // get psp movs r8, tos // get tos
  bl FS_include
Changed:
<
<
movs psp, r12 // update psp pop {r0-r3, pc}
>
>
movs psp, r9 // update psp movs tos, r8 // update tos pop {pc}
 

The C function FS_include() from fs.c calls the Forth word evaluate by the FS_evaluate() function.

Line: 137 to 126
 // void FS_evaluate(uint8_t* str, int count); .global FS_evaluate FS_evaluate:
Changed:
<
<
push {r4, r5, r7, lr} movs psp, r12 // get psp
>
>
push {r4-r7, lr} movs psp, r9 // get psp movs tos, r8 // get tos
  pushdatos movs tos, r0 // str pushdatos movs tos, r1 // count bl evaluate
Changed:
<
<
movs r12, psp // update psp pop {r4, r5, r7, pc}
>
>
movs r9, psp // update psp movs r8, tos // update tos pop {r4-r7, pc}
 

-- Peter Schmid - 2020-07-13

Revision 42020-08-05 - PeterSchmid

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Calling C Functions from Forth and Vice Versa

Line: 7 to 7
  https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/on-the-aapcs-with-an-application-to-efficient-parameter-passing
Changed:
<
<
Register AAPCS Purpose MECRISP Forth Purpose ISR Stacking
xPSR Processor Status Register, Flags Flags 1
r0 Argument, result, scratch register 1 Scratch 2
r1 Argument, result, scratch register 2 Scratch 3
r2 Argument, scratch register 3 Scratch 4
r3 Argument, scratch register 4 Scratch 5
r4 Variable register 1 DO Index  
r5 Variable register 2 DO Limit  
r6 Variable register 3 Top Of Stack TOS  
r7 Variable register 4 Data stack pointer  
r8 Variable register 5 unused  
r9 Platform register (usage defined by platform in use) unused  
r10 Variable register 7 unused  
r11 Variable register 8 unused  
r12 Intra-procedure-call scratch register unused 6
r13 Stack pointer (SP) Stack pointer (SP)  
r14 Link register (LR) Link register (LR) 7
r15 Program counter (PC) Program counter (PC) 0
>
>
Register AAPCS Purpose Restore Contents MECRISP Forth Purpose ISR Stacking
xPSR Processor Status Register, Flags N Flags 1
r0 Argument, result, scratch register 1 N Scratch 2
r1 Argument, result, scratch register 2 N Scratch 3
r2 Argument, scratch register 3 N Scratch 4
r3 Argument, scratch register 4 Y Scratch 5
r4 Variable register 1 Y DO Index  
r5 Variable register 2 Y DO Limit  
r6 Variable register 3 Y Top Of Stack TOS  
r7 Variable register 4 Y Data stack pointer SPS  
r8 Variable register 5 Y unused  
r9 Platform register (usage defined by platform in use) Y unused  
r10 Variable register 7 Y unused  
r11 Variable register 8 Y unused  
r12 Intra-procedure-call scratch register N unused 6
r13 Stack pointer (SP) y Stack pointer (SP)  
r14 Link register (LR) N Link register (LR) 7
r15 Program counter (PC) N Program counter (PC) 0
 

VFP Register Usage

The VFP-v2 co-processor has 32 single-precision registers, s0-s31, which may also be accessed as 16 double-precision registers, d0-d15 (with d0 overlapping s0, s1; d1 overlapping s2, s3; etc).

Calling C Functions from Forth

Added:
>
>
Word osDelay from rtos.s

// -----------------------------------------------------------------------------
	Wortbirne Flag_visible, "osDelay"
	@ ( u -- n ) Wait for Timeout (Time Delay).
/// \param[in]     ticks         \ref CMSIS_RTOS_TimeOutValue "time ticks" value
/// \return status code that indicates the execution status of the function.
// osStatus_t osDelay (uint32_t ticks);
// -----------------------------------------------------------------------------
rtos_osDelay:
	push	{r0-r3, lr}
	movs	r0, tos		// ticks
	bl	osDelay
	movs	tos, r0
	pop	{r0-r3, pc}

If the C function itself calls Forth words the Data Stack Pointer SPS and Top Of Stack TOS registers have to be passed to the Forth words. See below.

 

Calling Forth Words from C Functions

Changed:
<
<
Stack Pointer and Top Of Stack
>
>
Data Stack Pointer SPS is in R7 and Top Of Stack TOS is in R6. R7 can't be a register variable, that's why R12 is used as a temporary storage.

register uint32_t TOS asm ("r6");
register uint32_t PSP asm ("r12");

TOS = TOS;
PSP = PSP;

C function FS_include() from fs.c calls the Forth words FS_type and FS_evaluate.

/**
 *  @brief
 *      Interprets the content of the file.
 *  @param[in]
 *      str   filename (w/ or w/o null termination)
 *  @param[in]
 *      count string length
 *  @return
 *      None
 */
void FS_include(uint8_t *str, int count) {
	FIL fil;        /* File object */
	FRESULT fr;     /* FatFs return code */

	register uint32_t TOS asm ("r6");
	register uint32_t PSP asm ("r12");

	TOS = TOS;
	PSP = PSP;

	memcpy(path, str, count);
	line[count] = 0;

	/* Open a text file */
	fr = f_open(&fil, path, FA_READ);
	if (fr) {
		// open failed
		strcpy(line, "Err: file not found");
		FS_type((uint8_t*)line, strlen(line));
		return;
	}

	/* Read every line and interprets it */
	while (f_gets(line, sizeof line, &fil)) {
		// line without \n
		FS_evaluate((uint8_t*)line, strlen(line)-1);
	}

	/* Close the file */
	f_close(&fil);
}

Word include from fs.s calls the C function FS_include().

@ -----------------------------------------------------------------------------
		Wortbirne Flag_visible, "include"
		@  ( "filename" -- ) Interprets the content of the file.
// void FS_include(uint8_t *str, int count)
@ -----------------------------------------------------------------------------
include:
	push	{r0-r3, lr}
	bl	token		// ( -- c-addr len )
	movs	r1, tos		// len -> count
	drop
	movs	r0, tos		// c-addr -> str
	drop
	movs	r12, psp	// get psp
	bl	FS_include
	movs	psp, r12	// update psp
	pop	{r0-r3, pc}

The C function FS_include() from fs.c calls the Forth word evaluate by the FS_evaluate() function.

// void FS_evaluate(uint8_t* str, int count);
.global		FS_evaluate
FS_evaluate:
	push 	{r4, r5, r7, lr}
	movs	psp, r12	// get psp
	pushdatos
	movs	tos, r0		// str
	pushdatos
	movs	tos, r1		// count
	bl	evaluate
	movs	r12, psp	// update psp
	pop	{r4, r5, r7, pc}
  -- Peter Schmid - 2020-07-13

Revision 32020-07-17 - PeterSchmid

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Calling C Functions from Forth and Vice Versa

Line: 7 to 7
  https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/on-the-aapcs-with-an-application-to-efficient-parameter-passing
Changed:
<
<
Register AAPCS Purpose
<-- -->
Sorted ascending
MECRISP Forth Purpose
r0 Argument, result, scratch register 1 Scratch
r1 Argument, result, scratch register 2 Scratch
r2 Argument, scratch register 3 Scratch
r3 Argument, scratch register 4 Scratch
r12 Intra-procedure-call scratch register unused
r14 Link register (LR) Link register (LR)
r9 Platform register (usage defined by platform in use) unused
r15 Program counter (PC) Program counter (PC)
r13 Stack pointer (SP) Stack pointer (SP)
r4 Variable register 1 DO Index
r5 Variable register 2 DO Limit
r6 Variable register 3 Top Of Stack TOS
r7 Variable register 4 Data stack pointer
r8 Variable register 5 unused
r10 Variable register 7 unused
r11 Variable register 8 unused
>
>
Register AAPCS Purpose MECRISP Forth Purpose ISR Stacking
xPSR Processor Status Register, Flags Flags 1
r0 Argument, result, scratch register 1 Scratch 2
r1 Argument, result, scratch register 2 Scratch 3
r2 Argument, scratch register 3 Scratch 4
r3 Argument, scratch register 4 Scratch 5
r4 Variable register 1 DO Index  
r5 Variable register 2 DO Limit  
r6 Variable register 3 Top Of Stack TOS  
r7 Variable register 4 Data stack pointer  
r8 Variable register 5 unused  
r9 Platform register (usage defined by platform in use) unused  
r10 Variable register 7 unused  
r11 Variable register 8 unused  
r12 Intra-procedure-call scratch register unused 6
r13 Stack pointer (SP) Stack pointer (SP)  
r14 Link register (LR) Link register (LR) 7
r15 Program counter (PC) Program counter (PC) 0
 

VFP Register Usage

The VFP-v2 co-processor has 32 single-precision registers, s0-s31, which may also be accessed as 16

Revision 22020-07-13 - PeterSchmid

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Calling C Functions from Forth and Vice Versa

Added:
>
>

Register Usage

 Procedure Call Standard for the ARM Architecture AAPCS

https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/on-the-aapcs-with-an-application-to-efficient-parameter-passing

Line: 11 to 12
 
r1 Argument, result, scratch register 2 Scratch
r2 Argument, scratch register 3 Scratch
r3 Argument, scratch register 4 Scratch
Changed:
<
<
r4 Variable register 1  
r5 Variable register 2  
>
>
r4 Variable register 1 DO Index
r5 Variable register 2 DO Limit
 
r6 Variable register 3 Top Of Stack TOS
Changed:
<
<
r7 Variable register 4 Data Stack
r8 Variable register 5  
r9 Platform register (usage defined by platform in use)  
r10 Variable register 7  
r11 Variable register 8  
r12 Intra-procedure-call scratch register  
>
>
r7 Variable register 4 Data stack pointer
r8 Variable register 5 unused
r9 Platform register (usage defined by platform in use) unused
r10 Variable register 7 unused
r11 Variable register 8 unused
r12 Intra-procedure-call scratch register unused
 
r13 Stack pointer (SP) Stack pointer (SP)
r14 Link register (LR) Link register (LR)
r15 Program counter (PC) Program counter (PC)
Changed:
<
<
>
>

VFP Register Usage

The VFP-v2 co-processor has 32 single-precision registers, s0-s31, which may also be accessed as 16 double-precision registers, d0-d15 (with d0 overlapping s0, s1; d1 overlapping s2, s3; etc).

Calling C Functions from Forth

Calling Forth Words from C Functions

Stack Pointer and Top Of Stack
  -- Peter Schmid - 2020-07-13

Revision 12020-07-13 - PeterSchmid

Line: 1 to 1
Added:
>
>
META TOPICPARENT name="WebHome"

Calling C Functions from Forth and Vice Versa

Procedure Call Standard for the ARM Architecture AAPCS

https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/on-the-aapcs-with-an-application-to-efficient-parameter-passing

Register AAPCS Purpose MECRISP Forth Purpose
r0 Argument, result, scratch register 1 Scratch
r1 Argument, result, scratch register 2 Scratch
r2 Argument, scratch register 3 Scratch
r3 Argument, scratch register 4 Scratch
r4 Variable register 1  
r5 Variable register 2  
r6 Variable register 3 Top Of Stack TOS
r7 Variable register 4 Data Stack
r8 Variable register 5  
r9 Platform register (usage defined by platform in use)  
r10 Variable register 7  
r11 Variable register 8  
r12 Intra-procedure-call scratch register  
r13 Stack pointer (SP) Stack pointer (SP)
r14 Link register (LR) Link register (LR)
r15 Program counter (PC) Program counter (PC)

-- Peter Schmid - 2020-07-13

Comments

<--/commentPlugin-->
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback