From: Enoch <ix...@ho...> - 2013-04-19 00:35:41
|
Hello Matthias, I hope that you would be interested in the following AmForth development. I will send you the patch under a separate cover. Regards, Enoch. ----------------------------------------------------------------- 1 Objective ------------ One of AmForth features is the ability to write interrupt service routines (ISRs) in Forth. However, in the existing implementation as of SVN r1423 those ISRs should run with the hardware interrupt system (SREG I-bit) disabled. This means that one has to keep those ISRs very short and defer long processing to the "main" (aka user mode). The following changes to the kernel introduce an eight level soft interrupt queue, allowing Forth ISRs to be interruptible and thus be as slow to execute as necessary (and even reentrant). 2 Implementation ----------------- To the existing +int and -int ("hard front-end") words that control the SREG I-bit the following ("soft rear-end") words were added: 2.1 int+ ( -- ) "soft interrupts on" ======================================= Enables the soft interrupts. By default soft interrupts are enabled. 2.2 int- ( -- ) "soft interrupts off" ======================================== Disables the soft interrupts. 2.3 int' ( -- addr ) "soft interrupts apostrophe" ==================================================== Returns the address of a system variable where the lower byte, if non zero, indicates the occurance of a hard interrupt overflow. The overflow mark is the interrupting-device program address. Clear this mark by: 0 int' c! The higher byte, if non-zero, indicates having the soft interrupts inhibited. 3 Compatibility ---------------- Existing code should not be affected. |
From: Enoch <ix...@ho...> - 2013-04-19 00:57:03
|
Hello Matthias, I hope that you would be interested in the following AmForth development. I will send you the patch under a separate cover. Regards, Enoch. http://pastebin.com/sDGsKjhb P/S It includes some unrelated (though desired) stuff such as cinvert to complement a byte, etc. |
From: Matthias T. <mt...@we...> - 2013-04-19 19:04:10
|
Hi Enoch, > I hope that you would be interested in the following AmForth > development. I will send you the patch under a separate cover. I am interested. And regardless what you think of what follows, I appreciate your work. > http://pastebin.com/sDGsKjhb A few remarks: Your patch include some pseudo changes to files that are not really changed (e.g. amforth-interpreter with some whitespace changes). I was slightly puzzeled wether I mis-read the patch until I was sure, that the changes are purely cosmetic. changing the r0 to temp0 is something very close. Second: Your patch steps behind what amforth has already solved years ago: If an interrupt source has to be cleared *within* the ISR, it will block the controller with your new code I once spent a lot of time to deal with the reasons. I wrote a small article for the German Forth Group, unfortunatly (for you) in German. It seems, I should translate it into (my version of) English ASAP. There I explain the current interrupt handling in more detail. Basically your patch is the old interrupt handling plus queue (A solution I once considered too, btw.) Third: What makes you sure that a queue with 8 entries can do the job? The code comments indicate, that you're not that sure yourself. The default action "Drop the interrupt" is IMHO the worst solution. And finally: What exactly is the use case of having a reentrant interrupt service routine? In my understanding of interrupts, this is a situation, that must be avoided at any price. e.g. it does not make much sense to process a character from the usart if the previous one is not already processed. Or to stack timer events. Re-enabling interrupts within the current ISR is no big deal. Just call +INT and you're done. New interrupts will arrive as they they are triggered. > P/S It includes some unrelated (though desired) stuff such as cinvert to > complement a byte, etc. There are many word that can be implemented in assembly as well. A theoretical use case doesn't convince me. A cinvert could be a factor for invert ;) Matthias |
From: Enoch <ix...@ho...> - 2013-04-20 00:48:11
|
Matthias Trute <mt...@we...> writes: >> I hope that you would be interested in the following AmForth >> development. I will send you the patch under a separate cover. > > I am interested. And regardless what you think of what > follows, I appreciate your work. > >> http://pastebin.com/sDGsKjhb Hello Matthias, I can assure you that I am "ego-less" as far as AmForth is concerned. I invite criticism, in fact, being ignored would be more painful. > A few remarks: Your patch include some pseudo changes to > files that are not really changed (e.g. amforth-interpreter > with some whitespace changes). I was slightly puzzeled wether > I mis-read the patch until I was sure, that the changes are > purely cosmetic. changing the r0 to temp0 is something very > close. My editor (Emacs) apologizes. It does not like your asm code indentation. Which one do you use, BTW. > Second: Your patch steps behind what amforth has already > solved years ago: If an interrupt source has to be cleared > *within* the ISR, it will block the controller with your new code In my soft interrupts handling scheme I am interested in Atmel's type I interrupts only. They are described by Atmel as follows: """ There are basically two types of interrupts. The first type is triggered by an event that sets the interrupt flag. For these interrupts, the Program Counter is vectored to the actual Interrupt Vector in order to execute the interrupt handling routine, and *hardware clears the corresponding interrupt flag*. """ The other type, like the USART, does need special asm code. Your serial driver is a case in point. > I once spent a lot of time to deal with the reasons. I wrote > a small article for the German Forth Group, unfortunatly (for you) > in German. It seems, I should translate it into (my version of) English > ASAP. There I explain the current interrupt handling in more detail. Google Translate does magic, please forward a link. > Basically your patch is the old interrupt handling plus queue (A solution > I once considered too, btw.) What I implemented is called SLIH (second level interrupt handling). It exists in all operating systems. I don't consider myself an inventor at all here. > Third: What makes you sure that a queue with 8 entries > can do the job? The code comments indicate, that you're > not that sure yourself. The default action "Drop the interrupt" > is IMHO the worst solution. Note that there is an overflow mark. If the developer encounters hard interrupts overflow he should increase this queue size (or check up his code). This can be done through some asm .equ convenience. > And finally: What exactly is the use case of having a reentrant > interrupt service routine? In my understanding of interrupts, this > is a situation, that must be avoided at any price. e.g. it does not > make much sense to process a character from the usart if the > previous one is not already processed. Or to stack timer events. This is what Wikipedia says about the purpose of SLIH: """ A SLIH completes long interrupt processing tasks similarly to a process. SLIHs either have a dedicated kernel thread for each handler, or are executed by a pool of kernel worker threads. These threads sit on a run queue in the operating system until processor time is available for them to perform processing for the interrupt. SLIHs may have a long-lived execution time, and thus are typically scheduled similarly to threads and processes. """ FLIH (first level interrupt handlers) and SLIH (second level interrupt handlers) were already introduced in the old IBM mainframe days. > Re-enabling interrupts within the current ISR is no big deal. Just > call +INT and you're done. New interrupts will arrive as they they > are triggered. Did you really try it, i.e., reenabling interrupts within an ISR? You do it and your 'intcur' gets crushed. After receipt of a data buffer from a certain communication euipment I want to lanuch immediately a processing activity, i.e., right from the ISR and not wait for a round robin task to visit. By the way, it's okay to have different opinions. We already read our stacks (".s") in different order :-) >> P/S It includes some unrelated (though desired) stuff such as cinvert to >> complement a byte, etc. > There are many word that can be implemented in assembly as well. > A theoretical use case doesn't convince me. A cinvert could be a > factor for invert ;) cinvert is indeed not important by Rafael's u2/ is! Regards, Enoch. |
From: Matthias T. <mt...@we...> - 2013-04-20 07:50:52
|
Hi Enoch, > My editor (Emacs) apologizes. It does not like your asm code > indentation. Which one do you use, BTW. Uhm. my own one. And a different one for each file. Probably. ;) > > > Second: Your patch steps behind what amforth has already > > solved years ago: If an interrupt source has to be cleared > > *within* the ISR, it will block the controller with your new code > > In my soft interrupts handling scheme I am interested in Atmel's type I > interrupts only. They are described by Atmel as follows: > > """ > There are basically two types of interrupts. The first type is > triggered by an event that sets the interrupt flag. For these > interrupts, the Program Counter is vectored to the actual Interrupt > Vector in order to execute the interrupt handling routine, and *hardware > clears the corresponding interrupt flag*. > """ > > The other type, like the USART, does need special asm code. Your serial > driver is a case in point. And this is the major concern I have with your patch. I dont like the idea of having two different interrupt handlers for subtle different interrupt classes. In your notation, all amforth interrupts a first level interrupts. May I suggest, that you implement the second level interrupts just like they are described in the wikipedia: as a thread for the multitasker (see below). I should re-write the usart handler with forth code instead of the assembler, nobody seem to believe me that it will work ;) > > I once spent a lot of time to deal with the reasons. I wrote > > a small article for the German Forth Group, unfortunatly (for you) > > in German. It seems, I should translate it into (my version of) English > > ASAP. There I explain the current interrupt handling in more detail. > > Google Translate does magic, please forward a link. http://www.forth-ev.de/repos/vd/2011-02/Interrupts.tex > Note that there is an overflow mark. If the developer encounters hard > interrupts overflow he should increase this queue size (or check up his > code). This can be done through some asm .equ convenience. IMHO a little too late. The interrupt was lost. > Did you really try it, i.e., reenabling interrupts within an ISR? You > do it and your 'intcur' gets crushed. Its difficult to test. The program flow indicate that it should work: An interrupt occures. The current interrupt handler sets the T flag and the program flow continues. Soon after the forth VM is entered and detects the T flag. Everything with disabled further interrupts so far. The inner interpreter immediately calls the forth-ISR and both the T-flag and the curint information is no longer needed for the whole forth ISR word. Thats why I think that that re-enabling interrupts within the Forth-ISR is safe and does not cause any trouble. The only place that IMHO may be casue trouble is the final ISR-END which calls RETI. That may have to be expanded to something that checks the GIE flag to either call RETI (if set) or a simple RET (if cleared). But my impression is, that RETI is smart enough to handle both cases itself. I should re-read the datasheets ;) > After receipt of a data buffer from a certain communication euipment I > want to lanuch immediately a processing activity, i.e., right from the > ISR and not wait for a round robin task to visit. You can implement a priority task scheduler as well. PAUSE is not the ultimate tool for everything ;) Matthias |
From: Enoch <ix...@ho...> - 2013-04-22 07:43:29
|
Matthias Trute <mt...@we...> writes: >> After receipt of a data buffer from a certain communication euipment I >> want to lanuch immediately a processing activity, i.e., right from the >> ISR and not wait for a round robin task to visit. > > You can implement a priority task scheduler as well. PAUSE is not the > ultimate tool for everything ;) Hello Matthias, The Kiss Principle <http://en.wikipedia.org/wiki/KISS_principle> is my guiding light. I will not introduce cooperative, pre-emptive, etc. multitasking if I can solve a problem using simpler means. I will report to this forum how well my approach succeeds, or fails ;-) By the way, did you have an opportunity to look at MARKER? I think it does not preserve well wordlist order. It's non-trivial code so just if you don't have time for this now I'll have a go at it myself. Regards, Enoch. |
From: Matthias T. <mt...@we...> - 2013-04-25 17:27:41
|
Hi, > By the way, did you have an opportunity to look at MARKER? I think it > does not preserve well wordlist order. I havn't had the time to check this problem. Sorry. > It's non-trivial code so just if > you don't have time for this now I'll have a go at it myself. Its probably a good idea to change MARKER more radically: Keep the whole allocated EEPROM contents and restore it later. Michael Kalus (IIRC) once (years ago) had this idea but I lost his code :( Matthias |