IRQ handling is now merged into polling
This commit is contained in:
15
ChangeLog
15
ChangeLog
@@ -1,3 +1,18 @@
|
|||||||
|
2016-05-13 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* chopstx.c (chopstx_exit): Don't call chx_release_irq_thread.
|
||||||
|
(chx_release_irq_thread): Remove.
|
||||||
|
(q_intr): New variable.
|
||||||
|
(intr_top): Remove.
|
||||||
|
(chx_handle_intr, chx_init, chopstx_claim_irq)
|
||||||
|
(chopstx_intr_wait): Use Q_INTR.
|
||||||
|
(chx_intr_hook): New.
|
||||||
|
(chopstx_poll): Support CHOPSTX_POLL_INTR.
|
||||||
|
(chopstx_release_irq): Remove.
|
||||||
|
(chx_release_irq): New internal function.
|
||||||
|
(THREAD_WAIT_INT): Remove.
|
||||||
|
(chopstx_intr_wait): Remove, now offered as a macro.
|
||||||
|
|
||||||
2016-05-13 NIIBE Yutaka <gniibe@fsij.org>
|
2016-05-13 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* chopstx.c (chx_sched) [__ARM_ARCH_6M__]: Fix asm.
|
* chopstx.c (chx_sched) [__ARM_ARCH_6M__]: Fix asm.
|
||||||
|
|||||||
10
NEWS
10
NEWS
@@ -7,13 +7,19 @@ NEWS - Noteworthy changes
|
|||||||
|
|
||||||
** New feature: polling
|
** New feature: polling
|
||||||
New function chopstx_poll is added to watch multiple condition
|
New function chopstx_poll is added to watch multiple condition
|
||||||
variables simultaneously with timeout.
|
variables, threads' exit, or IRQ simultaneously with timeout.
|
||||||
|
|
||||||
|
** Remove the function chopstx_release_irq
|
||||||
|
Releasing irq is now called automaticall, internally.
|
||||||
|
|
||||||
|
** Function chopstx_intr_wait is deprecated
|
||||||
|
It's now a macro with chopstx_poll.
|
||||||
|
|
||||||
** FS-BB48: Kinetis L MCU
|
** FS-BB48: Kinetis L MCU
|
||||||
Support for FS-BB48 board with Kinetis L MCU is added.
|
Support for FS-BB48 board with Kinetis L MCU is added.
|
||||||
|
|
||||||
** No HardFault at context switch on Cortex-M0
|
** No HardFault at context switch on Cortex-M0
|
||||||
By its design, Chopstx does context switch hodling scheduler lock.
|
By its design, Chopstx does context switch holding the scheduler lock.
|
||||||
This is implemented with the feature of BASEPRI on Cortex-M3. Because
|
This is implemented with the feature of BASEPRI on Cortex-M3. Because
|
||||||
Cortex-M0 doesn't have support of BASEPRI, the context switch (before
|
Cortex-M0 doesn't have support of BASEPRI, the context switch (before
|
||||||
version 0.11) always caused HardFault exception. Since Cortex-M0
|
version 0.11) always caused HardFault exception. Since Cortex-M0
|
||||||
|
|||||||
186
chopstx.c
186
chopstx.c
@@ -239,12 +239,13 @@ static struct chx_queue q_ready;
|
|||||||
/* Queue of threads waiting for timer. */
|
/* Queue of threads waiting for timer. */
|
||||||
static struct chx_queue q_timer;
|
static struct chx_queue q_timer;
|
||||||
|
|
||||||
/* Queue of threads which wait exit of some thread. */
|
/* Queue of threads which wait for the exit of some thread. */
|
||||||
static struct chx_queue q_join;
|
static struct chx_queue q_join;
|
||||||
|
|
||||||
|
|
||||||
/* Forward declaration(s). */
|
/* Forward declaration(s). */
|
||||||
static void chx_request_preemption (uint16_t prio);
|
static void chx_request_preemption (uint16_t prio);
|
||||||
|
static int chx_wakeup (struct chx_thread *tp);
|
||||||
|
|
||||||
|
|
||||||
/**************/
|
/**************/
|
||||||
@@ -440,7 +441,6 @@ enum {
|
|||||||
THREAD_WAIT_MTX,
|
THREAD_WAIT_MTX,
|
||||||
THREAD_WAIT_CND,
|
THREAD_WAIT_CND,
|
||||||
THREAD_WAIT_TIME,
|
THREAD_WAIT_TIME,
|
||||||
THREAD_WAIT_INT,
|
|
||||||
THREAD_WAIT_POLL,
|
THREAD_WAIT_POLL,
|
||||||
THREAD_JOIN,
|
THREAD_JOIN,
|
||||||
/**/
|
/**/
|
||||||
@@ -612,44 +612,30 @@ chx_timer_expired (void)
|
|||||||
chx_spin_unlock (&q_timer.lock);
|
chx_spin_unlock (&q_timer.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static chopstx_intr_t *intr_top;
|
/* Queue of threads which wait for some interrupts. */
|
||||||
static struct chx_spinlock intr_lock;
|
static struct chx_queue q_intr;
|
||||||
|
|
||||||
void
|
void
|
||||||
chx_handle_intr (void)
|
chx_handle_intr (void)
|
||||||
{
|
{
|
||||||
chopstx_intr_t *intr;
|
struct chx_pq *p;
|
||||||
register uint32_t irq_num;
|
register uint32_t irq_num;
|
||||||
|
|
||||||
asm volatile ("mrs %0, IPSR\n\t"
|
asm volatile ("mrs %0, IPSR\n\t"
|
||||||
"sub %0, #16" /* Exception # - 16 = interrupt number. */
|
"sub %0, #16" /* Exception # - 16 = interrupt number. */
|
||||||
: "=r" (irq_num) : /* no input */ : "memory");
|
: "=r" (irq_num) : /* no input */ : "memory");
|
||||||
chx_disable_intr (irq_num);
|
chx_disable_intr (irq_num);
|
||||||
chx_spin_lock (&intr_lock);
|
chx_spin_lock (&q_intr.lock);
|
||||||
for (intr = intr_top; intr; intr = intr->next)
|
for (p = q_intr.q.next; p != (struct chx_pq *)&q_intr.q; p = p->next)
|
||||||
if (intr->irq_num == irq_num)
|
if (p->v == irq_num)
|
||||||
break;
|
{ /* should be one at most. */
|
||||||
|
struct chx_thread *tp = (struct chx_thread *)p;
|
||||||
|
|
||||||
if (intr)
|
ll_dequeue (p);
|
||||||
{
|
chx_wakeup (tp);
|
||||||
intr->ready++;
|
break;
|
||||||
if (intr->tp != running)
|
}
|
||||||
{
|
chx_spin_unlock (&q_intr.lock);
|
||||||
if (intr->tp->state == THREAD_WAIT_POLL)
|
|
||||||
{
|
|
||||||
if (intr->tp->parent == &q_timer.q)
|
|
||||||
chx_timer_dequeue (intr->tp);
|
|
||||||
chx_ready_enqueue (intr->tp);
|
|
||||||
chx_request_preemption (intr->tp->prio);
|
|
||||||
}
|
|
||||||
else if (intr->tp->state == THREAD_WAIT_INT)
|
|
||||||
{
|
|
||||||
chx_ready_enqueue (intr->tp);
|
|
||||||
chx_request_preemption (intr->tp->prio);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chx_spin_unlock (&intr_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -672,7 +658,6 @@ chopstx_t chopstx_main;
|
|||||||
void
|
void
|
||||||
chx_init (struct chx_thread *tp)
|
chx_init (struct chx_thread *tp)
|
||||||
{
|
{
|
||||||
chx_spin_init (&intr_lock);
|
|
||||||
chx_prio_init ();
|
chx_prio_init ();
|
||||||
memset (&tp->tc, 0, sizeof (tp->tc));
|
memset (&tp->tc, 0, sizeof (tp->tc));
|
||||||
q_ready.q.next = q_ready.q.prev = (struct chx_pq *)&q_ready.q;
|
q_ready.q.next = q_ready.q.prev = (struct chx_pq *)&q_ready.q;
|
||||||
@@ -681,6 +666,8 @@ chx_init (struct chx_thread *tp)
|
|||||||
chx_spin_init (&q_timer.lock);
|
chx_spin_init (&q_timer.lock);
|
||||||
q_join.q.next = q_join.q.prev = (struct chx_pq *)&q_join.q;
|
q_join.q.next = q_join.q.prev = (struct chx_pq *)&q_join.q;
|
||||||
chx_spin_init (&q_join.lock);
|
chx_spin_init (&q_join.lock);
|
||||||
|
q_intr.q.next = q_intr.q.prev = (struct chx_pq *)&q_intr.q;
|
||||||
|
chx_spin_init (&q_intr.lock);
|
||||||
tp->next = tp->prev = (struct chx_pq *)tp;
|
tp->next = tp->prev = (struct chx_pq *)tp;
|
||||||
tp->mutex_list = NULL;
|
tp->mutex_list = NULL;
|
||||||
tp->clp = NULL;
|
tp->clp = NULL;
|
||||||
@@ -1421,6 +1408,19 @@ chx_cond_hook (struct chx_px *px, struct chx_poll_head *pd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release the interrupt request.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
chx_release_irq (chopstx_intr_t *intr)
|
||||||
|
{
|
||||||
|
chx_cpu_sched_lock ();
|
||||||
|
chx_spin_lock (&q_intr.lock);
|
||||||
|
chx_enable_intr (intr->irq_num);
|
||||||
|
chx_spin_unlock (&q_intr.lock);
|
||||||
|
chx_cpu_sched_unlock ();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chopstx_claim_irq - Claim interrupt request to handle by this thread
|
* chopstx_claim_irq - Claim interrupt request to handle by this thread
|
||||||
* @intr: Pointer to INTR structure
|
* @intr: Pointer to INTR structure
|
||||||
@@ -1432,101 +1432,44 @@ void
|
|||||||
chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num)
|
chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num)
|
||||||
{
|
{
|
||||||
intr->type = CHOPSTX_POLL_INTR;
|
intr->type = CHOPSTX_POLL_INTR;
|
||||||
intr->irq_num = irq_num;
|
|
||||||
intr->tp = running;
|
|
||||||
intr->ready = 0;
|
intr->ready = 0;
|
||||||
|
intr->irq_num = irq_num;
|
||||||
|
intr->cln.routine = (void (*)(void *))chx_release_irq;
|
||||||
|
intr->cln.arg = (void *)intr;
|
||||||
|
chopstx_cleanup_push (&intr->cln);
|
||||||
|
|
||||||
chx_cpu_sched_lock ();
|
chx_cpu_sched_lock ();
|
||||||
|
chx_spin_lock (&q_intr.lock);
|
||||||
chx_disable_intr (irq_num);
|
chx_disable_intr (irq_num);
|
||||||
chx_set_intr_prio (irq_num);
|
chx_set_intr_prio (irq_num);
|
||||||
chx_spin_lock (&intr_lock);
|
chx_spin_unlock (&q_intr.lock);
|
||||||
intr->next = intr_top;
|
|
||||||
intr_top = intr;
|
|
||||||
chx_spin_unlock (&intr_lock);
|
|
||||||
chx_cpu_sched_unlock ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* chopstx_realease_irq - Unregister interrupt request
|
|
||||||
* @intr0: Interrupt request to be unregistered
|
|
||||||
*
|
|
||||||
* Release the interrupt request specified by @intr0.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
chopstx_release_irq (chopstx_intr_t *intr0)
|
|
||||||
{
|
|
||||||
chopstx_intr_t *intr, *intr_prev;
|
|
||||||
|
|
||||||
chx_cpu_sched_lock ();
|
|
||||||
chx_enable_intr (intr0->irq_num);
|
|
||||||
chx_spin_lock (&intr_lock);
|
|
||||||
intr_prev = intr_top;
|
|
||||||
for (intr = intr_top; intr; intr = intr->next)
|
|
||||||
if (intr == intr0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (intr == intr_top)
|
|
||||||
intr_top = intr_top->next;
|
|
||||||
else
|
|
||||||
intr_prev->next = intr->next;
|
|
||||||
chx_spin_unlock (&intr_lock);
|
|
||||||
chx_cpu_sched_unlock ();
|
chx_cpu_sched_unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chx_release_irq_thread (struct chx_thread *tp)
|
chx_intr_hook (struct chx_px *px, struct chx_poll_head *pd)
|
||||||
{
|
{
|
||||||
chopstx_intr_t *intr, *intr_prev;
|
struct chx_intr *intr = (struct chx_intr *)pd;
|
||||||
|
|
||||||
chx_cpu_sched_lock ();
|
|
||||||
chx_spin_lock (&intr_lock);
|
|
||||||
intr_prev = intr_top;
|
|
||||||
for (intr = intr_top; intr; intr = intr->next)
|
|
||||||
{
|
|
||||||
if (intr->tp == tp)
|
|
||||||
break;
|
|
||||||
intr_prev = intr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intr)
|
|
||||||
{
|
|
||||||
chx_enable_intr (intr->irq_num);
|
|
||||||
if (intr == intr_top)
|
|
||||||
intr_top = intr_top->next;
|
|
||||||
else
|
|
||||||
intr_prev->next = intr->next;
|
|
||||||
}
|
|
||||||
chx_spin_unlock (&intr_lock);
|
|
||||||
chx_cpu_sched_unlock ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* chopstx_intr_wait - Wait for interrupt request from hardware
|
|
||||||
* @intr: Pointer to INTR structure
|
|
||||||
*
|
|
||||||
* Wait for the interrupt @intr to be occured.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
chopstx_intr_wait (chopstx_intr_t *intr)
|
|
||||||
{
|
|
||||||
chopstx_testcancel ();
|
chopstx_testcancel ();
|
||||||
chx_cpu_sched_lock ();
|
chx_cpu_sched_lock ();
|
||||||
if (intr->ready == 0)
|
if (intr->ready)
|
||||||
{
|
{
|
||||||
chx_enable_intr (intr->irq_num);
|
chx_spin_lock (&px->lock);
|
||||||
if (running->flag_sched_rr)
|
(*px->counter_p)++;
|
||||||
chx_timer_dequeue (running);
|
*px->ready_p = 1;
|
||||||
running->state = THREAD_WAIT_INT;
|
chx_spin_unlock (&px->lock);
|
||||||
running->parent = NULL;
|
|
||||||
running->v = 0;
|
|
||||||
chx_sched (CHX_SLEEP);
|
|
||||||
chx_clr_intr (intr->irq_num);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
chx_cpu_sched_unlock ();
|
{
|
||||||
intr->ready--;
|
px->v = intr->irq_num;
|
||||||
|
chx_spin_lock (&q_intr.lock);
|
||||||
|
chx_enable_intr (intr->irq_num);
|
||||||
|
ll_prio_enqueue ((struct chx_pq *)px, &q_intr.q);
|
||||||
|
chx_spin_unlock (&q_intr.lock);
|
||||||
|
}
|
||||||
|
chx_cpu_sched_unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1598,7 +1541,6 @@ chopstx_exit (void *retval)
|
|||||||
chx_cpu_sched_unlock ();
|
chx_cpu_sched_unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
chx_release_irq_thread (running);
|
|
||||||
chx_exit (retval);
|
chx_exit (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1742,8 +1684,8 @@ chopstx_cancel (chopstx_t thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Cancellation points: cond_wait, intr_wait, and usec_wait. */
|
/* Cancellation points: cond_wait, intr_wait, and usec_wait. */
|
||||||
if (tp->state == THREAD_WAIT_CND || tp->state == THREAD_WAIT_INT
|
if (tp->state == THREAD_WAIT_CND || tp->state == THREAD_WAIT_TIME
|
||||||
|| tp->state == THREAD_WAIT_TIME || tp->state == THREAD_WAIT_POLL)
|
|| tp->state == THREAD_WAIT_POLL)
|
||||||
{
|
{
|
||||||
/* Throw away registers on stack and direct to chopstx_exit. */
|
/* Throw away registers on stack and direct to chopstx_exit. */
|
||||||
/* This is pretty much violent, but it works. */
|
/* This is pretty much violent, but it works. */
|
||||||
@@ -1823,11 +1765,11 @@ chx_proxy_init (struct chx_px *px, uint32_t *cp)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chopstx_poll - wait for condition variable or thread's exit
|
* chopstx_poll - wait for condition variable, thread's exit, or IRQ
|
||||||
* @usec_p: Pointer to usec
|
* @usec_p: Pointer to usec for timeout. Forever if NULL.
|
||||||
* @n: Number of poll descriptors
|
* @n: Number of poll descriptors
|
||||||
* @VARARGS: Pointers to an object which should be one of:
|
* @VARARGS: Pointers to an object which should be one of:
|
||||||
* struct chx_poll_cond, chx_poll_join, or chx_intr.
|
* chopstx_poll_cond_t, chopstx_poll_join_t, or chopstx_intr_t.
|
||||||
*
|
*
|
||||||
* Returns number of active descriptors.
|
* Returns number of active descriptors.
|
||||||
*/
|
*/
|
||||||
@@ -1851,6 +1793,8 @@ chopstx_poll (uint32_t *usec_p, int n, ...)
|
|||||||
pd = va_arg (ap, struct chx_poll_head *);
|
pd = va_arg (ap, struct chx_poll_head *);
|
||||||
if (pd->type == CHOPSTX_POLL_COND)
|
if (pd->type == CHOPSTX_POLL_COND)
|
||||||
chx_cond_hook (&px[i], pd);
|
chx_cond_hook (&px[i], pd);
|
||||||
|
else if (pd->type == CHOPSTX_POLL_INTR)
|
||||||
|
chx_intr_hook (&px[i], pd);
|
||||||
else
|
else
|
||||||
chx_join_hook (&px[i], pd);
|
chx_join_hook (&px[i], pd);
|
||||||
px[i].ready_p = &pd->ready;
|
px[i].ready_p = &pd->ready;
|
||||||
@@ -1864,7 +1808,7 @@ chopstx_poll (uint32_t *usec_p, int n, ...)
|
|||||||
chx_spin_unlock (&px->lock);
|
chx_spin_unlock (&px->lock);
|
||||||
chx_cpu_sched_unlock ();
|
chx_cpu_sched_unlock ();
|
||||||
}
|
}
|
||||||
else if (*usec_p == 0)
|
else if (usec_p == NULL)
|
||||||
{
|
{
|
||||||
if (running->flag_sched_rr)
|
if (running->flag_sched_rr)
|
||||||
chx_timer_dequeue (running);
|
chx_timer_dequeue (running);
|
||||||
@@ -1888,14 +1832,24 @@ chopstx_poll (uint32_t *usec_p, int n, ...)
|
|||||||
while (r == 0);
|
while (r == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
va_start (ap, n);
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
|
pd = va_arg (ap, struct chx_poll_head *);
|
||||||
|
if (pd->type == CHOPSTX_POLL_INTR)
|
||||||
|
{
|
||||||
|
struct chx_intr *intr = (struct chx_intr *)pd;
|
||||||
|
if (intr->ready)
|
||||||
|
chx_clr_intr (intr->irq_num);
|
||||||
|
}
|
||||||
|
|
||||||
chx_cpu_sched_lock ();
|
chx_cpu_sched_lock ();
|
||||||
chx_spin_lock (&px[i].lock);
|
chx_spin_lock (&px[i].lock);
|
||||||
ll_dequeue ((struct chx_pq *)&px[i]);
|
ll_dequeue ((struct chx_pq *)&px[i]);
|
||||||
chx_spin_unlock (&px[i].lock);
|
chx_spin_unlock (&px[i].lock);
|
||||||
chx_cpu_sched_unlock ();
|
chx_cpu_sched_unlock ();
|
||||||
}
|
}
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|||||||
39
chopstx.h
39
chopstx.h
@@ -82,21 +82,6 @@ void chopstx_cond_wait (chopstx_cond_t *cond, chopstx_mutex_t *mutex);
|
|||||||
void chopstx_cond_signal (chopstx_cond_t *cond);
|
void chopstx_cond_signal (chopstx_cond_t *cond);
|
||||||
void chopstx_cond_broadcast (chopstx_cond_t *cond);
|
void chopstx_cond_broadcast (chopstx_cond_t *cond);
|
||||||
|
|
||||||
struct chx_intr {
|
|
||||||
uint16_t type;
|
|
||||||
uint16_t ready;
|
|
||||||
/**/
|
|
||||||
struct chx_intr *next;
|
|
||||||
struct chx_thread *tp;
|
|
||||||
uint8_t irq_num;
|
|
||||||
};
|
|
||||||
typedef struct chx_intr chopstx_intr_t;
|
|
||||||
|
|
||||||
void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num);
|
|
||||||
void chopstx_release_irq (chopstx_intr_t *intr);
|
|
||||||
|
|
||||||
void chopstx_intr_wait (chopstx_intr_t *intr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Library provides default implementation as weak reference.
|
* Library provides default implementation as weak reference.
|
||||||
* User can replace it.
|
* User can replace it.
|
||||||
@@ -125,14 +110,14 @@ void chopstx_testcancel (void);
|
|||||||
/* NOTE: This signature is different to PTHREAD's one. */
|
/* NOTE: This signature is different to PTHREAD's one. */
|
||||||
int chopstx_setcancelstate (int);
|
int chopstx_setcancelstate (int);
|
||||||
|
|
||||||
struct chx_cleanup {
|
typedef struct chx_cleanup {
|
||||||
struct chx_cleanup *next;
|
struct chx_cleanup *next;
|
||||||
void (*routine) (void *);
|
void (*routine) (void *);
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
} chopstx_cleanup_t;
|
||||||
|
|
||||||
/* NOTE: This signature is different to PTHREAD's one. */
|
/* NOTE: This signature is different to PTHREAD's one. */
|
||||||
void chopstx_cleanup_push (struct chx_cleanup *clp);
|
void chopstx_cleanup_push (chopstx_cleanup_t *clp);
|
||||||
void chopstx_cleanup_pop (int execute);
|
void chopstx_cleanup_pop (int execute);
|
||||||
|
|
||||||
|
|
||||||
@@ -140,8 +125,8 @@ void chopstx_wakeup_usec_wait (chopstx_t thd);
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
CHOPSTX_POLL_COND = 0,
|
CHOPSTX_POLL_COND = 0,
|
||||||
CHOPSTX_POLL_JOIN,
|
|
||||||
CHOPSTX_POLL_INTR,
|
CHOPSTX_POLL_INTR,
|
||||||
|
CHOPSTX_POLL_JOIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chx_poll_cond {
|
struct chx_poll_cond {
|
||||||
@@ -153,6 +138,7 @@ struct chx_poll_cond {
|
|||||||
int (*check) (void *);
|
int (*check) (void *);
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
typedef struct chx_poll_cond chopstx_poll_cond_t;
|
||||||
|
|
||||||
struct chx_poll_join {
|
struct chx_poll_join {
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
@@ -160,6 +146,21 @@ struct chx_poll_join {
|
|||||||
/**/
|
/**/
|
||||||
chopstx_t thd;
|
chopstx_t thd;
|
||||||
};
|
};
|
||||||
|
typedef struct chx_poll_join chopstx_poll_join_t;
|
||||||
|
|
||||||
|
struct chx_intr {
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t ready;
|
||||||
|
/**/
|
||||||
|
uint8_t irq_num;
|
||||||
|
struct chx_cleanup cln;
|
||||||
|
};
|
||||||
|
typedef struct chx_intr chopstx_intr_t;
|
||||||
|
|
||||||
|
void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num);
|
||||||
|
|
||||||
|
#define chopstx_intr_wait(intr) chopstx_poll (NULL, 1, intr)
|
||||||
|
|
||||||
|
|
||||||
struct chx_poll_head {
|
struct chx_poll_head {
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
|
|||||||
@@ -92,7 +92,6 @@ usb_intr (void *arg)
|
|||||||
usb_interrupt_handler ();
|
usb_interrupt_handler ();
|
||||||
}
|
}
|
||||||
|
|
||||||
chopstx_release_irq (&interrupt);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ usb_intr (void *arg)
|
|||||||
usb_interrupt_handler ();
|
usb_interrupt_handler ();
|
||||||
}
|
}
|
||||||
|
|
||||||
chopstx_release_irq (&interrupt);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,10 +113,6 @@ void adc3_conversion (uint32_t *result)
|
|||||||
void adc3_stop (void)
|
void adc3_stop (void)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if USE_ADC3_INTR
|
|
||||||
chopstx_release_irq (&adc3_intr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Power off. */
|
/* Power off. */
|
||||||
ADC3->CR1 = 0;
|
ADC3->CR1 = 0;
|
||||||
ADC3->CR2 = 0;
|
ADC3->CR2 = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user