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 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 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
r13 Stack pointer (SP) Stack pointer (SP)
r14 Link register (LR) Link register (LR)
r15 Program counter (PC) Program counter (PC)
>
>
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