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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.236.104.134 with SMTP id i6mr21337795yhg.48.1424104080140; Mon, 16 Feb 2015 08:28:00 -0800 (PST) X-Received: by 10.182.78.65 with SMTP id z1mr146727obw.10.1424104079925; Mon, 16 Feb 2015 08:27:59 -0800 (PST) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!usenet.blueworldhosting.com!feeder01.blueworldhosting.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!j7no948243qaq.1!news-out.google.com!qk8ni35602igc.0!nntp.google.com!hl2no17309305igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Mon, 16 Feb 2015 08:27:59 -0800 (PST) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=74.203.194.21; posting-account=bXcJoAoAAAAWI5APBG37o4XwnD4kTuQQ NNTP-Posting-Host: 74.203.194.21 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <27492d6c-3bf8-4eb9-8ebb-4d9f621235eb@googlegroups.com> Subject: Re: Ravenscar and context switching for Cortex-M4 From: Patrick Noffke Injection-Date: Mon, 16 Feb 2015 16:28:00 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:24969 Date: 2015-02-16T08:27:59-08:00 List-Id: On Thursday, February 12, 2015 at 2:25:40 PM UTC-6, Patrick Noffke wrote: > I am porting the GNAT Ravenscar-sfp runtime to work with the TI TM4C MCU,= using the STM32F4 implementation as a starting point. I am having a probl= em where one of two tasks blocked on entries (each in separate protected ob= jects) is not getting activated. >=20 > Here is the situation: >=20 > I have two POs, each with an interrupt handler and an entry. PO1 service= s UART interrupts and PO2 services SPI interrupts. When each interrupt fir= es, the barrier in the corresponding entry is released. >=20 > Then I have two tasks, T1 and T2. T1 is blocked on PO1's entry and T2 is= blocked on PO2's entry. >=20 I have changed things up a bit now just to see if I can get any more insigh= t. Now T2 is the main program (no longer an Ada task, but AFAICT the runti= me doesn't distinguish between main and a task with regard to context switc= hing). > The problem happens when the interrupts happen very near in time to each = other. Then, both entries are still executed, but only one task runs after= the last entry completes. I have instrumented the run-time as well as my = code to toggle GPIOs and see what's happening when. Here is the timing tha= t fails: >=20 > 1. SPI interrupt triggers. > 2. Interrupt_Request_Handler in s-bbcppr-armv7m.adb is executed. It call= s my interrupt handler or PO2, followed by the entry (entry called in the i= nterrupt context), and triggers a context switch for T2. > 3. Before the task T2 can run, the UART interrupt triggers. > 4. Interrupt_Request_Handler calls my interrupt handler for PO1 and its e= ntry, and triggers a context switch for T1. > 5. T1 then runs until it blocks again on the entry for PO1. >=20 > T2 never runs. Furthermore, after this occurs, the entry for PO2 is neve= r executed again (though its interrupt handler is). T2 also never runs aga= in. >=20 Here's what happens now (the order of the interrupts may change between run= s, but this is for one capture): 1. UART interrupt triggers. 2. PO1's entry executes. 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 p= riority than T1 so T2 should run first. 6. T2 (SPI task) executes twice. Upon the second execution, I get a progra= m error because Object.Entry_Queue is null. The exception is raised in s-t= posen-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 com= plete (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 f= or the above run, the entry was released during the second SPI interrupt. Please let me know if you have any suggestions. Best regards, Patrick