ForthHub / discussion

Discussion repository for Forth enthusiasts.
118 stars 4 forks source link

How Forth handles hardware interuptions #70

Open Lecrapouille opened 6 years ago

Lecrapouille commented 6 years ago

Hi everybody, I have a noob question. I'm working on embedded systems written in C. I'm too young to have worked with Forth in professional projects, I hardly know how to write Forth scripts but I know how to make my own Forth interpreter.

When Forth is embedded inside a micro-controller, how do you manage hardware interruptions routines (ISR) ? For example: reading the ADC value and filter the value or getting the I2C message ? In C code I'm accustomed to have an ISR table with the correct pointers on your ISR functions. When an interruption occurs your routine is called.

How in Forth this is managed ? Do you write the code of the routine directly in asm ? Or do you create a task for polling the register (ugly way) ? Or has it a way to do it directly with Forth words.

Thanks

pebhidecs commented 6 years ago

On 21/07/2018 at 9:56 PM, "Quentin Quadrat" notifications@github.com wrote:

Hi everybody, I have a noob question. I'm working on embedded systems written in C. I'm too young to have worked with Forth in professional projects, I hardly know how to write Forth scripts but I know how to make my own Forth interpreter.

When Forth is embedded inside a micro-controller, how do you manage hardware interruptions routines (ISR) ? For example: reading the ADC value and filter the value or getting the I2C message ? In C code I'm accustomed to have an ISR table with the correct pointers on your ISR functions. When an interruption occurs your routine is called.

Couple of rules first.

  1. All ISRs MUST be stack neutral. That means that whatever values are placed on the stack, must be removed before the return from the Interrupt.

  2. All ISRs must be kept very short and single pass, without looping. This is to maintain the system's ability to get the interrupting work done quickly and get back to the main task with the minimum of disruption. It also means that you do not destroy the latency of responses to interrupts.

How in Forth this is managed ? Do you write the code of the routine directly in asm ? Or do you create a task for polling the register (ugly way) ? Or has it a way to do it directly with Forth words.

ISRs can be written in Forth. When handling the interrupt, you are just running the inner interpreter (NEXT) with a different set of threaded addresses. So long as you have sufficient room on the stack for any interrupt routine data, there is no need to even tidy away the current stacks. Just be sure of the next address that you would have executed, had the interrupt not happened, is the one you execute on return from interrupt.

There were a few different words that were used by different Forth systems.

Regards

Paul E. Bennett IEng MIET Systems Engineer Lunar Mission One Ambassador --


Paul E. Bennett IEng MIET..... Forth based HIDECS Consultancy............. Mob: +44 (0)7811-639972 Tel: +44 (0)1392-426688 Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..


GarthWilson commented 6 years ago
I sent this a few minutes ago, but it looks like I used the wrong
  reply address.  Here it is again.

  -------- Forwarded Message --------

        Subject:

        Re: [ForthHub/discussion] How Forth handles hardware
          interuptions (#70)

        Date: 
        Sat, 21 Jul 2018 14:38:52 -0700

        From: 
        Garth Wilson <wilsonmines@dslextreme.com>

        To: 
        Quentin Quadrat <notifications@github.com>

  I did it in ITC Forth on a 6502 in
    about 1990 and wrote it up at http://wilsonminesco.com/0-overhead_Forth_interrupts/
    .  I envisioned a way to do it without overhead.  Several people
    told me it couldn't be done, which of course only fueled my
    fire.  The result I've been using for 28 years now is described
    here.  I wanted it for the production automated test equipment
    (ATE) I designed and programmed, shown here.  The RS-232
    input from the PC for software development was handled at 9600
    bps through a 65C51 ACIA entirely by interrupts in high-level
    Forth on a 2MHz 65C02.

    One man told me that he always does interrupts in assembly for
    speed, so he wasn't very interested in high-level Forth
    interrupt service.  The nice thing here is that when you
    eliminate the overhead, you get some of the speed back.  (Also,
    error-reporting and handling becomes easier.)  You can of course
    still have assembly-language ISRs also if you like, and they
    will get priority over the Forth ISRs.

    The zero-overhead interrupt support is simple, adds only about
    100 bytes to your overall code, and can be nested—ie, you can
    allow a higher-priority interrupt to interrupt the servicing of
    a lower-priority one—as many interrupt levels deep as you wish. 
    No additional stacks are required.  It's another natural
    for Forth.  As usual for interrupts, some assembly is required
    to get the system going, but very little.

    I call it "zero-overhead" interrupt response because when an
    interrupt occurs, the Forth system moves right into the
    interrupt-service routine (ISR) just as if it were part of the
    normal code.  Simply put, it is as if a new word was suddenly
    inserted into the executing code—a word whose stack effect is (
    -- ).

    Garth

     
    On 07/21/2018 01:56 PM, Quentin Quadrat wrote:

    Hi everybody, I have a noob question. I'm working on embedded
      systems written in C. I'm too young to have worked with Forth
      in professional projects, I hardly know how to write Forth
      scripts but I know how to make my own Forth interpreter.
    When Forth is embedded inside a micro-controller, how do you
      manage hardware interruptions routines (ISR) ? For example:
      reading the ADC value and filter the value or getting the I2C
      message ? In C code I'm accustomed to have an ISR table with
      the correct pointers on your ISR functions. When an
      interruption occurs your routine is called.
    How in Forth this is managed ? Do you write the code of the
      routine directly in asm ? Or do you create a task for polling
      the register (ugly way) ? Or has it a way to do it directly
      with Forth words.
    Thanks
    —
      You are receiving this because you are subscribed to this
      thread.
      Reply to this email directly, view it on GitHub, or mute the thread.
    {"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/ForthHub/discussion","title":"ForthHub/discussion","subtitle":"GitHub repository","main_image_url":"https://assets-cdn.github.com/images/email/message_cards/header.png","avatar_image_url":"https://assets-cdn.github.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/ForthHub/discussion"}},"updates":{"snippets":[{"icon":"DESCRIPTION","message":"How Forth handles hardware interuptions (#70)"}],"action":{"name":"View Issue","url":"https://github.com/ForthHub/discussion/issues/70"}}}
    [

{ "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/ForthHub/discussion/issues/70", "url": "https://github.com/ForthHub/discussion/issues/70", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } }, { "@type": "MessageCard", "@context": "http://schema.org/extensions", "hideOriginalBody": "false", "originator": "AF6C5A86-E920-430C-9C59-A73278B5EFEB", "title": "How Forth handles hardware interuptions (#70)", "sections": [ { "text": "", "activityTitle": "Quentin Quadrat", "activityImage": "https://assets-cdn.github.com/images/email/message_cards/avatar.png", "activitySubtitle": "@Lecrapouille", "facts": [ { "name": "Repository: ", "value": "ForthHub/discussion" }, { "name": "Issue #: ", "value": 70 } ] } ], "potentialAction": [ { "name": "Add a comment", "@type": "ActionCard", "inputs": [ { "isMultiLine": true, "@type": "TextInput", "id": "IssueComment", "isRequired": false } ], "actions": [ { "name": "Comment", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueComment\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70,\n\"IssueComment\": \"{{IssueComment.value}}\"\n}" } ] }, { "name": "Close issue", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueClose\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70\n}" }, { "targets": [ { "os": "default", "uri": "https://github.com/ForthHub/discussion/issues/70" } ], "@type": "OpenUri", "name": "View on GitHub" }, { "name": "Unsubscribe", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"MuteNotification\",\n\"threadId\": 359074464\n}" } ], "themeColor": "26292E" } ]

Brad-R commented 6 years ago

As a general rule, you want an interrupt service routine to be as quick as possible. For example, read a UART and stuff the character into a buffer for later processing -- don't try having the interrupt routine parse the text input.

Usually that means writing the ISR in assembly language, but that's not required. It's straightforward to save the registers of the Forth virtual machine, and then reload those registers to execute a "high-level" Forth word.

There's an example for the MSP430 in the CamelForth distribution at http://www.camelforth.com/download.php?view.32 -- in that zip you will find itc430irpts.asm, which is heavily commented. That file builds Forth words that can be used as ISRs. You'll also want to study 430g2553install.asm, which installs ISR addresses into the interrupt vector table (specifically the 430G2553 vector table).

Regards, Brad

On Sat, 21 Jul 2018 13:56:33 -0700 Quentin Quadrat notifications@github.com wrote:

Hi everybody, I have a noob question. I'm working on embedded systems written in C. I'm too young to have worked with Forth in professional projects, I hardly know how to write Forth scripts but I know how to make my own Forth interpreter.

When Forth is embedded inside a micro-controller, how do you manage hardware interruptions routines (ISR) ? For example: reading the ADC value and filter the value or getting the I2C message ? In C code I'm accustomed to have an ISR table with the correct pointers on your ISR functions. When an interruption occurs your routine is called.

How in Forth this is managed ? Do you write the code of the routine directly in asm ? Or do you create a task for polling the register (ugly way) ? Or has it a way to do it directly with Forth words.

Thanks

-- brad@bradrodriguez.com

bfox9900 commented 6 years ago

Everything Paul said are lessons from an authority.

I had to implement a four channel optical counter as an ISR on a Forth system that was running on a 68HC11. For that machine, I opted to use ASM code to minimize taking too much time as it had to run every 4mS on a timer interrupt.

I also used a old Forth system for DOS that provided the words INT: ;INT which allowed you to create hi-level Forth words that had the appropriate code to enter and exit as an ISR, when called by an interrupt. (this extra code was Assembler) You could then install the address of the INT: word into the system's interrupt table and it would run seamlessly. This to me seems like a nice Forth solution... extend the compiler to make the job simple.

TG9541 commented 6 years ago

STM8 eForth takes this approach:

After the context switch, the interrupt routine uses a small private data stack which doesn't need to be balanced.

In STM8 eForth there is also a preemptive background task which can use character I/O, and there is a console idle task (which should be careful with character I/O).

paraplegic commented 6 years ago

so basically, an interrupt handler would take the address of the service routine, and move it to the return stack of the currently executing word? Nice ...

' isr >r

Hmmm ...

On Sat, 21 Jul 2018, Garth Wilson wrote:

Date: Sat, 21 Jul 2018 14:44:03 -0700 From: Garth Wilson notifications@github.com Reply-To: ForthHub/discussion <reply+0025a5129b6ac9527feaea98538b2af303e2274829c3022892cf00000001176b6b2 392a169ce14772f55@reply.github.com> To: ForthHub/discussion discussion@noreply.github.com Cc: Subscribed subscribed@noreply.github.com Subject: Re: [ForthHub/discussion] How Forth handles hardware interuptions (#70)

I sent this a few minutes ago, but it looks like I used the wrong reply address.? Here it is again.

-------- Forwarded Message --------

Subject:

Re: [ForthHub/discussion] How Forth handles hardware interuptions (#70)

Date: Sat, 21 Jul 2018 14:38:52 -0700

From: Garth Wilson wilsonmines@dslextreme.com

To: Quentin Quadrat notifications@github.com

I did it in ITC Forth on a 6502 in about 1990 and wrote it up at http://wilsonminesco.com/0-overhead_Forth_interrupts/ .?I envisioned a way to do it without overhead.? Several people told me it couldn't be done, which of course only fueled my fire.? The result I've been using for 28 years now is described here.? I wanted it for the production automated test equipment (ATE) I designed and programmed, shown here.? The RS-232 input from the PC for software development was handled at 9600 bps through a 65C51 ACIA entirely by interrupts in high-level Forth on a 2MHz 65C02.

One man told me that he always does interrupts in assembly for speed, so he wasn't very interested in high-level Forth interrupt service.? The nice thing here is that when you eliminate the overhead, you get some of the speed back.? (Also, error-reporting and handling becomes easier.)? You can of course still have assembly-language ISRs also if you like, and they will get priority over the Forth ISRs.

The zero-overhead interrupt support is simple, adds only about 100 bytes to your overall code, and can be nested?ie, you can allow a higher-priority interrupt to interrupt the servicing of a lower-priority one?as many interrupt levels deep as you wish.? No additional stacks are required.? It's another natural for Forth.? As usual for interrupts, some assembly is required to get the system going, but very little.

I call it "zero-overhead" interrupt response because when an interrupt occurs, the Forth system moves right into the interrupt-service routine (ISR) just as if it were part of the normal code.? Simply put, it is as if a new word was suddenly inserted into the executing code?a word whose stack effect is ( -- ).

Garth

? On 07/21/2018 01:56 PM, Quentin Quadrat wrote:

Hi everybody, I have a noob question. I'm working on embedded systems written in C. I'm too young to have worked with Forth in professional projects, I hardly know how to write Forth scripts but I know how to make my own Forth interpreter. When Forth is embedded inside a micro-controller, how do you manage hardware interruptions routines (ISR) ? For example: reading the ADC value and filter the value or getting the I2C message ? In C code I'm accustomed to have an ISR table with the correct pointers on your ISR functions. When an interruption occurs your routine is called. How in Forth this is managed ? Do you write the code of the routine directly in asm ? Or do you create a task for polling the register (ugly way) ? Or has it a way to do it directly with Forth words. Thanks ? You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread. {"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/ForthHub/discussion","title":"ForthHub/discuss ion","subtitle":"GitHubrepository","main_image_url":"https://assets-cdn.github.com/images/email/message_cards/header.png","avatar_image_url":"https://assets-cdn.github.com/images/email/message_cards /avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/ForthHub/discussion"}},"updates":{"snippets":[{"icon":"DESCRIPTION","message":"How Forth handles hardware interuptions (#70)"}],"action":{"name":"View Issue","url":"https://github.com/ForthHub/discussion/issues/70"}}} [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/ForthHub/discussion/issues/70", "url": "https://github.com/ForthHub/discussion/issues/70", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } }, { "@type": "MessageCard", "@context": "http://schema.org/extensions", "hideOriginalBody": "false", "originator": "AF6C5A86-E920-430C-9C59-A73278B5EFEB", "title": "How Forth handles hardware interuptions (#70)", "sections": [ { "text": "", "activityTitle": "Quentin Quadrat", "activityImage": "https://assets-cdn.github.com/images/email/message_cards/avatar.png", "activitySubtitle": "@Lecrapouille", "facts": [ { "name": "Repository: ", "value": "ForthHub/discussion" }, { "name": "Issue #: ", "value": 70 } ] } ], "potentialAction": [ { "name": "Add a comment", "@type": "ActionCard", "inputs": [ { "isMultiLine": true, "@type": "TextInput", "id": "IssueComment", "isRequired": false } ], "actions": [ { "name": "Comment", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueComment\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70,\n\"IssueComment\": \"{{IssueComment.value}}\"\n}" } ] }, { "name": "Close issue", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueClose\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70\n}" }, { "targets": [ { "os": "default", "uri": "https://github.com/ForthHub/discussion/issues/70" } ], "@type": "OpenUri", "name": "View on GitHub" }, { "name": "Unsubscribe", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"MuteNotification\",\n\"threadId\": 359074464\n}" } ], "themeColor": "26292E" } ]

? You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.[ACWlEk78akwNkJtjGlM_7QJCtL1WlyG2ks5uI6CjgaJpZM4VZwqg.gif]

-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Robert S. Sciuk rob@controlq.com Principal Consultant 905.706.1354 Control-Q Research 97 Village Rd. Wellesley, ON N0B 2T0

pebhidecs commented 6 years ago

On 22/07/2018 at 10:55 PM, "Rob Sciuk" notifications@github.com wrote:

so basically, an interrupt handler would take the address of the service routine, and move it to the return stack of the currently executing word? Nice ...

' isr >r

Hmmm ...

On some Forth systems, it is literally that simple. As I said, make your ISR stacks completely neutral and everything is already where it will be safe for when you return.

Regards

Paul E. Bennett IEng MIET Systems Engineer Lunar Mission One Ambassador --


Paul E. Bennett IEng MIET..... Forth based HIDECS Consultancy............. Mob: +44 (0)7811-639972 Tel: +44 (0)1392-426688 Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..


MitchBradley commented 6 years ago

That approach can play havoc if the currently executing word is using the return stack explicitly, or implicitly for things like DO .. LOOP.  Better to push the current IP onto the return stack and then point IP at the ISR.  Essentially EXECUTE the ISR as a colon definition.

On 7/22/2018 12:13 PM, Paul E. Bennett IEng MIET wrote:

On 22/07/2018 at 10:55 PM, "Rob Sciuk" notifications@github.com wrote:

so basically, an interrupt handler would take the address of the service routine, and move it to the return stack of the currently executing word? Nice ...

' isr >r

Hmmm ...

On some Forth systems, it is literally that simple. As I said, make your ISR stacks completely neutral and everything is already where it will be safe for when you return.

Regards

Paul E. Bennett IEng MIET Systems Engineer Lunar Mission One Ambassador --


Paul E. Bennett IEng MIET..... Forth based HIDECS Consultancy............. Mob: +44 (0)7811-639972 Tel: +44 (0)1392-426688 Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..


— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ForthHub/discussion/issues/70#issuecomment-406901211, or mute the thread https://github.com/notifications/unsubscribe-auth/AEoszSsqX3HuADiMQMfbyi9LCHrphF4Aks5uJPkXgaJpZM4VZwqg.

GarthWilson commented 6 years ago
If you're referring still to my article
  at http://wilsonminesco.com/0-overhead_Forth_interrupts/, it does
  not play havoc on anything.  It does essentially EXECUTE
  the ISR as a colon definition, except that the ISR's replacement
  for unnest (which I called SYSRTI) is a word
  that also restores the ability to interrupt if appropriate.  It
  does not matter if the interrupt occurs during the execution of a
  DO...LOOP, or while the main program is storing
  things on the return stack with >R and R>,
  or compiling a CASE structure, or anything else.  I've
  been using it for about 28 years with no problems at all.

  I've done it a couple of different ways (both in ITC Forth).

  On the 8-bit 6502, since the 16-bit W and IP cannot be handled all
  in one gulp, the Y register is used as an index for one byte then
  decremented for the other byte.  But!  With the interrupt system,
  rather than starting by loading Y with a constant 1 (ie, load
  immediate), we load it instead from a byte variable (which I
  called irqnot).  Normally the variable contains a 1; but
  if there's an interrupt pending, the tiny routine in machine
  language that registered the interrupt request will have set that
  variable to 0.  NEXT tests it (the 6502 tests against 0
  as an automatic, implied part of the loading, so it's not an extra
  instruction) and branches to a different version of NEXT
  if it's 0.  This latter version is actually faster than
  the non-interrupt version, because it doesn't have to increment
  the instruction pointer when going to the interrupt-handling
  word.  If it did increment it, the ISR would be replacing
  the next Forth instruction in the main code instead of delaying
  it.

  I did it differently with the 65816 which has 16-bit registers. 
  There I used a variable holding the address of the desired version
  of NEXT.  The tiny machine-language routine that
  registered the interrupt request changes the address in that
  variable.  Then, instead of the usual absolute jump-to-NEXT
  at the end of each Forth word, the instruction is a jump indirect,
  to the address pointed to by that variable.  The ISR version of NEXT
  resets that address to the regular one for the next time NEXT
  runs.  An extra possibility afforded by doing it this way
  (although I have not gone through with this part) is that you
  could have different versions of NEXT pointed to by the
  variable, for things like single-step and instruction trace.

  ITC Forth is not the best-performing; but it does offer certain
  advantages.  I've been wanting to write a STC Forth for the 65816,
  but then servicing interrupts in high-level Forth would get more
  complicated.  The generally best-performing STC method uses a
  single one-byte instruction for NEXT, but is not well
  suited for good interrupt performance.

  On 07/22/2018 06:43 PM, Mitch Bradley wrote:

That
  approach can play havoc if the currently executing word is using
  the return stack explicitly, or implicitly for things like DO ..
  LOOP. 
  Better to push the current IP onto the return stack and then point
  IP at
  the ISR.  Essentially EXECUTE the ISR as a colon definition.

  On 7/22/2018 12:13 PM, Paul E. Bennett IEng MIET wrote:
  > On 22/07/2018 at 10:55 PM, "Rob Sciuk"
  <notifications@github.com> wrote:
  > >
  > >so basically, an interrupt handler would take the address
  of the
  > >service
  > >routine, and move it to the return stack of the currently
  > >executing word?
  > >Nice ...
  > >
  > > ' isr >r
  > >
  > >Hmmm ...
  >
  > On some Forth systems, it is literally that simple. As I
  said, make your
  > ISR stacks completely neutral and everything is already where
  it will be
  > safe for when you return.
  >
  > Regards
  >
  > Paul E. Bennett IEng MIET
  > Systems Engineer
  > Lunar Mission One Ambassador
  > -- 
  >
  ********************************************************************
  > Paul E. Bennett IEng MIET.....
  > Forth based HIDECS Consultancy.............
  > Mob: +44 (0)7811-639972
  > Tel: +44 (0)1392-426688
  > Going Forth Safely ..... EBA.
  www.electric-boat-association.org.uk..
  >
  ********************************************************************
  >
  > —
  > You are receiving this because you are subscribed to this
  thread.
  > Reply to this email directly, view it on GitHub
  >

https://github.com/ForthHub/discussion/issues/70#issuecomment-406901211,

or mute the thread

https://github.com/notifications/unsubscribe-auth/AEoszSsqX3HuADiMQMfbyi9LCHrphF4Aks5uJPkXgaJpZM4VZwqg.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread. {"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/ForthHub/discussion","title":"ForthHub/discussion","subtitle":"GitHub repository","main_image_url":"https://assets-cdn.github.com/images/email/message_cards/header.png","avatar_image_url":"https://assets-cdn.github.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/ForthHub/discussion"}},"updates":{"snippets":[{"icon":"PERSON","message":"@MitchBradley in #70: That approach can play havoc if the currently executing word is using\nthe return stack explicitly, or implicitly for things like DO .. LOOP. \nBetter to push the current IP onto the return stack and then point IP at\nthe ISR.  Essentially EXECUTE the ISR as a colon definition.\n\nOn 7/22/2018 12:13 PM, Paul E. Bennett IEng MIET wrote:\n\u003e On 22/07/2018 at 10:55 PM, \"Rob Sciuk\" \u003cnotifications@github.com\u003e wrote:\n\u003e \u003e\n\u003e \u003eso basically, an interrupt handler would take the address of the\n\u003e \u003eservice\n\u003e \u003eroutine, and move it to the return stack of the currently\n\u003e \u003eexecuting word?\n\u003e \u003eNice ...\n\u003e \u003e\n\u003e \u003e ' isr \u003er\n\u003e \u003e\n\u003e \u003eHmmm ...\n\u003e\n\u003e On some Forth systems, it is literally that simple. As I said, make your\n\u003e ISR stacks completely neutral and everything is already where it will be\n\u003e safe for when you return.\n\u003e\n\u003e Regards\n\u003e\n\u003e Paul E. Bennett IEng MIET\n\u003e Systems Engineer\n\u003e Lunar Mission One Ambassador\n\u003e -- \n\u003e ****\n\u003e Paul E. Bennett IEng MIET.....\n\u003e Forth based HIDECS Consultancy.............\n\u003e Mob: +44 (0)7811-639972\n\u003e Tel: +44 (0)1392-426688\n\u003e Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..\n\u003e ****\n\u003e\n\u003e —\n\u003e You are receiving this because you are subscribed to this thread.\n\u003e Reply to this email directly, view it on GitHub\n\u003e \u003chttps://github.com/ForthHub/discussion/issues/70#issuecomment-406901211\u003e,\n\u003e or mute the thread\n\u003e \u003chttps://github.com/notifications/unsubscribe-auth/AEoszSsqX3HuADiMQMfbyi9LCHrphF4Aks5uJPkXgaJpZM4VZwqg\u003e.\n\u003e\n"}],"action":{"name":"View Issue","url":"https://github.com/ForthHub/discussion/issues/70#issuecomment-406915777"}}} [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/ForthHub/discussion/issues/70#issuecomment-406915777", "url": "https://github.com/ForthHub/discussion/issues/70#issuecomment-406915777", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } }, { "@type": "MessageCard", "@context": "http://schema.org/extensions", "hideOriginalBody": "false", "originator": "AF6C5A86-E920-430C-9C59-A73278B5EFEB", "title": "Re: [ForthHub/discussion] How Forth handles hardware interuptions (#70)", "sections": [ { "text": "", "activityTitle": "Mitch Bradley", "activityImage": "https://assets-cdn.github.com/images/email/message_cards/avatar.png", "activitySubtitle": "@MitchBradley", "facts": [

] } ], "potentialAction": [ { "name": "Add a comment", "@type": "ActionCard", "inputs": [ { "isMultiLine": true, "@type": "TextInput", "id": "IssueComment", "isRequired": false } ], "actions": [ { "name": "Comment", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueComment\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70,\n\"IssueComment\": \"{{IssueComment.value}}\"\n}" } ] }, { "name": "Close issue", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueClose\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70\n}" }, { "targets": [ { "os": "default", "uri": "https://github.com/ForthHub/discussion/issues/70#issuecomment-406915777" } ], "@type": "OpenUri", "name": "View on GitHub" }, { "name": "Unsubscribe", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"MuteNotification\",\n\"threadId\": 359074464\n}" } ], "themeColor": "26292E" } ]

paraplegic commented 6 years ago

On Sun, 22 Jul 2018, Mitch Bradley wrote:

Date: Sun, 22 Jul 2018 18:43:11 -0700 From: Mitch Bradley notifications@github.com Reply-To: ForthHub/discussion <reply+0025a512441b323e2d561bf4b25cf114cce54a8059f3471092cf00000001176cf4a f92a169ce14772f55@reply.github.com> To: ForthHub/discussion discussion@noreply.github.com Cc: Rob Sciuk rob@controlq.com, Comment comment@noreply.github.com Subject: Re: [ForthHub/discussion] How Forth handles hardware interuptions (#70)

That approach can play havoc if the currently executing word is using the return stack explicitly, or implicitly for things like DO .. LOOP.? Better to push the current IP onto the return stack and then point IP at the ISR.? Essentially EXECUTE the ISR as a colon definition.

Ah, many DO LOOP implementations use the return stack for counters ... as an example of Mitch's assertion, so yes, that approach is a bit too simplistic ... though it has about the right instruction count to keep latency down ... perhaps a dedicated interrupt stack might be a way around this.

On 7/22/2018 12:13 PM, Paul E. Bennett IEng MIET wrote:

On 22/07/2018 at 10:55 PM, "Rob Sciuk" notifications@github.com wrote:

so basically, an interrupt handler would take the address of the service routine, and move it to the return stack of the currently executing word? Nice ...

' isr >r

Hmmm ...

On some Forth systems, it is literally that simple. As I said, make your ISR stacks completely neutral and everything is already where it will be safe for when you return.

Regards

Paul E. Bennett IEng MIET Systems Engineer Lunar Mission One Ambassador


Paul E. Bennett IEng MIET..... Forth based HIDECS Consultancy............. Mob: +44 (0)7811-639972 Tel: +44 (0)1392-426688 Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..


? You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ForthHub/discussion/issues/70#issuecomment-406901211, or mute the thread https://github.com/notifications/unsubscribe-auth/AEoszSsqX3HuADiMQMfbyi9LCHrphF4Aks5uJPkXgaJpZM4VZwqg.

? You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.[ACWlEqjmWDck919W4lZy1kJgy-9DQbTnks5uJSovgaJpZM4VZwqg.gif]

-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Robert S. Sciuk rob@controlq.com Principal Consultant 905.706.1354 Control-Q Research 97 Village Rd. Wellesley, ON N0B 2T0

GarthWilson commented 6 years ago
On 07/22/2018 08:25 PM, Rob Sciuk
  wrote:

On
  Sun, 22 Jul 2018, Mitch Bradley wrote:

  > Date: Sun, 22 Jul 2018 18:43:11 -0700
  > From: Mitch Bradley <notifications@github.com>
  > Reply-To: ForthHub/discussion
  >

<reply+0025a512441b323e2d561bf4b25cf114cce54a8059f3471092cf00000001176cf4a

f92a169ce14772f55@reply.github.com> To: ForthHub/discussion discussion@noreply.github.com Cc: Rob Sciuk rob@controlq.com, Comment comment@noreply.github.com Subject: Re: [ForthHub/discussion] How Forth handles hardware interuptions (#70)

That approach can play havoc if the currently executing word is using the return stack explicitly, or implicitly for things like DO .. LOOP.? Better to push the current IP onto the return stack and then point IP at the ISR.? Essentially EXECUTE the ISR as a colon definition.

  Ah, many DO LOOP implementations use the return stack for counters
  ... as 
  an example of Mitch's assertion, so yes, that approach is a bit
  too 
  simplistic

Not at all.  The only thing that would be a danger would be if you
use stack cells (on any stack, whether return, data,
floating-point, whatever) that are beyond where the stack pointer
points, ie, already dropped, which is pretty much a no-no anyway,
regardless of how interrupts are handled.  You cannot depend on them
being left undisturbed if there's any kind of interrupt.  As long as
a stack is used as a stack, there's no problem.

  ... though it has about the right instruction count to keep 
  latency down ... perhaps a dedicated interrupt stack might be a
  way around 
  this.

  > 
  > On 7/22/2018 12:13 PM, Paul E. Bennett IEng MIET wrote:
  > > On 22/07/2018 at 10:55 PM, "Rob Sciuk"
  <notifications@github.com> wrote:
  > > >
  > > >so basically, an interrupt handler would take the
  address of the
  > > >service
  > > >routine, and move it to the return stack of the
  currently
  > > >executing word?
  > > >Nice ...
  > > >
  > > > ' isr >r
  > > >
  > > >Hmmm ...
  > >
  > > On some Forth systems, it is literally that simple. As I
  said, make your
  > > ISR stacks completely neutral and everything is already
  where it will be
  > > safe for when you return.
  > >
  > > Regards
  > >
  > > Paul E. Bennett IEng MIET
  > > Systems Engineer
  > > Lunar Mission One Ambassador
  > > --
  > >
  ********************************************************************
  > > Paul E. Bennett IEng MIET.....
  > > Forth based HIDECS Consultancy.............
  > > Mob: +44 (0)7811-639972
  > > Tel: +44 (0)1392-426688
  > > Going Forth Safely ..... EBA.
  www.electric-boat-association.org.uk..
  > >
  ********************************************************************
  > >
  > > ?
  > > You are receiving this because you are subscribed to
  this thread.
  > > Reply to this email directly, view it on GitHub
  > >

https://github.com/ForthHub/discussion/issues/70#issuecomment-406901211,

or mute the thread

https://github.com/notifications/unsubscribe-auth/AEoszSsqX3HuADiMQMfbyi9LCHrphF4Aks5uJPkXgaJpZM4VZwqg.

? You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.[ACWlEqjmWDck919W4lZy1kJgy-9DQbTnks5uJSovgaJpZM4VZwqg.gif]

  -- 

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Robert S. Sciuk rob@controlq.com Principal Consultant 905.706.1354 Control-Q Research 97 Village Rd. Wellesley, ON N0B 2T0 — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread. {"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/ForthHub/discussion","title":"ForthHub/discussion","subtitle":"GitHub repository","main_image_url":"https://assets-cdn.github.com/images/email/message_cards/header.png","avatar_image_url":"https://assets-cdn.github.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/ForthHub/discussion"}},"updates":{"snippets":[{"icon":"PERSON","message":"@paraplegic in #70: On Sun, 22 Jul 2018, Mitch Bradley wrote:\n\n\u003e Date: Sun, 22 Jul 2018 18:43:11 -0700\n\u003e From: Mitch Bradley \u003cnotifications@github.com\u003e\n\u003e Reply-To: ForthHub/discussion\n\u003e \u003creply+0025a512441b323e2d561bf4b25cf114cce54a8059f3471092cf00000001176cf4a\n\u003e f92a169ce14772f55@reply.github.com\u003e\n\u003e To: ForthHub/discussion \u003cdiscussion@noreply.github.com\u003e\n\u003e Cc: Rob Sciuk \u003crob@controlq.com\u003e, Comment \u003ccomment@noreply.github.com\u003e\n\u003e Subject: Re: [ForthHub/discussion] How Forth handles hardware interuptions\n\u003e (#70)\n\u003e \n\u003e That approach can play havoc if the currently executing word is using\n\u003e the return stack explicitly, or implicitly for things like DO .. LOOP.?\n\u003e Better to push the current IP onto the return stack and then point IP at\n\u003e the ISR.? Essentially EXECUTE the ISR as a colon definition.\n\nAh, many DO LOOP implementations use the return stack for counters ... as \nan example of Mitch's assertion, so yes, that approach is a bit too \nsimplistic ... though it has about the right instruction count to keep \nlatency down ... perhaps a dedicated interrupt stack might be a way around \nthis.\n\n\u003e \n\u003e On 7/22/2018 12:13 PM, Paul E. Bennett IEng MIET wrote:\n\u003e \u003e On 22/07/2018 at 10:55 PM, \"Rob Sciuk\" \u003cnotifications@github.com\u003e wrote:\n\u003e \u003e \u003e\n\u003e \u003e \u003eso basically, an interrupt handler would take the address of the\n\u003e \u003e \u003eservice\n\u003e \u003e \u003eroutine, and move it to the return stack of the currently\n\u003e \u003e \u003eexecuting word?\n\u003e \u003e \u003eNice ...\n\u003e \u003e \u003e\n\u003e \u003e \u003e ' isr \u003er\n\u003e \u003e \u003e\n\u003e \u003e \u003eHmmm ...\n\u003e \u003e\n\u003e \u003e On some Forth systems, it is literally that simple. As I said, make your\n\u003e \u003e ISR stacks completely neutral and everything is already where it will be\n\u003e \u003e safe for when you return.\n\u003e \u003e\n\u003e \u003e Regards\n\u003e \u003e\n\u003e \u003e Paul E. Bennett IEng MIET\n\u003e \u003e Systems Engineer\n\u003e \u003e Lunar Mission One Ambassador\n\u003e \u003e --\n\u003e \u003e ****\n\u003e \u003e Paul E. Bennett IEng MIET.....\n\u003e \u003e Forth based HIDECS Consultancy.............\n\u003e \u003e Mob: +44 (0)7811-639972\n\u003e \u003e Tel: +44 (0)1392-426688\n\u003e \u003e Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..\n\u003e \u003e ****\n\u003e \u003e\n\u003e \u003e ?\n\u003e \u003e You are receiving this because you are subscribed to this thread.\n\u003e \u003e Reply to this email directly, view it on GitHub\n\u003e \u003e \u003chttps://github.com/ForthHub/discussion/issues/70#issuecomment-406901211\u003e,\n\u003e \u003e or mute the thread\n\u003e \u003e \u003chttps://github.com/notifications/unsubscribe-auth/AEoszSsqX3HuADiMQMfbyi9LCHrphF4Aks5uJPkXgaJpZM4VZwqg\u003e.\n\u003e \u003e\n\u003e \n\u003e ?\n\u003e You are receiving this because you commented.\n\u003e Reply to this email directly, view it on GitHub, or mute the thread.[ACWlEqjmWDck919W4lZy1kJgy-9DQbTnks5uJSovgaJpZM4VZwqg.gif]\n\u003e \n\u003e \n\u003e\n\n-- \n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\nRobert S. Sciuk rob@controlq.com\nPrincipal Consultant 905.706.1354\nControl-Q Research 97 Village Rd. Wellesley, ON N0B 2T0\n"}],"action":{"name":"View Issue","url":"https://github.com/ForthHub/discussion/issues/70#issuecomment-406928771"}}} [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/ForthHub/discussion/issues/70#issuecomment-406928771", "url": "https://github.com/ForthHub/discussion/issues/70#issuecomment-406928771", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } }, { "@type": "MessageCard", "@context": "http://schema.org/extensions", "hideOriginalBody": "false", "originator": "AF6C5A86-E920-430C-9C59-A73278B5EFEB", "title": "Re: [ForthHub/discussion] How Forth handles hardware interuptions (#70)", "sections": [ { "text": "", "activityTitle": "Rob Sciuk", "activityImage": "https://assets-cdn.github.com/images/email/message_cards/avatar.png", "activitySubtitle": "@paraplegic", "facts": [

] } ], "potentialAction": [ { "name": "Add a comment", "@type": "ActionCard", "inputs": [ { "isMultiLine": true, "@type": "TextInput", "id": "IssueComment", "isRequired": false } ], "actions": [ { "name": "Comment", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueComment\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70,\n\"IssueComment\": \"{{IssueComment.value}}\"\n}" } ] }, { "name": "Close issue", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueClose\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70\n}" }, { "targets": [ { "os": "default", "uri": "https://github.com/ForthHub/discussion/issues/70#issuecomment-406928771" } ], "@type": "OpenUri", "name": "View on GitHub" }, { "name": "Unsubscribe", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"MuteNotification\",\n\"threadId\": 359074464\n}" } ], "themeColor": "26292E" } ]

TG9541 commented 6 years ago

@Lecrapouille I still consider myself a Forth newbie, but I hold it as a fact that whenever Forthers meet they feel compelled to not only discuss the problem but also the advantage of "their Forth", or their aptness to compare any Forth. I love it.

The discussion above discus Forth implementations that use an Inner Interpreter (ITC, DTC...) for switching to the ISR. Here it's generally simple (but as @MitchBradley points out sometimes not). The Inner Interpreter (NEXT) injects your ISR into the execution flow, and that's it. Your worst case latency is basically the time it takes to execute the longest primitive word (e.g. /).

Some other Forth (STC) compile to machine code, and don't have an inner interpreter proper. There, one usually relies on the ISR capabilities of a µC (just like in C), and one has to perform a context switch (the µCs interrupt feature often does the bulk of it).

All the implementation approaches certainly have their pros and cons, and that's why it's fun ;-)

Mecrisp commented 6 years ago

On Mecrisp-Stellaris, which is a native code Forth for ARM Cortex, you can directly use a normal ( -- ) definition as interrupt handler:

: adc-handler ( -- ) ... ;

: initialisation ( -- ) ... ['] adc-handler irq-adc0seq0 ! ... ;

No special framework necessary, but this depends on the Forth implementation and the underlying CPU you are using.

Matthias

Hi everybody, I have a noob question. I'm working on embedded systems written in C. I'm too young to have worked with Forth in professional projects, I hardly know how to write Forth scripts but I know how to make my own Forth interpreter.

When Forth is embedded inside a micro-controller, how do you manage hardware interruptions routines (ISR) ? For example: reading the ADC value and filter the value or getting the I2C message ? In C code I'm accustomed to have an ISR table with the correct pointers on your ISR functions. When an interruption occurs your routine is called.

How in Forth this is managed ? Do you write the code of the routine directly in asm ? Or do you create a task for polling the register (ugly way) ? Or has it a way to do it directly with Forth words.

Thanks

TG9541 commented 6 years ago

@Mecrisp Matthias, this makes me curious - how do you deal with the data stack pointer?

GarthWilson commented 6 years ago
I'm not Mecrisp; but in case it takes
  him a while to respond, I, the interrupt junkie, will jump in
  again.  Thomas, it's no different from any other Forth word that
  expects no input on the stack(s) and leaves no output.  That's one
  of the beauties of a stack-based system.  It doesn't matter what's
  on the stack(s) when the interrupt hits, nor how deep it is. 
  Cells there remain undisturbed.  The only difference in my Forth
  ISR words is to re-enable interrupts if/when appropriate.

  On 07/23/2018 12:18 PM, Thomas wrote:

  @Mecrisp
    Matthias, this makes me curious - how do you deal with the data
    stack pointer?
  —
    You are receiving this because you commented.
    Reply to this email directly, view it on GitHub, or mute the thread.
  {"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/ForthHub/discussion","title":"ForthHub/discussion","subtitle":"GitHub repository","main_image_url":"https://assets-cdn.github.com/images/email/message_cards/header.png","avatar_image_url":"https://assets-cdn.github.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/ForthHub/discussion"}},"updates":{"snippets":[{"icon":"PERSON","message":"@TG9541 in #70: @Mecrisp Matthias, this makes me curious - how do you deal with the data stack pointer? "}],"action":{"name":"View Issue","url":"https://github.com/ForthHub/discussion/issues/70#issuecomment-407170656"}}}
  [

{ "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/ForthHub/discussion/issues/70#issuecomment-407170656", "url": "https://github.com/ForthHub/discussion/issues/70#issuecomment-407170656", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } }, { "@type": "MessageCard", "@context": "http://schema.org/extensions", "hideOriginalBody": "false", "originator": "AF6C5A86-E920-430C-9C59-A73278B5EFEB", "title": "Re: [ForthHub/discussion] How Forth handles hardware interuptions (#70)", "sections": [ { "text": "", "activityTitle": "Thomas", "activityImage": "https://assets-cdn.github.com/images/email/message_cards/avatar.png", "activitySubtitle": "@TG9541", "facts": [

] } ], "potentialAction": [ { "name": "Add a comment", "@type": "ActionCard", "inputs": [ { "isMultiLine": true, "@type": "TextInput", "id": "IssueComment", "isRequired": false } ], "actions": [ { "name": "Comment", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueComment\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70,\n\"IssueComment\": \"{{IssueComment.value}}\"\n}" } ] }, { "name": "Close issue", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueClose\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70\n}" }, { "targets": [ { "os": "default", "uri": "https://github.com/ForthHub/discussion/issues/70#issuecomment-407170656" } ], "@type": "OpenUri", "name": "View on GitHub" }, { "name": "Unsubscribe", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"MuteNotification\",\n\"threadId\": 359074464\n}" } ], "themeColor": "26292E" } ]

Lecrapouille commented 6 years ago

Thanks for all your answers that helped me understand better and sorry for not having replied sooner !

@TG9541 yes it does not exist a single Forth standard language but a several Forth: one for each implementor. This is something cool for competitions for innovation but gives hard job for beginners :)

@GarthWilson nice article I'm too novice to understand everything.

@pebhidecs:

May I digress the conversion a little but that makes me remind something that I learned but not so much documented for beginners: when you make a word definition you also have to let the data stack neutral. What does "neutral" really mean ? Ok for not touching at the stack depth ! What about the content of the data stack? for example the following code:

: foo [ 3 ] ;

is refused (because of changing the depth). This one accepted by pforth but not by gforth:

: foo [ literal 3 ] ;

(ok this is a bad example because literal is added during compilation and forbidden at interpretation but could be an alias for pushing 3). And what about this one:

1 2
: foo [ swap ] ;

only accepted by pforth: the data stack will be 2 1. So I guess that for ISR similar security has to done.

@MitchBradley saving the IP: I never liked Forth for letting the developer storing datum inside the R stack. I know this is so crucial like defining words DO LOOP or nice hacks by injecting CFA, as well as for helping swapping data stack elements by saving memory with a 2nd data stack and that was something important in 70's but nowadays why not having a 3thd (auxiliary) stack and making the return stack fully private. This looks safer (I may be wrong but it seems that what 4th does).

TG9541 commented 6 years ago

@GarthWilson thanks for your answer! I infer that the assumption that a controller register always contains a valid data stack pointer is most often true :-)

GarthWilson commented 6 years ago
IMO, this stuff is easy to understand,
  but difficult to communicate.  Depending on the outcome of this
  discussion, I might find ways to make it more clear in my
  article.  That was one of the first articles I ever wrote, decades
  ago, and hopefully my writing has improved since then anyway.

  After my last response here, I realized what someone else must
  have been thinking, regarding messing up the return stack, about
  the interrupt being registered with something like ' ISR
    >R as someone else posted.  Yes, that would indeed mess
  up the return stack.  It's less efficient anyway though, and I
  don't see any point in doing it that way.

  The way I'm referring to does not put an address on the stack for
  an unnest (or dosemi, or whatever the
  equivalent might be called in your system) to take.  In fact, that
  would be for waiting for a secondary (or colon definition) to
  finish before the ISR can run, since primitives don't end in unnest. 
  There are various ways to implement interrupt service in
  high-level Forth, depending of course on the threading method and
  on the processor too I suppose; but what I was referring to leaves
  primitives (ie, code definitions) atomic, but the interrupt can be
  serviced between any two primitives, regardless of any
  secondaries' boundaries.

  When an interrupt hits, a machine-language ISR (which may get run
  during a primitive's execution) changes my variable and
  exits in a way that won't immediately re-enable interrupt
  reception.  There is no net stack effect at all.  Rather than
  using addresses (or anything else) on either stack, the content is
  left in the variable (not on stack) for NEXT to load and
  simultaneously compare to zero, and branch to a different version
  of NEXT if the content of that variable indicates
  there's an interrupt waiting to be serviced.

  For the 65816 processor, I did it a little different, using JMP
    (NEXTadr) (ie, an indirect jump to the address of the
  desired NEXT version, rather than JMP NEXT
  (ie, a direct jump).  The indirect jump is not a quick as the
  direct jump, but the requirement of a conditional branch in NEXT
  is eliminated.  Still, there's no net stack effect.

  On 07/23/2018 09:36 PM, Thomas wrote:

  @GarthWilson
    thanks for your answer! I infer that the assumption that a
    controller register always contains a valid data stack pointer
    is most often true :-)
  —
    You are receiving this because you were mentioned.
    Reply to this email directly, view it on GitHub, or mute the thread.
  {"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/ForthHub/discussion","title":"ForthHub/discussion","subtitle":"GitHub repository","main_image_url":"https://assets-cdn.github.com/images/email/message_cards/header.png","avatar_image_url":"https://assets-cdn.github.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/ForthHub/discussion"}},"updates":{"snippets":[{"icon":"PERSON","message":"@TG9541 in #70: @GarthWilson thanks for your answer! I infer that the assumption that a controller register always contains a valid data stack pointer is most often true :-)"}],"action":{"name":"View Issue","url":"https://github.com/ForthHub/discussion/issues/70#issuecomment-407278242"}}}
  [

{ "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/ForthHub/discussion/issues/70#issuecomment-407278242", "url": "https://github.com/ForthHub/discussion/issues/70#issuecomment-407278242", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } }, { "@type": "MessageCard", "@context": "http://schema.org/extensions", "hideOriginalBody": "false", "originator": "AF6C5A86-E920-430C-9C59-A73278B5EFEB", "title": "Re: [ForthHub/discussion] How Forth handles hardware interuptions (#70)", "sections": [ { "text": "", "activityTitle": "Thomas", "activityImage": "https://assets-cdn.github.com/images/email/message_cards/avatar.png", "activitySubtitle": "@TG9541", "facts": [

] } ], "potentialAction": [ { "name": "Add a comment", "@type": "ActionCard", "inputs": [ { "isMultiLine": true, "@type": "TextInput", "id": "IssueComment", "isRequired": false } ], "actions": [ { "name": "Comment", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueComment\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70,\n\"IssueComment\": \"{{IssueComment.value}}\"\n}" } ] }, { "name": "Close issue", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"IssueClose\",\n\"repositoryFullName\": \"ForthHub/discussion\",\n\"issueId\": 70\n}" }, { "targets": [ { "os": "default", "uri": "https://github.com/ForthHub/discussion/issues/70#issuecomment-407278242" } ], "@type": "OpenUri", "name": "View on GitHub" }, { "name": "Unsubscribe", "@type": "HttpPOST", "target": "https://api.github.com", "body": "{\n\"commandName\": \"MuteNotification\",\n\"threadId\": 359074464\n}" } ], "themeColor": "26292E" } ]

Mecrisp commented 6 years ago

Exactly, stacks are interrupt-safe by design. Take care of maintaining the stacks in primitives; for example, do not "drop and compare later" in assembly, the stack always needs to be in a consistent state. And when using cooperative multitasking, context switches may be interrupted also. Valid stacks with enough memory for the desired depths plus the whole CPU interrupt frame need to be active all the time.

A nice debugging feature is that you can examine the data and return stacks of the just-interrupted code from within of a fault exception interrupt handler.

Besides the stacks, think of temporary registers; your CPU might or might not save them automatically, a special interrupt wrapper might be necessary. If your CPU does automatically push and pop some registers, these should be used for internal temporary variables. Best is to consider interrupts at the beginning of the design of a new Forth.