Compare commits

...

11 Commits

Author SHA1 Message Date
NIIBE Yutaka
b6c90e3df4 Version 1.13. 2018-12-19 12:52:26 +09:00
NIIBE Yutaka
4d4f82fd06 Update copyright notice. 2018-12-19 12:47:20 +09:00
NIIBE Yutaka
1ef6256784 Fix calculation of ticks remained. 2018-12-08 10:06:33 +09:00
NIIBE Yutaka
1400e677e3 Change behavior of chopstx_poll to correctly update *USEC_P. 2018-12-07 18:01:39 +09:00
NIIBE Yutaka
39683dbc5f Version 1.12. 2018-11-12 14:09:25 +09:00
NIIBE Yutaka
fd98c5e162 ackbtn driver: Add possible FST-01 and FST-01G support. 2018-11-12 14:06:13 +09:00
NIIBE Yutaka
1369361e59 Add eventflag_set_mask, removing eventflag_wait_all. 2018-11-09 20:49:39 +09:00
NIIBE Yutaka
2992b894e0 Add eventflag_wait_all. 2018-11-09 16:04:42 +09:00
NIIBE Yutaka
fffb8aa3b3 Version 1.11. 2018-10-02 09:58:45 +09:00
NIIBE Yutaka
0ed2e95ea2 Fix ackbtn clearing the edge detector. 2018-10-01 12:56:41 +09:00
NIIBE Yutaka
02aa678d4c Fix interrupt handling. 2018-10-01 10:10:09 +09:00
15 changed files with 241 additions and 62 deletions

28
AUTHORS
View File

@@ -27,19 +27,30 @@ Mateusz Zalega:
NIIBE Yutaka: NIIBE Yutaka:
Wrote the library: Wrote the library:
chopstx.c, entry.c, eventflag.c, chopstx.c, chopstx.h,
chopstx.h, eventflag.h chopstx-cortex-m.c, chopstx-cortex-m.h,
chopstx-gnu-linux.c, chopstx-gnu-linux.h,
entry.c,
eventflag.c, eventflag.h
Wrote the drivers mcu/*: Wrote the drivers mcu/*:
chx-gnu-linux.c, chx-mkl27z.c, chx-stm32f0.c, chx-stm32f103.c,
clk_gpio_init-mkl27z.c, clk_gpio_init-stm32.c, clk_gpio_init-mkl27z.c, clk_gpio_init-stm32.c,
sys-stm32f103.c, sys-stm32f030.c, sys-mkl27z.c, cortex-m.h, mkl27z.h, stm32.h, stm32f103.h,
adc-stm32f103.c, adc-mkl27z.c sys-gnu-linux.c,sys-gnu-linux.h,
sys-mkl27z.c, sys-mkl27z.h,
sys-stm32f0.c, sys-stm32f0.h
sys-stm32f103.c, sys-stm32f103.h,
usb-stm32f103.c, usb-mkl27z.c
Wrote the drivers:
controb/adc-mkl27z.c
Drew the logo: Drew the logo:
chopstx.svg, chopstx.png chopstx.svg, chopstx.png
Wrote examples: Wrote examples:
example-led, example-cdc, example-fsm-55, example-fs-bb48, example-led, example-cdc, example-fsm-55, example-fs-bb48,
example-usb-serial example-usb-serial, example-cdc-gnu-linux
Wrote board/*: Wrote board/*:
board-fst-01.h, board-fst-01-00.h, board-fst-01sz.h,
board-fst-01g.h, board-fst-01.h, board-fst-01-00.h,
board-olimex-stm32-h103.h, board-stm8s-discovery.h board-olimex-stm32-h103.h, board-stm8s-discovery.h
board-cq-starm.h, board-stbee-mini.h, board-stbee.h, board-cq-starm.h, board-stbee-mini.h, board-stbee.h,
@@ -47,9 +58,14 @@ NIIBE Yutaka:
board-fs-bb48.h board-fs-bb48.h
For Free Software Initiative of Japan, wrote:
contrib/adc-stm32f103.c,
contrib/adc-gnu-linux.c
Under contract of g10 Code GmbH, wrote: Under contract of g10 Code GmbH, wrote:
mcu/usb-usbip.c mcu/usb-usbip.c
contrib/usart-stm32f103.c contrib/usart-stm32f103.c
contrib/ackbtn-stm32f103.c
Paul Fertser: Paul Fertser:
Added Blue Pill support. Added Blue Pill support.

View File

@@ -1,3 +1,52 @@
2018-12-19 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.13.
* doc/chopstx.texi (VERSION): 1.13.
2018-12-08 NIIBE Yutaka <gniibe@fsij.org>
* chopstx.c (chx_timer_dequeue): Fix calculation of return value.
2018-12-07 NIIBE Yutaka <gniibe@fsij.org>
* chopstx.c (chx_timer_dequeue): Return ticks remained.
(chx_wakeup, chopstx_mutex_lock): Use return value of
chx_timer_dequeue.
(chx_snooze): Update *USEC_P, accordingly.
2018-11-12 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.12.
* doc/chopstx.texi (VERSION): 1.12.
* contrib/ackbtn-stm32f103.c (ackbtn_init): Support FST-01 and
FST-01G, using PA2.
(ackbtn_disable): Fix to correctly clear pending interrupt.
2018-11-09 NIIBE Yutaka <gniibe@fsij.org>
* eventflag.c (eventflag_set_mask): New.
2018-10-02 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.11.
* doc/chopstx.texi (VERSION): 1.11.
2018-10-01 NIIBE Yutaka <gniibe@fsij.org>
* contrib/ackbtn-stm32f103.c (PINCFG_EDGE): New.
(ackbtn_init): Use PINCFG_EDGE bit.
(ackbtn_enable): Configure the edge detector here.
(ackbtn_disable): Disable the edge detector.
* chopstx.c (chopstx_poll): Don't clear ->ready here.
(chx_cond_hook): Set ->ready = 0 when condition does
not meet.
(chopstx_claim_irq): Make sure clearing the interrupt.
(chx_intr_hook): Add the case when ->ready == 1.
(chopstx_intr_done): Set ->ready = 0.
(chx_join_hook): Set ->ready = 0 when it is still alive.
2018-09-29 NIIBE Yutaka <gniibe@fsij.org> 2018-09-29 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.10. * VERSION: 1.10.

55
NEWS
View File

@@ -1,11 +1,54 @@
NEWS - Noteworthy changes NEWS - Noteworthy changes
* Major changes in Chopstx 1.13
Released 2018-12-19
** API fix (redefinition): chopstx_poll
In old implementations, when chopstx_poll returns by non-timeout
event, *USEC_P is not updated. Now, it is updated.
* Major changes in Chopstx 1.12
Released 2018-11-12
** Enhance API of eventflag
New function eventflag_set_mask is added, so that we can only handle
specified events. See Gnuk 1.2.12 for an example (while USB Tx is
busy, the USB thread only accepts EV_TX_FINISHED event, leaving
other events).
** Acknowledge button support for FST-01 and FST-01G
While FST-01 and FST-01G don't have any button in the original design,
it may be PA2 when user put a hall sensor or a switch.
* Major changes in Chopstx 1.11
Released 2018-10-02
** Support calling chopstx_poll with intr->ready==1
In version <= 1.10, it assumed that all events should be handled after
chopstx_poll, before calling chopstx_poll again. With having
chopstx_intr_done, it's OK now that chopstx_poll can be called again
not examining/handling all poll descriptors, but only parts of them.
** Acknowledge button change
In 1.10, the action was able to be "memorized" by the edge detector.
Now, the edge detector is disabled by ackbtn_disable, and it is
enabled by ackbtn_enable. So, the status is cleared correctly.
** New board support: FST-01SZ
It's still under development. Programming-wise, it will be kept same.
* Major changes in Chopstx 1.10 * Major changes in Chopstx 1.10
Released 2018-09-29 Released 2018-09-29
** Function chopstx_intr_wait is not deprecated, now. ** Function chopstx_intr_wait is not deprecated, now
Once, it was said that it's deprecated, but it's active again Once, it was said that it's deprecated, but it's active again
to match the new function of chopstx_intr_done. to match the new function of chopstx_intr_done.
@@ -59,7 +102,7 @@ Timer expiration had a bug. When it is waken up, the wake up doesn't
handle as a timer expiration when there are multiple threads on same handle as a timer expiration when there are multiple threads on same
timing of expire. It confuses as if it were forced wakeup. timing of expire. It confuses as if it were forced wakeup.
** New driver: USART for STM32. ** New driver: USART for STM32
USART driver for STM32 is added. USART driver for STM32 is added.
@@ -394,11 +437,11 @@ Vectored Interrupt Controller (NVIC), in the ARM v7-M Architecture
Reference Manual. The subsection, B3.4.1, Theory of operation, Reference Manual. The subsection, B3.4.1, Theory of operation,
explains how it works. explains how it works.
** gpio_init change ** gpio_init change
Now, gpi_init support AFIO mapping and another GPIO (GPIO_OTHER) Now, gpi_init support AFIO mapping and another GPIO (GPIO_OTHER)
settings. settings.
Local Variables:
mode: outline # Local Variables:
End: # mode: outline
# End:

4
README
View File

@@ -1,6 +1,6 @@
Chopstx - Threads and only Threads Chopstx - Threads and only Threads
Version 1.10 Version 1.12
2018-09-29 2018-11-12
Niibe Yutaka Niibe Yutaka
Flying Stone Technology Flying Stone Technology

View File

@@ -1 +1 @@
release/1.10 release/1.12

View File

@@ -293,8 +293,8 @@ chx_request_preemption (uint16_t prio)
* AAPCS: ARM Architecture Procedure Call Standard * AAPCS: ARM Architecture Procedure Call Standard
* *
* Returns: * Returns:
* 1 on wakeup by others. * >= 1 on wakeup by others, value means ticks remained for sleep.
* 0 on normal wakeup (timer expiration, lock aquirement). * 0 on normal wakeup (timer expiration, lock acquirement).
* -1 on cancellation. * -1 on cancellation.
*/ */
static uintptr_t __attribute__ ((naked, noinline)) static uintptr_t __attribute__ ((naked, noinline))

View File

@@ -107,7 +107,7 @@ static struct chx_queue q_intr;
static void chx_request_preemption (uint16_t prio); static void chx_request_preemption (uint16_t prio);
static int chx_wakeup (struct chx_pq *p); static int chx_wakeup (struct chx_pq *p);
static struct chx_thread * chx_timer_insert (struct chx_thread *tp, uint32_t usec); static struct chx_thread * chx_timer_insert (struct chx_thread *tp, uint32_t usec);
static void chx_timer_dequeue (struct chx_thread *tp); static uint32_t chx_timer_dequeue (struct chx_thread *tp);
@@ -349,29 +349,35 @@ chx_timer_insert (struct chx_thread *tp, uint32_t usec)
} }
static void static uint32_t
chx_timer_dequeue (struct chx_thread *tp) chx_timer_dequeue (struct chx_thread *tp)
{ {
struct chx_thread *tp_prev; struct chx_thread *tp_prev;
uint32_t ticks_remained;
chx_spin_lock (&q_timer.lock); chx_spin_lock (&q_timer.lock);
ticks_remained = chx_systick_get ();
tp_prev = (struct chx_thread *)tp->prev; tp_prev = (struct chx_thread *)tp->prev;
if (tp_prev == (struct chx_thread *)&q_timer.q) if (tp_prev == (struct chx_thread *)&q_timer.q)
{ {
if (tp->next == (struct chx_pq *)&q_timer.q) if (tp->next == (struct chx_pq *)&q_timer.q)
chx_set_timer (tp_prev, 0); /* Cancel timer*/ chx_systick_reload (0); /* Cancel timer. */
else else
{ /* Update timer. */ chx_systick_reload (ticks_remained + tp->v); /* Update timer. */
uint32_t next_ticks = chx_systick_get () + tp->v; }
else
{
struct chx_pq *p;
for (p = q_timer.q.next; p != (struct chx_pq *)tp; p = p->next)
ticks_remained += p->v;
chx_set_timer (tp_prev, next_ticks);
}
}
else
tp_prev->v += tp->v; tp_prev->v += tp->v;
}
ll_dequeue ((struct chx_pq *)tp); ll_dequeue ((struct chx_pq *)tp);
tp->v = 0; tp->v = 0;
chx_spin_unlock (&q_timer.lock); chx_spin_unlock (&q_timer.lock);
return ticks_remained;
} }
@@ -502,9 +508,11 @@ chx_wakeup (struct chx_pq *pq)
tp = px->master; tp = px->master;
if (tp->state == THREAD_WAIT_POLL) if (tp->state == THREAD_WAIT_POLL)
{ {
tp->v = (uintptr_t)1;
if (tp->parent == &q_timer.q) if (tp->parent == &q_timer.q)
chx_timer_dequeue (tp); tp->v = (uintptr_t)chx_timer_dequeue (tp);
else
tp->v = (uintptr_t)1;
chx_ready_enqueue (tp); chx_ready_enqueue (tp);
if (!running || tp->prio > running->prio) if (!running || tp->prio > running->prio)
yield = 1; yield = 1;
@@ -679,6 +687,11 @@ chx_snooze (uint32_t state, uint32_t *usec_p)
r = chx_sched (CHX_SLEEP); r = chx_sched (CHX_SLEEP);
if (r == 0) if (r == 0)
*usec_p -= usec0; *usec_p -= usec0;
else if (r > 0)
{
*usec_p -= (usec0 - r / MHZ);
r = 1;
}
return r; return r;
} }
@@ -803,9 +816,10 @@ chopstx_mutex_lock (chopstx_mutex_t *mutex)
if (tp0->state == THREAD_WAIT_TIME if (tp0->state == THREAD_WAIT_TIME
|| tp0->state == THREAD_WAIT_POLL) || tp0->state == THREAD_WAIT_POLL)
{ {
tp0->v = (uintptr_t)1;
if (tp0->parent == &q_timer.q) if (tp0->parent == &q_timer.q)
chx_timer_dequeue (tp0); tp0->v = (uintptr_t)chx_timer_dequeue (tp0);
else
tp0->v = (uintptr_t)1;
chx_ready_enqueue (tp0); chx_ready_enqueue (tp0);
tp0 = NULL; tp0 = NULL;
@@ -969,6 +983,7 @@ chx_cond_hook (struct chx_px *px, struct chx_poll_head *pd)
{ /* Condition doesn't met. { /* Condition doesn't met.
* Register the proxy to wait for the condition. * Register the proxy to wait for the condition.
*/ */
pc->ready = 0;
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
chx_spin_lock (&pc->cond->lock); chx_spin_lock (&pc->cond->lock);
ll_prio_enqueue ((struct chx_pq *)px, &pc->cond->q); ll_prio_enqueue ((struct chx_pq *)px, &pc->cond->q);
@@ -998,6 +1013,7 @@ chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num)
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
chx_spin_lock (&q_intr.lock); chx_spin_lock (&q_intr.lock);
chx_disable_intr (irq_num); chx_disable_intr (irq_num);
chx_clr_intr (irq_num);
chx_set_intr_prio (irq_num); chx_set_intr_prio (irq_num);
chx_spin_unlock (&q_intr.lock); chx_spin_unlock (&q_intr.lock);
chx_cpu_sched_unlock (); chx_cpu_sched_unlock ();
@@ -1012,10 +1028,19 @@ chx_intr_hook (struct chx_px *px, struct chx_poll_head *pd)
chopstx_testcancel (); chopstx_testcancel ();
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
px->v = intr->irq_num; px->v = intr->irq_num;
if (intr->ready)
{
chx_spin_lock (&px->lock);
(*px->counter_p)++;
chx_spin_unlock (&px->lock);
}
else
{
chx_spin_lock (&q_intr.lock); chx_spin_lock (&q_intr.lock);
ll_prio_enqueue ((struct chx_pq *)px, &q_intr.q); ll_prio_enqueue ((struct chx_pq *)px, &q_intr.q);
chx_enable_intr (intr->irq_num); chx_enable_intr (intr->irq_num);
chx_spin_unlock (&q_intr.lock); chx_spin_unlock (&q_intr.lock);
}
chx_cpu_sched_unlock (); chx_cpu_sched_unlock ();
} }
@@ -1047,7 +1072,10 @@ chopstx_intr_done (chopstx_intr_t *intr)
chx_dmb (); chx_dmb ();
if (intr->ready) if (intr->ready)
{
chx_clr_intr (intr->irq_num); chx_clr_intr (intr->irq_num);
intr->ready = 0;
}
} }
@@ -1215,6 +1243,7 @@ chx_join_hook (struct chx_px *px, struct chx_poll_head *pd)
{ /* Not yet exited. { /* Not yet exited.
* Register the proxy to wait for TP's exit. * Register the proxy to wait for TP's exit.
*/ */
pj->ready = 0;
px->v = (uintptr_t)tp; px->v = (uintptr_t)tp;
chx_spin_lock (&q_join.lock); chx_spin_lock (&q_join.lock);
ll_prio_enqueue ((struct chx_pq *)px, &q_join.q); ll_prio_enqueue ((struct chx_pq *)px, &q_join.q);
@@ -1332,7 +1361,8 @@ chx_proxy_init (struct chx_px *px, uint32_t *cp)
/** /**
* chopstx_poll - wait for condition variable, thread's exit, or IRQ * chopstx_poll - wait for condition variable, thread's exit, or IRQ
* @usec_p: Pointer to usec for timeout. Forever if NULL. * @usec_p: Pointer to usec for timeout. Forever if NULL. It is
* updated on return
* @n: Number of poll descriptors * @n: Number of poll descriptors
* @pd_array: Pointer to an array of poll descriptor pointer which * @pd_array: Pointer to an array of poll descriptor pointer which
* should be one of: * should be one of:
@@ -1358,7 +1388,6 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
pd = pd_array[i]; pd = pd_array[i];
pd->ready = 0;
px[i].ready_p = &pd->ready; px[i].ready_p = &pd->ready;
if (pd->type == CHOPSTX_POLL_COND) if (pd->type == CHOPSTX_POLL_COND)
chx_cond_hook (&px[i], pd); chx_cond_hook (&px[i], pd);

View File

@@ -1,7 +1,7 @@
/* /*
* chopstx.h - Threads and only threads. * chopstx.h - Threads and only threads.
* *
* Copyright (C) 2013, 2016, 2017 Flying Stone Technology * Copyright (C) 2013, 2016, 2017, 2018 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.

View File

@@ -34,7 +34,17 @@
#include "board.h" #include "board.h"
#include "sys.h" #include "sys.h"
/*
* All EXTI registers (EXTI_IMR, EXTI_EMR, EXTI_PR , EXTI_RTSR, and
* EXTI_FTSR) have same structure, where each bit of X is used for
* line X, from 0 up to 19.
*
* We use 31-bit of PIN_CONFIG to represent if it's for rising edge or
* falling edge.
*/
static uint32_t pin_config; static uint32_t pin_config;
#define PINCFG_EDGE 0x80000000
#define PINCFG_EDGE_RISING PINCFG_EDGE
void void
ackbtn_init (chopstx_intr_t *intr) ackbtn_init (chopstx_intr_t *intr)
@@ -42,10 +52,19 @@ ackbtn_init (chopstx_intr_t *intr)
uint8_t irq_num; uint8_t irq_num;
uint32_t afio_exticr_index; uint32_t afio_exticr_index;
uint32_t afio_exticr_extiX_pY; uint32_t afio_exticr_extiX_pY;
int rising_edge;
switch (SYS_BOARD_ID) switch (SYS_BOARD_ID)
{ {
case BOARD_ID_FST_01:
case BOARD_ID_FST_01G:
/* PA2 can be connected to a hall sensor or a switch */
afio_exticr_index = 0;
afio_exticr_extiX_pY = AFIO_EXTICR1_EXTI2_PA;
irq_num = EXTI2_IRQ;
pin_config = 0x0004; /* EXTI_PR_PR2 == EXTI_IMR_MR2 == EXTI_RTSR_TR2 */
pin_config |= PINCFG_EDGE_RISING;
break;
case BOARD_ID_FST_01SZ: case BOARD_ID_FST_01SZ:
default: default:
/* PA3 is connected to a hall sensor DRV5032FA */ /* PA3 is connected to a hall sensor DRV5032FA */
@@ -53,36 +72,44 @@ ackbtn_init (chopstx_intr_t *intr)
afio_exticr_extiX_pY = AFIO_EXTICR1_EXTI3_PA; afio_exticr_extiX_pY = AFIO_EXTICR1_EXTI3_PA;
irq_num = EXTI3_IRQ; irq_num = EXTI3_IRQ;
pin_config = 0x0008; /* EXTI_PR_PR3 == EXTI_IMR_MR3 == EXTI_RTSR_TR3 */ pin_config = 0x0008; /* EXTI_PR_PR3 == EXTI_IMR_MR3 == EXTI_RTSR_TR3 */
rising_edge = 1; pin_config |= PINCFG_EDGE_RISING;
break; break;
} }
chopstx_claim_irq (intr, irq_num);
/* Configure EXTI line */ /* Configure EXTI line */
if (afio_exticr_extiX_pY) if (afio_exticr_extiX_pY)
AFIO->EXTICR[afio_exticr_index] |= afio_exticr_extiX_pY; AFIO->EXTICR[afio_exticr_index] |= afio_exticr_extiX_pY;
/* Interrupt is masked, now */ /* Interrupt is masked, now */
EXTI->IMR &= ~pin_config; EXTI->IMR &= ~(pin_config & ~PINCFG_EDGE);
/* Configure which edge is detected */ chopstx_claim_irq (intr, irq_num);
if (rising_edge)
EXTI->RTSR |= pin_config;
else
EXTI->FTSR |= pin_config;
} }
void void
ackbtn_enable (void) ackbtn_enable (void)
{ {
EXTI->PR |= pin_config; /* Clear pending interrupt */ /* Clear pending interrupt */
EXTI->IMR |= pin_config; /* Enable interrupt clearing the mask */ EXTI->PR |= (pin_config & ~PINCFG_EDGE);
/* Enable interrupt, clearing the mask */
EXTI->IMR |= (pin_config & ~PINCFG_EDGE);
/* Configure which edge is detected */
if ((pin_config & PINCFG_EDGE))
EXTI->RTSR |= (pin_config & ~PINCFG_EDGE);
else
EXTI->FTSR |= (pin_config & ~PINCFG_EDGE);
} }
void void
ackbtn_disable (void) ackbtn_disable (void)
{ {
EXTI->IMR &= ~pin_config; /* Disable interrupt having the mask */ /* Disable interrupt having the mask */
EXTI->PR |= pin_config; /* Clear pending interrupt */ EXTI->IMR &= ~(pin_config & ~PINCFG_EDGE);
/* Clear pending interrupt */
EXTI->PR |= (pin_config & ~PINCFG_EDGE);
/* Disable edge detection */
EXTI->RTSR &= ~(pin_config & ~PINCFG_EDGE);
EXTI->FTSR &= ~(pin_config & ~PINCFG_EDGE);
} }

View File

@@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*- \input texinfo @c -*-texinfo-*-
@c %**start of header @c %**start of header
@setfilename chopstx.info @setfilename chopstx.info
@set VERSION 1.10 @set VERSION 1.13
@settitle Chopstx Reference Manual @settitle Chopstx Reference Manual
@c Unify some of the indices. @c Unify some of the indices.
@syncodeindex tp fn @syncodeindex tp fn

View File

@@ -1,7 +1,7 @@
/* /*
* eventflag.c - Eventflag * eventflag.c - Eventflag
* *
* Copyright (C) 2013, 2016 Flying Stone Technology * Copyright (C) 2013, 2016, 2018 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.
@@ -36,17 +36,29 @@ void
eventflag_init (struct eventflag *ev) eventflag_init (struct eventflag *ev)
{ {
ev->flags = 0; ev->flags = 0;
ev->mask = ~0;
chopstx_cond_init (&ev->cond); chopstx_cond_init (&ev->cond);
chopstx_mutex_init (&ev->mutex); chopstx_mutex_init (&ev->mutex);
} }
void
eventflag_set_mask (struct eventflag *ev, eventmask_t m)
{
chopstx_mutex_lock (&ev->mutex);
ev->mask = m;
if ((ev->flags & ev->mask))
chopstx_cond_signal (&ev->cond);
chopstx_mutex_unlock (&ev->mutex);
}
static int static int
eventflag_check (void *arg) eventflag_check (void *arg)
{ {
struct eventflag *ev = arg; struct eventflag *ev = arg;
return ev->flags != 0; return (ev->flags & ev->mask) != 0;
} }
@@ -69,7 +81,7 @@ eventflag_get (struct eventflag *ev)
eventmask_t m; eventmask_t m;
chopstx_mutex_lock (&ev->mutex); chopstx_mutex_lock (&ev->mutex);
n = __builtin_ffs (ev->flags); n = __builtin_ffs ((ev->flags & ev->mask));
if (n) if (n)
{ {
m = (1 << (n - 1)); m = (1 << (n - 1));
@@ -90,10 +102,10 @@ eventflag_wait (struct eventflag *ev)
eventmask_t m; eventmask_t m;
chopstx_mutex_lock (&ev->mutex); chopstx_mutex_lock (&ev->mutex);
if (!ev->flags) while (!(ev->flags & ev->mask))
chopstx_cond_wait (&ev->cond, &ev->mutex); chopstx_cond_wait (&ev->cond, &ev->mutex);
n = __builtin_ffs (ev->flags); n = __builtin_ffs ((ev->flags & ev->mask));
if (n) /* Always n > 0 when waked up, but make sure no bad things. */ if (n) /* Always n > 0 when waked up, but make sure no bad things. */
{ {
m = (1 << (n - 1)); m = (1 << (n - 1));
@@ -124,6 +136,7 @@ eventflag_signal (struct eventflag *ev, eventmask_t m)
{ {
chopstx_mutex_lock (&ev->mutex); chopstx_mutex_lock (&ev->mutex);
ev->flags |= m; ev->flags |= m;
if ((ev->flags & ev->mask))
chopstx_cond_signal (&ev->cond); chopstx_cond_signal (&ev->cond);
chopstx_mutex_unlock (&ev->mutex); chopstx_mutex_unlock (&ev->mutex);
} }

View File

@@ -2,11 +2,13 @@ typedef uint32_t eventmask_t;
struct eventflag { struct eventflag {
eventmask_t flags; eventmask_t flags;
eventmask_t mask;
chopstx_mutex_t mutex; chopstx_mutex_t mutex;
chopstx_cond_t cond; chopstx_cond_t cond;
}; };
void eventflag_init (struct eventflag *ev); void eventflag_init (struct eventflag *ev);
void eventflag_set_mask (struct eventflag *ev, eventmask_t m);
eventmask_t eventflag_wait (struct eventflag *ev); eventmask_t eventflag_wait (struct eventflag *ev);
eventmask_t eventflag_wait_timeout (struct eventflag *ev, uint32_t usec); eventmask_t eventflag_wait_timeout (struct eventflag *ev, uint32_t usec);
void eventflag_signal (struct eventflag *ev, eventmask_t m); void eventflag_signal (struct eventflag *ev, eventmask_t m);

View File

@@ -1,7 +1,7 @@
/* /*
* usb-mkl27z.c - USB driver for MKL27Z * usb-mkl27z.c - USB driver for MKL27Z
* *
* Copyright (C) 2016 Flying Stone Technology * Copyright (C) 2016, 2018 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.

View File

@@ -1,7 +1,7 @@
/* /*
* usb-stm32f103.c - USB driver for STM32F103 * usb-stm32f103.c - USB driver for STM32F103
* *
* Copyright (C) 2016, 2017 Flying Stone Technology * Copyright (C) 2016, 2017, 2018 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.

View File

@@ -1,7 +1,7 @@
/* /*
* usb-usbip.c - USB Device Emulation (server side) by USBIP * usb-usbip.c - USB Device Emulation (server side) by USBIP
* *
* Copyright (C) 2017 g10 Code GmbH * Copyright (C) 2017, 2018 g10 Code GmbH
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.