diff --git a/ChangeLog b/ChangeLog index 602d06e..4ccf7fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2019-05-10 NIIBE Yutaka + + * chopstx.c (chopstx_claim_irq): Check INTR before the call. + + * chopstx-cortex-m.c (chx_disable_intr): Have return value. + * chopstx-gnu-linux.c (chx_disable_intr): Likewise. + 2019-05-10 NIIBE Yutaka * mcu/sys-stm32f103.c: SYS version 4.0. diff --git a/chopstx-cortex-m.c b/chopstx-cortex-m.c index c6d1b3e..23cfe03 100644 --- a/chopstx-cortex-m.c +++ b/chopstx-cortex-m.c @@ -179,10 +179,13 @@ chx_clr_intr (uint8_t irq_num) NVIC_ICPR (irq_num) = 1 << (irq_num & 0x1f); } -static void +static int chx_disable_intr (uint8_t irq_num) { + int already_disabled = !!(NVIC_ICER (irq_num) & (1 << (irq_num & 0x1f))); + NVIC_ICER (irq_num) = 1 << (irq_num & 0x1f); + return already_disabled; } static void diff --git a/chopstx-gnu-linux.c b/chopstx-gnu-linux.c index 07f9a7a..9c7f8df 100644 --- a/chopstx-gnu-linux.c +++ b/chopstx-gnu-linux.c @@ -2,7 +2,7 @@ * chopstx-gnu-linux.c - Threads and only threads: Arch specific code * for GNU/Linux emulation * - * Copyright (C) 2017, 2018 Flying Stone Technology + * Copyright (C) 2017, 2018, 2019 Flying Stone Technology * Author: NIIBE Yutaka * * This file is a part of Chopstx, a thread library for embedded. @@ -89,10 +89,13 @@ chx_clr_intr (uint8_t irq_num) (void)irq_num; } -static void +static int chx_disable_intr (uint8_t irq_num) { + int already_disabled = sigismember (&ss_cur, irq_num); + sigaddset (&ss_cur, irq_num); + return already_disabled; } static void diff --git a/chopstx.c b/chopstx.c index 70217f6..022d821 100644 --- a/chopstx.c +++ b/chopstx.c @@ -1005,17 +1005,21 @@ chx_cond_hook (struct chx_px *px, struct chx_poll_head *pd) void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num) { + int intr_before_claim; + intr->type = CHOPSTX_POLL_INTR; intr->ready = 0; intr->irq_num = irq_num; chx_cpu_sched_lock (); chx_spin_lock (&q_intr.lock); - chx_disable_intr (irq_num); + intr_before_claim = chx_disable_intr (irq_num); chx_clr_intr (irq_num); chx_set_intr_prio (irq_num); chx_spin_unlock (&q_intr.lock); chx_cpu_sched_unlock (); + if (intr_before_claim) + intr->ready = 1; } diff --git a/example-cdc-gnu-linux/usb-cdc.c b/example-cdc-gnu-linux/usb-cdc.c index 90b27c5..aa4c01d 100644 --- a/example-cdc-gnu-linux/usb-cdc.c +++ b/example-cdc-gnu-linux/usb-cdc.c @@ -660,31 +660,8 @@ tty_main (void *arg) struct usb_dev dev; int e; -#if defined(OLDER_SYS_H) - /* - * Historically (before sys < 3.0), NVIC priority setting for USB - * interrupt was done in usb_lld_sys_init. Thus this code. - * - * When USB interrupt occurs between usb_lld_init (which assumes - * ISR) and chopstx_claim_irq (which clears pending interrupt), - * invocation of usb_lld_event_handler won't occur. - * - * Calling usb_lld_event_handler is no harm even if there were no - * interrupts, thus, we call it unconditionally here, just in case - * if there is a request. - * - * We can't call usb_lld_init after chopstx_claim_irq, as - * usb_lld_init does its own setting for NVIC. Calling - * chopstx_claim_irq after usb_lld_init overrides that. - * - */ - usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); - chopstx_claim_irq (&usb_intr, INTR_REQ_USB); - goto event_handle; -#else chopstx_claim_irq (&usb_intr, INTR_REQ_USB); usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); -#endif while (1) { diff --git a/example-cdc/usb-cdc.c b/example-cdc/usb-cdc.c index a4d146c..64c5ac4 100644 --- a/example-cdc/usb-cdc.c +++ b/example-cdc/usb-cdc.c @@ -675,24 +675,17 @@ tty_main (void *arg) #if defined(OLDER_SYS_H) /* * Historically (before sys < 3.0), NVIC priority setting for USB - * interrupt was done in usb_lld_sys_init. Thus this code. - * - * When USB interrupt occurs between usb_lld_init (which assumes - * ISR) and chopstx_claim_irq (which clears pending interrupt), - * invocation of usb_lld_event_handler won't occur. - * - * Calling usb_lld_event_handler is no harm even if there were no - * interrupts, thus, we call it unconditionally here, just in case - * if there is a request. + * interrupt was done in usb_lld_sys_init for free standing + * application. Thus this compatibility code. * * We can't call usb_lld_init after chopstx_claim_irq, as - * usb_lld_init does its own setting for NVIC. Calling - * chopstx_claim_irq after usb_lld_init overrides that. + * usb_lld_init does its own setting for NVIC, which is incompatible + * to Chopstx's interrupt handling. Calling chopstx_claim_irq after + * usb_lld_init overrides that for Chopstx. * */ usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); chopstx_claim_irq (&usb_intr, INTR_REQ_USB); - goto event_handle; #else chopstx_claim_irq (&usb_intr, INTR_REQ_USB); usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); diff --git a/example-fs-bb48/usb-cdc.c b/example-fs-bb48/usb-cdc.c index f96244d..1e44124 100644 --- a/example-fs-bb48/usb-cdc.c +++ b/example-fs-bb48/usb-cdc.c @@ -660,24 +660,17 @@ tty_main (void *arg) #if defined(OLDER_SYS_H) /* * Historically (before sys < 3.0), NVIC priority setting for USB - * interrupt was done in usb_lld_sys_init. Thus this code. - * - * When USB interrupt occurs between usb_lld_init (which assumes - * ISR) and chopstx_claim_irq (which clears pending interrupt), - * invocation of usb_lld_event_handler won't occur. - * - * Calling usb_lld_event_handler is no harm even if there were no - * interrupts, thus, we call it unconditionally here, just in case - * if there is a request. + * interrupt was done in usb_lld_sys_init for free standing + * application. Thus this compatibility code. * * We can't call usb_lld_init after chopstx_claim_irq, as - * usb_lld_init does its own setting for NVIC. Calling - * chopstx_claim_irq after usb_lld_init overrides that. + * usb_lld_init does its own setting for NVIC, which is incompatible + * to Chopstx's interrupt handling. Calling chopstx_claim_irq after + * usb_lld_init overrides that for Chopstx. * */ usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); chopstx_claim_irq (&usb_intr, INTR_REQ_USB); - goto event_handle; #else chopstx_claim_irq (&usb_intr, INTR_REQ_USB); usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); diff --git a/example-usb-serial/usb-cdc.c b/example-usb-serial/usb-cdc.c index 898217b..8e0adfa 100644 --- a/example-usb-serial/usb-cdc.c +++ b/example-usb-serial/usb-cdc.c @@ -725,24 +725,17 @@ cdc_main (void *arg) #if defined(OLDER_SYS_H) /* * Historically (before sys < 3.0), NVIC priority setting for USB - * interrupt was done in usb_lld_sys_init. Thus this code. - * - * When USB interrupt occurs between usb_lld_init (which assumes - * ISR) and chopstx_claim_irq (which clears pending interrupt), - * invocation of usb_lld_event_handler won't occur. - * - * Calling usb_lld_event_handler is no harm even if there were no - * interrupts, thus, we call it unconditionally here, just in case - * if there is a request. + * interrupt was done in usb_lld_sys_init for free standing + * application. Thus this compatibility code. * * We can't call usb_lld_init after chopstx_claim_irq, as - * usb_lld_init does its own setting for NVIC. Calling - * chopstx_claim_irq after usb_lld_init overrides that. + * usb_lld_init does its own setting for NVIC, which is incompatible + * to Chopstx's interrupt handling. Calling chopstx_claim_irq after + * usb_lld_init overrides that for Chopstx. * */ usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); chopstx_claim_irq (&usb_intr, INTR_REQ_USB); - goto event_handle; #else chopstx_claim_irq (&usb_intr, INTR_REQ_USB); usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED);