Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
Calling C Functions from Forth and Vice Versa | ||||||||
Line: 147 to 147 | ||||||||
-- ![]() | ||||||||
Deleted: | ||||||||
< < | Comments | |||||||
\ No newline at end of file | ||||||||
Added: | ||||||||
> > | ![]() This work by Peter Schmid is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. | |||||||
\ No newline at end of file |
Line: 1 to 1 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Calling C Functions from Forth and Vice Versa | ||||||||||||||||
Line: 17 to 17 | ||||||||||||||||
| ||||||||||||||||
Changed: | ||||||||||||||||
< < |
| |||||||||||||||
> > |
| |||||||||||||||
| ||||||||||||||||
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![]() FS_type and FS_evaluate .
| ||||||||||||||||
Line: 65 to 65 | ||||||||||||||||
* @brief![]() ![]() | ||||||||||||||||
Added: | ||||||||||||||||
> > | * forth_stack TOS (lower word) and SPS (higher word)
* @param![]() | |||||||||||||||
* str filename (w/ or w/o null termination)
* @param![]() ![]() | ||||||||||||||||
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![]() 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} |
Line: 1 to 1 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Calling C Functions from Forth and Vice Versa | ||||||||||||||||
Line: 17 to 17 | ||||||||||||||||
| ||||||||||||||||
Changed: | ||||||||||||||||
< < |
| |||||||||||||||
> > |
| |||||||||||||||
| ||||||||||||||||
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![]() 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![]() 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} | |||||||||||||||
-- ![]() |
Line: 1 to 1 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
< < |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> > |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
VFP Register UsageThe 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![]() 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![]() 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![]() 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} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- ![]() |
Line: 1 to 1 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
< < |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> > |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
VFP Register UsageThe VFP-v2 co-processor has 32 single-precision registers, s0-s31, which may also be accessed as 16 |
Line: 1 to 1 | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Calling C Functions from Forth and Vice Versa | |||||||||||||||||||
Added: | |||||||||||||||||||
> > | Register Usage | ||||||||||||||||||
Procedure Call Standard for the ARM Architecture AAPCS![]() ![]() | |||||||||||||||||||
Line: 11 to 12 | |||||||||||||||||||
| |||||||||||||||||||
Changed: | |||||||||||||||||||
< < |
| ||||||||||||||||||
> > |
| ||||||||||||||||||
| |||||||||||||||||||
Changed: | |||||||||||||||||||
< < |
| ||||||||||||||||||
> > |
| ||||||||||||||||||
| |||||||||||||||||||
Changed: | |||||||||||||||||||
< < | |||||||||||||||||||
> > | VFP Register UsageThe 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 ForthCalling Forth Words from C FunctionsStack Pointer and Top Of Stack | ||||||||||||||||||
-- ![]() |
Line: 1 to 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Added: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
> > |
Calling C Functions from Forth and Vice VersaProcedure Call Standard for the ARM Architecture AAPCS![]() ![]()
![]() Comments |