Tags:
view all tags
---+ Calling C Functions from Forth and Vice Versa ---++ Register Usage Procedure Call Standard for the ARM Architecture [[https://developer.arm.com/documentation/ihi0042/j][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* | *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 Word =osDelay= from [[https://github.com/spyren/Mecrisp-Cube/blob/master/Forth/cube/rtos.s][rtos.s]] <pre> // ----------------------------------------------------------------------------- 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} </pre> 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 R12 is used as a temporary storage. <verbatim> register uint32_t TOS asm ("r6"); register uint32_t PSP asm ("r12"); TOS = TOS; PSP = PSP; </verbatim> C function =FS_include()= from [[https://github.com/spyren/Mecrisp-Cube/blob/master/Forth/Src/fs.c][fs.c]] calls the Forth words =FS_type= and =FS_evaluate=. <pre> /** * @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"); <b>FS_type((uint8_t*)line, strlen(line));</b> return; } /* Read every line and interprets it */ while (f_gets(line, sizeof line, &fil)) { // line without \n <b>FS_evaluate((uint8_t*)line, strlen(line)-1);</b> } /* Close the file */ f_close(&fil); } </pre> Word =include= from [[https://github.com/spyren/Mecrisp-Cube/blob/master/Forth/cube/fs.s][fs.s]] calls the C function =FS_include()=. <pre> @ ----------------------------------------------------------------------------- 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 <b>movs r12, psp // get psp</b> bl FS_include <b>movs psp, r12 // update psp</b> pop {r0-r3, pc} </pre> The C function =FS_include()= from [[https://github.com/spyren/Mecrisp-Cube/blob/master/Forth/Src/fs.c][fs.c]] calls the Forth word =evaluate= by the =FS_evaluate()= function. <pre> // 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} </pre> -- %USERSIG{PeterSchmid - 2020-07-13}% ---++ Comments %COMMENT%
Edit
|
Attach
|
Watch
|
P
rint version
|
H
istory
:
r7
<
r6
<
r5
<
r4
<
r3
|
B
acklinks
|
V
iew topic
|
Raw edit
|
More topic actions...
Topic revision: r4 - 2020-08-05
-
PeterSchmid
Home
Site map
Cosmac web
MRR web
MecrispCube web
SuperRandonnee web
TWiki web
Ursula web
Velo web
MecrispCube Web
Create New Topic
Index
Search
Changes
Notifications
RSS Feed
Statistics
Preferences
View
Raw View
Print version
Find backlinks
History
More topic actions
Edit
Raw edit
Attach file or image
Edit topic preference settings
Set new parent
More topic actions
Account
Log In
Edit
Attach
Copyright © 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