Calling C Functions from Forth and Vice Versa

Register Usage

Procedure Call Standard for the ARM Architecture AAPCS

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 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
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

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);
// -----------------------------------------------------------------------------
	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

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.

 *  @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 */

	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));

	/* 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 */

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

@ -----------------------------------------------------------------------------
		Wortbirne Flag_visible, "include"
		@  ( "filename" any -- any ) Interprets the content of the file.
// void FS_include(uint8_t *str, int count)
@ -----------------------------------------------------------------------------
	push	{lr}
	bl	token		@ ( -- c-addr len )
	movs	r1, tos		// len -> count
	movs	r0, tos		// c-addr -> str
	movs	r9, psp		// get psp
	movs	r8, tos		// get tos
	bl	FS_include
	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.

// void FS_evaluate(uint8_t* str, int count);
.global		FS_evaluate
	push 	{r4-r7, lr}
	movs	psp, r9		// get psp
	movs	tos, r8		// get tos
	movs	tos, r0		// str
	movs	tos, r1		// count
	bl	evaluate
	movs	r9, psp		// update psp
	movs	r8, tos		// update tos
	pop	{r4-r7, pc}

-- Peter Schmid - 2020-07-13


Edit | Attach | Watch | Print version | History: r5 < r4 < r3 < r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r5 - 2020-08-06 - PeterSchmid
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback