From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Re: Ravenscar and context switching for Cortex-M4 Date: Mon, 16 Feb 2015 21:28:06 +0000 Organization: A noiseless patient Spider Message-ID: References: <27492d6c-3bf8-4eb9-8ebb-4d9f621235eb@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; format=flowed Injection-Info: mx02.eternal-september.org; posting-host="4eba6dd55c03f4a8d448cad2a88d67ef"; logging-data="26880"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX182jbo0x2+xvSz4KG1r7cm50jlIQs9SFnM=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (darwin) Cancel-Lock: sha1:7HmwhBV5PfE/hJDeEI6kja/NlsY= sha1:MDjsL07qFTPHRm5FBoROPA6fu7U= Xref: news.eternal-september.org comp.lang.ada:24973 Date: 2015-02-16T21:28:06+00:00 List-Id: Patrick Noffke writes: > Here's what happens now (the order of the interrupts may change > between runs, but this is for one capture): > > 1. UART interrupt triggers. 2. PO1's entry executes. because the entry body is executed in interrupt context. See below. > 3. SPI interrupt triggers twice (see below). 4. PO2's entry > executes. 5. T1 (UART task) executes. This is the first thing > wrong. T2 is higher priority than T1 so T2 should run first. > 6. T2 (SPI task) executes twice. Upon the second execution, I > get a program error because Object.Entry_Queue is null. The > exception is Entry_Queue is *not* null, as you said in the next post. > raised in s-tposen-raven.adb (line 167 in my copy) in > Protected_Single_Entry_Call. > > This may be relevant -- the SPI interrupt triggers twice. This > is because the interrupt is for a DMA completion, and it fires > both when TX and RX complete (since it's SPI, they complete at > the same time). I take care in my interrupt handler to release > the entry from only one of the two interrupts. Perhaps with the > interrupt firing twice, the runtime may get confused and > activate the task twice (even though the entry only executes > once). But for the above run, the entry was released during the > second SPI interrupt. The RTS does this (I hope I have it right): The entry call (Protected_Single_Entry_Call): locks the entry if the barrier is open then asserts that Call_In_Progress isn't set sets Call_In_Progress calls the entry body wrapper clears Call_In_Progress unlocks the entry else if the Entry_Queue isn't null then unlocks the entry raises PE end if sets the Entry_Queue unlocks the entry sleeps end if The handler wrapper: locks the entry calls another wrapper for the handler itself calls Service_Entry exits Service_Entry: if the Entry_Queue is set and the barrier is open then clears the Entry_Queue asserts that Call_In_Progress isn't set sets Call_In_Progress calls the entry body wrapper clears Call_In_Progress saves the caller task_id unlocks the entry wakes the caller else unlocks the entry end if I really don't see how the sequnece you describe happens! One thing that puzzles me is the locking/unlocking of the entry: this is done (in that RTS) by raising the caller task's priority to the ceiling priority of the task, if necessary. So what about interrupts? And when the handler wrapper (you can see this by compiling the package with the PO in with -gnatdg) locks the entry, it seems to raise the current task's priority, where the current task has nothing to do with the PO at all! My version of lock does procedure Lock (Object : Protection_Access) is begin if FreeRTOS.Tasks.In_ISR then null; elsif Object.Ceiling in System.Interrupt_Priority then FreeRTOS.Tasks.Disable_Interrupts; else -- do ceiling priority stuff