Compare commits
19 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc49f4ef23 | ||
|
|
a0732c125a | ||
|
|
6be482413c | ||
|
|
9253777f5f | ||
|
|
63f47cede3 | ||
|
|
4c0c15588e | ||
|
|
e58e134b42 | ||
|
|
4cd47453ae | ||
|
|
89523f22bf | ||
|
|
0e5994506a | ||
|
|
bdbc84ba18 | ||
|
|
c73258138c | ||
|
|
2180ed24be | ||
|
|
b70de1b98d | ||
|
|
355482550b | ||
|
|
858a9f5d01 | ||
|
|
c7b83fd51c | ||
|
|
8e55209f33 | ||
|
|
4bde2ae1fc |
97
ChangeLog
97
ChangeLog
@@ -1,3 +1,100 @@
|
||||
2019-12-30 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.18.
|
||||
* doc/chopstx.texi (VERSION): 1.18.
|
||||
|
||||
2019-12-27 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx.c (chopstx_poll): Call CHECK for condition
|
||||
valiable after woken up.
|
||||
|
||||
2019-12-20 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* mcu/usb-st-common.c (usb_lld_ctrl_recv): Fix receiving
|
||||
more than one packet.
|
||||
|
||||
2019-12-04 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx-gnu-linux.c (chx_thread_start): Fix return value.
|
||||
|
||||
2019-11-21 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx-cortex-m.c (chx_set_running): New.
|
||||
(chx_init_arch): Use chx_set_running.
|
||||
(preempt, svc): Remove set to running, not needed.
|
||||
|
||||
* chopstx-gnu-linux.c (chx_set_running): New.
|
||||
(chx_init_arch, chx_request_preemption, chx_sched): Use
|
||||
chx_set_running and chx_running.
|
||||
(chx_sched): Bug fix of return value handling.
|
||||
|
||||
2019-11-20 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.17.
|
||||
* doc/chopstx.texi (VERSION): 1.17.
|
||||
|
||||
* chopstx-gnu-linux.c (chx_running): New.
|
||||
(chx_init_arch): Set RUNNING.
|
||||
|
||||
2019-11-19 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx-cortex-m.c (chx_running): New.
|
||||
(chx_init_arch): Set RUNNING.
|
||||
|
||||
* chopstx.c (chx_init): Don't set RUNNING here.
|
||||
(chx_timer_expired): Use chx_running.
|
||||
(chx_systick_init, chx_exit, chx_mutex_unlock, chopstx_create)
|
||||
(chopstx_mutex_lock, chopstx_mutex_unlock, chopstx_cleanup_push)
|
||||
(chopstx_cleanup_pop, chopstx_exit, chopstx_cancel)
|
||||
(chopstx_testcancel, chopstx_setcancelstate, chx_proxy_init)
|
||||
(chopstx_poll, chopstx_setpriority): Likewise.
|
||||
|
||||
2019-11-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx-gnu-linux.c (chx_systick_init_arch): Rename.
|
||||
(chx_interrupt_controller_init): Rename.
|
||||
* chopstx-cortex-m.c (chx_systick_init_arch): Rename.
|
||||
(chx_interrupt_controller_init): Rename.
|
||||
* chopstx.c (chx_systick_init): Use chx_systick_init_arch.
|
||||
(chx_init): Use chx_interrupt_controller_init.
|
||||
|
||||
2019-11-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx.c (chx_ready_pop): Check flag_sched_rr here.
|
||||
* chopstx-cortex-m.c (chx_sched) [__ARM_ARCH_6M__]: Use
|
||||
new interface of chx_ready_pop.
|
||||
(preempt,svc): Likewise.
|
||||
|
||||
2019-11-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx-cortex-m.c (ticks_to_usec): New.
|
||||
* chopstx-gnu-linux.c (ticks_to_usec): New.
|
||||
* chopstx.c (chx_snooze): Use ticks_to_usec.
|
||||
|
||||
2019-11-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* rules.mk (CSRC): Change the rule of entry*.c.
|
||||
* entry.c: It's only for Cortex-M, now.
|
||||
* entry-gnu-linux.c: New file.
|
||||
|
||||
2019-11-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* entry.c: Use chopstx-cortex-m.h.
|
||||
* chopstx.h (CHOPSTX_THREAD_SIZE): Move the definition to ...
|
||||
* chopstx-cortex-m.h (CHOPSTX_THREAD_SIZE): ... here.
|
||||
|
||||
2019-10-07 Jeremy Drake <jeremy@drastrom.science>
|
||||
|
||||
* mcu/usb-st-common.c (usb_lld_init): Move BTABLE initialization
|
||||
after clearing ISTR register.
|
||||
|
||||
2019-09-04 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
When it was exactly 64-byte, two ZLPs were sent wrongly.
|
||||
* mcu/usb-st-common.c (usb_lld_ctrl_send): Fix for 64-byte.
|
||||
* mcu/usb-usbip.c (usb_lld_ctrl_send): Likewise.
|
||||
* mcu/usb-mkl27z.c (usb_lld_ctrl_send): Likewise.
|
||||
|
||||
2019-05-22 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.16.
|
||||
|
||||
26
NEWS
26
NEWS
@@ -1,6 +1,32 @@
|
||||
NEWS - Noteworthy changes
|
||||
|
||||
|
||||
* Major changes in Chopstx 1.18
|
||||
|
||||
Released 2019-12-30
|
||||
|
||||
** Fix of chopstx_poll
|
||||
When waiting for a condition variable, we supply CHECK method with a
|
||||
descriptor. Since a condition variable may be fired for multiple
|
||||
reasons, old implementation of chopstx_poll may return with wrong
|
||||
information saying a condition of CHECK were met but actually not. It
|
||||
should not return when condition is not satisfied and it should not
|
||||
give wrong information to application. Fixed by calling the CHECK
|
||||
method again when woken up, and don't return when no condition meet.
|
||||
|
||||
** Bug fix for GNU/Linux emulation
|
||||
When woken up, return value of chx_sched was wrong. Because of this,
|
||||
timeout handling had problem. Termination value of a thread was
|
||||
wrong.
|
||||
|
||||
|
||||
* Major changes in Chopstx 1.17
|
||||
|
||||
Released 2019-11-20
|
||||
|
||||
** USB drivers bug fix for STM32 and ZLP handling for 64-byte packet.
|
||||
|
||||
|
||||
* Major changes in Chopstx 1.16
|
||||
|
||||
Released 2019-05-22
|
||||
|
||||
7
README
7
README
@@ -1,6 +1,6 @@
|
||||
Chopstx - Threads and only Threads
|
||||
Version 1.15
|
||||
2018-05-14
|
||||
Version 1.18
|
||||
2019-12-30
|
||||
Niibe Yutaka
|
||||
Flying Stone Technology
|
||||
|
||||
@@ -60,6 +60,9 @@ For STM32 Primer2, see the directory: example-primer2.
|
||||
Future Works
|
||||
============
|
||||
|
||||
RISC-V port (for GD32VF103) is under development. Please have a look
|
||||
at the master branch.
|
||||
|
||||
Convenience function to determine the bottom of thread stack,
|
||||
configuration of thread size by compiler's output would be next things
|
||||
to be done.
|
||||
|
||||
@@ -28,6 +28,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
static struct chx_thread *running;
|
||||
|
||||
static struct chx_thread *
|
||||
chx_running (void)
|
||||
{
|
||||
return running;
|
||||
}
|
||||
|
||||
static void
|
||||
chx_set_running (struct chx_thread *r)
|
||||
{
|
||||
running = r;
|
||||
}
|
||||
|
||||
|
||||
/* Data Memory Barrier. */
|
||||
static void
|
||||
chx_dmb (void)
|
||||
@@ -115,7 +130,7 @@ struct SYST {
|
||||
static struct SYST *const SYST = (struct SYST *)0xE000E010;
|
||||
|
||||
static void
|
||||
chx_systick_reset (void)
|
||||
chx_systick_init_arch (void)
|
||||
{
|
||||
SYST->RVR = 0;
|
||||
SYST->CVR = 0;
|
||||
@@ -141,6 +156,12 @@ static uint32_t usec_to_ticks (uint32_t usec)
|
||||
return usec * MHZ;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ticks_to_usec (uint32_t ticks)
|
||||
{
|
||||
return ticks / MHZ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt Handling
|
||||
*/
|
||||
@@ -205,7 +226,7 @@ static uint32_t *const SHPR2 = (uint32_t *)0xE000ED1C;
|
||||
static uint32_t *const SHPR3 = (uint32_t *)0xE000ED20;
|
||||
|
||||
static void
|
||||
chx_prio_init (void)
|
||||
chx_interrupt_controller_init (void)
|
||||
{
|
||||
*AIRCR = 0x05FA0000 | ( 5 << 8); /* PRIGROUP = 5, 2-bit:2-bit. */
|
||||
*SHPR2 = (CPU_EXCEPTION_PRIORITY_SVC << 24);
|
||||
@@ -272,6 +293,7 @@ static void
|
||||
chx_init_arch (struct chx_thread *tp)
|
||||
{
|
||||
memset (&tp->tc, 0, sizeof (tp->tc));
|
||||
chx_set_running (tp);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -366,12 +388,6 @@ chx_sched (uint32_t yield)
|
||||
}
|
||||
|
||||
tp = chx_ready_pop ();
|
||||
if (tp && tp->flag_sched_rr)
|
||||
{
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
tp = chx_timer_insert (tp, PREEMPTION_USEC);
|
||||
chx_spin_unlock (&q_timer.lock);
|
||||
}
|
||||
|
||||
asm volatile (/* Now, r0 points to the thread to be switched. */
|
||||
/* Put it to *running. */
|
||||
@@ -562,19 +578,12 @@ preempt (void)
|
||||
}
|
||||
else
|
||||
chx_ready_push (tp);
|
||||
running = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Registers on stack (PSP): r0, r1, r2, r3, r12, lr, pc, xpsr */
|
||||
|
||||
tp = chx_ready_pop ();
|
||||
if (tp && tp->flag_sched_rr)
|
||||
{
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
tp = chx_timer_insert (tp, PREEMPTION_USEC);
|
||||
chx_spin_unlock (&q_timer.lock);
|
||||
}
|
||||
|
||||
asm volatile (
|
||||
".L_CONTEXT_SWITCH:\n\t"
|
||||
@@ -688,16 +697,9 @@ svc (void)
|
||||
if (tp->flag_sched_rr)
|
||||
chx_timer_dequeue (tp);
|
||||
chx_ready_enqueue (tp);
|
||||
running = NULL;
|
||||
}
|
||||
|
||||
tp = chx_ready_pop ();
|
||||
if (tp && tp->flag_sched_rr)
|
||||
{
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
chx_timer_insert (tp, PREEMPTION_USEC);
|
||||
chx_spin_unlock (&q_timer.lock);
|
||||
}
|
||||
|
||||
asm volatile (
|
||||
"b .L_CONTEXT_SWITCH"
|
||||
|
||||
@@ -10,3 +10,5 @@ struct tcontext {
|
||||
};
|
||||
|
||||
typedef struct tcontext tcontext_t;
|
||||
|
||||
#define CHOPSTX_THREAD_SIZE 64
|
||||
|
||||
@@ -32,6 +32,21 @@
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static struct chx_thread *running;
|
||||
|
||||
static struct chx_thread *
|
||||
chx_running (void)
|
||||
{
|
||||
return running;
|
||||
}
|
||||
|
||||
static void
|
||||
chx_set_running (struct chx_thread *r)
|
||||
{
|
||||
running = r;
|
||||
}
|
||||
|
||||
|
||||
/* Data Memory Barrier. */
|
||||
static void
|
||||
chx_dmb (void)
|
||||
@@ -42,7 +57,7 @@ chx_dmb (void)
|
||||
static sigset_t ss_cur;
|
||||
|
||||
static void
|
||||
chx_systick_reset (void)
|
||||
chx_systick_init_arch (void)
|
||||
{
|
||||
const struct itimerval it = { {0, 0}, {0, 0} };
|
||||
|
||||
@@ -76,6 +91,11 @@ usec_to_ticks (uint32_t usec)
|
||||
return usec * MHZ;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ticks_to_usec (uint32_t ticks)
|
||||
{
|
||||
return ticks / MHZ;
|
||||
}
|
||||
|
||||
static void
|
||||
chx_enable_intr (uint8_t irq_num)
|
||||
@@ -105,7 +125,7 @@ chx_set_intr_prio (uint8_t n)
|
||||
}
|
||||
|
||||
static void
|
||||
chx_prio_init (void)
|
||||
chx_interrupt_controller_init (void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -200,19 +220,22 @@ chx_init_arch (struct chx_thread *tp)
|
||||
makecontext (&idle_tc, idle, 0);
|
||||
|
||||
getcontext (&tp->tc);
|
||||
|
||||
chx_set_running (tp);
|
||||
}
|
||||
|
||||
static void
|
||||
chx_request_preemption (uint16_t prio)
|
||||
{
|
||||
struct chx_thread *tp, *tp_prev;
|
||||
ucontext_t *tcp;
|
||||
struct chx_thread *tp_prev;
|
||||
struct chx_thread *tp = chx_running ();
|
||||
|
||||
if (running && (uint16_t)running->prio >= prio)
|
||||
if (tp && (uint16_t)tp->prio >= prio)
|
||||
return;
|
||||
|
||||
/* Change the context to another thread with higher priority. */
|
||||
tp = tp_prev = running;
|
||||
tp_prev = tp;
|
||||
if (tp)
|
||||
{
|
||||
if (tp->flag_sched_rr)
|
||||
@@ -225,23 +248,15 @@ chx_request_preemption (uint16_t prio)
|
||||
}
|
||||
else
|
||||
chx_ready_push (tp);
|
||||
running = NULL;
|
||||
}
|
||||
|
||||
tp = running = chx_ready_pop ();
|
||||
tp = chx_ready_pop ();
|
||||
if (tp)
|
||||
{
|
||||
tcp = &tp->tc;
|
||||
if (tp->flag_sched_rr)
|
||||
{
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
tp = chx_timer_insert (tp, PREEMPTION_USEC);
|
||||
chx_spin_unlock (&q_timer.lock);
|
||||
}
|
||||
}
|
||||
tcp = &tp->tc;
|
||||
else
|
||||
tcp = &idle_tc;
|
||||
|
||||
chx_set_running (tp);
|
||||
if (tp_prev)
|
||||
{
|
||||
/*
|
||||
@@ -286,10 +301,9 @@ static uintptr_t
|
||||
chx_sched (uint32_t yield)
|
||||
{
|
||||
struct chx_thread *tp, *tp_prev;
|
||||
uintptr_t v;
|
||||
ucontext_t *tcp;
|
||||
|
||||
tp = tp_prev = running;
|
||||
tp = tp_prev = chx_running ();
|
||||
if (yield)
|
||||
{
|
||||
if (tp->flag_sched_rr)
|
||||
@@ -297,35 +311,28 @@ chx_sched (uint32_t yield)
|
||||
chx_ready_enqueue (tp);
|
||||
}
|
||||
|
||||
running = tp = chx_ready_pop ();
|
||||
tp = chx_ready_pop ();
|
||||
if (tp)
|
||||
{
|
||||
v = tp->v;
|
||||
if (tp->flag_sched_rr)
|
||||
{
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
tp = chx_timer_insert (tp, PREEMPTION_USEC);
|
||||
chx_spin_unlock (&q_timer.lock);
|
||||
}
|
||||
tcp = &tp->tc;
|
||||
}
|
||||
tcp = &tp->tc;
|
||||
else
|
||||
{
|
||||
v = 0;
|
||||
tcp = &idle_tc;
|
||||
}
|
||||
tcp = &idle_tc;
|
||||
|
||||
chx_set_running (tp);
|
||||
swapcontext (&tp_prev->tc, tcp);
|
||||
chx_cpu_sched_unlock ();
|
||||
return v;
|
||||
|
||||
tp = chx_running ();
|
||||
return tp->v;
|
||||
}
|
||||
|
||||
static void __attribute__((__noreturn__))
|
||||
chx_thread_start (voidfunc thread_entry, void *arg)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
chx_cpu_sched_unlock ();
|
||||
thread_entry (arg);
|
||||
chopstx_exit (0);
|
||||
ret = thread_entry (arg);
|
||||
chopstx_exit (ret);
|
||||
}
|
||||
|
||||
static struct chx_thread *
|
||||
|
||||
61
chopstx.c
61
chopstx.c
@@ -83,9 +83,6 @@ chx_fatal (uint32_t err_code)
|
||||
int chx_allow_sleep;
|
||||
static struct chx_spinlock chx_enable_sleep_lock;
|
||||
|
||||
/* RUNNING: the current thread. */
|
||||
struct chx_thread *running;
|
||||
|
||||
struct chx_queue {
|
||||
struct chx_qh q;
|
||||
struct chx_spinlock lock;
|
||||
@@ -271,6 +268,12 @@ chx_ready_pop (void)
|
||||
tp->state = THREAD_RUNNING;
|
||||
chx_spin_unlock (&q_ready.lock);
|
||||
|
||||
if (tp && tp->flag_sched_rr)
|
||||
{
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
chx_timer_insert (tp, PREEMPTION_USEC);
|
||||
chx_spin_unlock (&q_timer.lock);
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
@@ -385,6 +388,7 @@ void
|
||||
chx_timer_expired (void)
|
||||
{
|
||||
struct chx_thread *tp;
|
||||
struct chx_thread *running = chx_running ();
|
||||
uint16_t prio = 0; /* Use uint16_t here. */
|
||||
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
@@ -433,10 +437,12 @@ chx_timer_expired (void)
|
||||
void
|
||||
chx_systick_init (void)
|
||||
{
|
||||
chx_systick_reset ();
|
||||
chx_systick_init_arch ();
|
||||
|
||||
if ((CHX_FLAGS_MAIN & CHOPSTX_SCHED_RR))
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
chx_cpu_sched_lock ();
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
chx_timer_insert (running, PREEMPTION_USEC);
|
||||
@@ -450,7 +456,7 @@ chopstx_t chopstx_main;
|
||||
void
|
||||
chx_init (struct chx_thread *tp)
|
||||
{
|
||||
chx_prio_init ();
|
||||
chx_interrupt_controller_init ();
|
||||
chx_init_arch (tp);
|
||||
chx_spin_init (&chx_enable_sleep_lock);
|
||||
|
||||
@@ -475,7 +481,6 @@ chx_init (struct chx_thread *tp)
|
||||
tp->prio = 0;
|
||||
tp->parent = NULL;
|
||||
tp->v = 0;
|
||||
running = tp;
|
||||
|
||||
if (CHX_PRIO_MAIN_INIT >= CHOPSTX_PRIO_INHIBIT_PREEMPTION)
|
||||
chx_cpu_sched_lock ();
|
||||
@@ -497,6 +502,7 @@ chx_wakeup (struct chx_pq *pq)
|
||||
{
|
||||
int yield = 0;
|
||||
struct chx_thread *tp;
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
if (pq->flag_is_proxy)
|
||||
{
|
||||
@@ -537,6 +543,7 @@ static void __attribute__((noreturn))
|
||||
chx_exit (void *retval)
|
||||
{
|
||||
struct chx_pq *p;
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
chx_cpu_sched_lock ();
|
||||
if (running->flag_join_req)
|
||||
@@ -573,6 +580,7 @@ static chopstx_prio_t
|
||||
chx_mutex_unlock (chopstx_mutex_t *mutex)
|
||||
{
|
||||
struct chx_thread *tp;
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
mutex->owner = NULL;
|
||||
running->mutex_list = mutex->list;
|
||||
@@ -620,6 +628,7 @@ chopstx_create (uint32_t flags_and_prio,
|
||||
{
|
||||
struct chx_thread *tp;
|
||||
chopstx_prio_t prio = (flags_and_prio & CHOPSTX_PRIO_MASK);
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
tp = chopstx_create_arch (stack_addr, stack_size, thread_entry,
|
||||
arg);
|
||||
@@ -665,6 +674,7 @@ chopstx_create (uint32_t flags_and_prio,
|
||||
static int
|
||||
chx_snooze (uint32_t state, uint32_t *usec_p)
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
uint32_t usec = *usec_p;
|
||||
uint32_t usec0;
|
||||
int r;
|
||||
@@ -688,7 +698,7 @@ chx_snooze (uint32_t state, uint32_t *usec_p)
|
||||
*usec_p -= usec0;
|
||||
else if (r > 0)
|
||||
{
|
||||
*usec_p -= (usec0 - r / MHZ);
|
||||
*usec_p -= (usec0 - ticks_to_usec (r));
|
||||
r = 1;
|
||||
}
|
||||
|
||||
@@ -787,7 +797,7 @@ requeue (struct chx_thread *tp)
|
||||
void
|
||||
chopstx_mutex_lock (chopstx_mutex_t *mutex)
|
||||
{
|
||||
struct chx_thread *tp = running;
|
||||
struct chx_thread *tp = chx_running ();
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -846,6 +856,7 @@ chopstx_mutex_lock (chopstx_mutex_t *mutex)
|
||||
void
|
||||
chopstx_mutex_unlock (chopstx_mutex_t *mutex)
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
chopstx_prio_t prio;
|
||||
|
||||
chx_cpu_sched_lock ();
|
||||
@@ -883,7 +894,7 @@ chopstx_cond_init (chopstx_cond_t *cond)
|
||||
void
|
||||
chopstx_cond_wait (chopstx_cond_t *cond, chopstx_mutex_t *mutex)
|
||||
{
|
||||
struct chx_thread *tp = running;
|
||||
struct chx_thread *tp = chx_running ();
|
||||
int r;
|
||||
|
||||
chopstx_testcancel ();
|
||||
@@ -1091,6 +1102,8 @@ chopstx_intr_done (chopstx_intr_t *intr)
|
||||
void
|
||||
chopstx_cleanup_push (struct chx_cleanup *clp)
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
clp->next = running->clp;
|
||||
running->clp = clp;
|
||||
}
|
||||
@@ -1105,6 +1118,7 @@ chopstx_cleanup_push (struct chx_cleanup *clp)
|
||||
void
|
||||
chopstx_cleanup_pop (int execute)
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
struct chx_cleanup *clp = running->clp;
|
||||
|
||||
if (clp)
|
||||
@@ -1129,6 +1143,7 @@ void
|
||||
chopstx_exit (void *retval)
|
||||
{
|
||||
struct chx_mtx *m, *m_next;
|
||||
struct chx_thread *running = chx_running ();
|
||||
struct chx_cleanup *clp = running->clp;
|
||||
|
||||
running->clp = NULL;
|
||||
@@ -1165,6 +1180,7 @@ chopstx_exit (void *retval)
|
||||
int
|
||||
chopstx_join (chopstx_t thd, void **ret)
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
struct chx_thread *tp = (struct chx_thread *)thd;
|
||||
int r = 0;
|
||||
|
||||
@@ -1268,6 +1284,7 @@ void
|
||||
chopstx_cancel (chopstx_t thd)
|
||||
{
|
||||
struct chx_thread *tp = (struct chx_thread *)thd;
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
chx_cpu_sched_lock ();
|
||||
tp->flag_got_cancel = 1;
|
||||
@@ -1324,6 +1341,8 @@ chopstx_cancel (chopstx_t thd)
|
||||
void
|
||||
chopstx_testcancel (void)
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
if (running->flag_cancelable && running->flag_got_cancel)
|
||||
chopstx_exit (CHOPSTX_CANCELED);
|
||||
}
|
||||
@@ -1340,6 +1359,7 @@ chopstx_testcancel (void)
|
||||
int
|
||||
chopstx_setcancelstate (int cancel_disable)
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
int old_state = !running->flag_cancelable;
|
||||
|
||||
running->flag_cancelable = (cancel_disable == 0);
|
||||
@@ -1350,6 +1370,8 @@ chopstx_setcancelstate (int cancel_disable)
|
||||
static void
|
||||
chx_proxy_init (struct chx_px *px, uint32_t *cp)
|
||||
{
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
px->next = px->prev = (struct chx_pq *)px;
|
||||
px->flag_is_proxy = 1;
|
||||
px->prio = running->prio;
|
||||
@@ -1381,6 +1403,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
|
||||
struct chx_px px[n];
|
||||
struct chx_poll_head *pd;
|
||||
int r = 0;
|
||||
struct chx_thread *running = chx_running ();
|
||||
|
||||
chx_dmb ();
|
||||
chopstx_testcancel ();
|
||||
@@ -1388,6 +1411,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
|
||||
for (i = 0; i < n; i++)
|
||||
chx_proxy_init (&px[i], &counter);
|
||||
|
||||
again:
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
pd = pd_array[i];
|
||||
@@ -1450,6 +1474,20 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
|
||||
ll_dequeue ((struct chx_pq *)&px[i]);
|
||||
chx_spin_unlock (&pc->cond->lock);
|
||||
}
|
||||
else
|
||||
{ /* Check the condition again after woken up. */
|
||||
if (pc->mutex)
|
||||
chopstx_mutex_lock (pc->mutex);
|
||||
|
||||
if ((*pc->check) (pc->arg) == 0)
|
||||
{ /* Condition doesn't met. */
|
||||
pc->ready = 0;
|
||||
counter--;
|
||||
}
|
||||
|
||||
if (pc->mutex)
|
||||
chopstx_mutex_unlock (pc->mutex);
|
||||
}
|
||||
}
|
||||
else if (pd->type == CHOPSTX_POLL_INTR)
|
||||
{
|
||||
@@ -1481,6 +1519,9 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
|
||||
if (r < 0)
|
||||
chopstx_exit (CHOPSTX_CANCELED);
|
||||
|
||||
if (counter == 0 && (usec_p == NULL || *usec_p))
|
||||
goto again;
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
@@ -1501,7 +1542,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
|
||||
chopstx_prio_t
|
||||
chopstx_setpriority (chopstx_prio_t prio_new)
|
||||
{
|
||||
struct chx_thread *tp = running;
|
||||
struct chx_thread *tp = chx_running ();
|
||||
chopstx_prio_t prio_orig, prio_cur;
|
||||
|
||||
chx_cpu_sched_lock ();
|
||||
|
||||
@@ -163,5 +163,3 @@ int chopstx_poll (uint32_t *usec_p, int n,
|
||||
struct chx_poll_head *const pd_array[]);
|
||||
|
||||
int chopstx_conf_idle (int enable_sleep);
|
||||
|
||||
#define CHOPSTX_THREAD_SIZE 64
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
@setfilename chopstx.info
|
||||
@set VERSION 1.16
|
||||
@set VERSION 1.18
|
||||
@settitle Chopstx Reference Manual
|
||||
@c Unify some of the indices.
|
||||
@syncodeindex tp fn
|
||||
|
||||
45
entry-gnu-linux.c
Normal file
45
entry-gnu-linux.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* entry.c - Entry routine.
|
||||
*
|
||||
* Copyright (C) 2017, 2019
|
||||
* Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Chopstx, a thread library for embedded.
|
||||
*
|
||||
* Chopstx is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chopstx is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As additional permission under GNU GPL version 3 section 7, you may
|
||||
* distribute non-source form of the Program without the copy of the
|
||||
* GNU GPL normally required by section 4, provided you inform the
|
||||
* recipients of GNU GPL by a written offer.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <chopstx.h>
|
||||
|
||||
int emulated_main (int, const char **);
|
||||
void chx_init (struct chx_thread *);
|
||||
void chx_systick_init (void);
|
||||
extern struct chx_thread main_thread;
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
chx_init (&main_thread);
|
||||
chx_systick_init ();
|
||||
emulated_main (argc, argv);
|
||||
}
|
||||
17
entry.c
17
entry.c
@@ -29,24 +29,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <chopstx.h>
|
||||
#include <chopstx-cortex-m.h>
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
int emulated_main (int, const char **);
|
||||
void chx_init (struct chx_thread *);
|
||||
void chx_systick_init (void);
|
||||
extern struct chx_thread main_thread;
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
chx_init (&main_thread);
|
||||
chx_systick_init ();
|
||||
emulated_main (argc, argv);
|
||||
}
|
||||
#else
|
||||
#if defined(USE_SYS3) || defined(USE_SYS_CLOCK_GPIO_SETTING)
|
||||
#define REQUIRE_CLOCK_GPIO_SETTING_IN_SYS
|
||||
#include "sys.h"
|
||||
@@ -258,4 +244,3 @@ handler vector_table[] __attribute__ ((section(".startup.vectors"))) = {
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -768,7 +768,7 @@ tty_main (void *arg)
|
||||
&& t->flag_send_ready)
|
||||
{
|
||||
uint8_t line[32];
|
||||
int len = get_chars_from_ringbuffer (t, line, sizeof (len));
|
||||
int len = get_chars_from_ringbuffer (t, line, sizeof (line));
|
||||
|
||||
if (len)
|
||||
{
|
||||
|
||||
@@ -780,7 +780,7 @@ tty_main (void *arg)
|
||||
&& t->flag_send_ready)
|
||||
{
|
||||
uint8_t line[32];
|
||||
int len = get_chars_from_ringbuffer (t, line, sizeof (len));
|
||||
int len = get_chars_from_ringbuffer (t, line, sizeof (line));
|
||||
|
||||
if (len)
|
||||
{
|
||||
|
||||
@@ -768,7 +768,7 @@ tty_main (void *arg)
|
||||
&& t->flag_send_ready)
|
||||
{
|
||||
uint8_t line[32];
|
||||
int len = get_chars_from_ringbuffer (t, line, sizeof (len));
|
||||
int len = get_chars_from_ringbuffer (t, line, sizeof (line));
|
||||
|
||||
if (len)
|
||||
{
|
||||
|
||||
@@ -956,7 +956,7 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
|
||||
else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
|
||||
data_p->require_zlp = 1;
|
||||
|
||||
if (data_p->len < USB_MAX_PACKET_SIZE)
|
||||
if (data_p->len <= USB_MAX_PACKET_SIZE)
|
||||
{
|
||||
len = data_p->len;
|
||||
dev->state = LAST_IN_DATA;
|
||||
|
||||
@@ -235,10 +235,9 @@ usb_lld_init (struct usb_dev *dev, uint8_t feature)
|
||||
USB->CNTR = CNTR_FRES;
|
||||
USB->CNTR = 0;
|
||||
|
||||
USB->BTABLE = 0;
|
||||
|
||||
/* Clear Interrupt Status Register, and enable interrupt for USB */
|
||||
USB->ISTR = 0;
|
||||
USB->BTABLE = 0;
|
||||
USB->CNTR = (CNTR_CTRM | CNTR_OVRM | CNTR_ERRM
|
||||
| CNTR_WKUPM | CNTR_SUSPM | CNTR_RESETM);
|
||||
}
|
||||
@@ -329,7 +328,7 @@ handle_datastage_out (struct usb_dev *dev)
|
||||
static void
|
||||
handle_datastage_in (struct usb_dev *dev)
|
||||
{
|
||||
uint32_t len = USB_MAX_PACKET_SIZE;;
|
||||
uint32_t len = USB_MAX_PACKET_SIZE;
|
||||
struct ctrl_data *data_p = &dev->ctrl_data;
|
||||
|
||||
if ((data_p->len == 0) && (dev->state == LAST_IN_DATA))
|
||||
@@ -865,6 +864,8 @@ usb_lld_ctrl_recv (struct usb_dev *dev, void *p, size_t len)
|
||||
struct ctrl_data *data_p = &dev->ctrl_data;
|
||||
data_p->addr = p;
|
||||
data_p->len = len;
|
||||
if (len > USB_MAX_PACKET_SIZE)
|
||||
len = USB_MAX_PACKET_SIZE;
|
||||
dev->state = OUT_DATA;
|
||||
ep_set_rx_status (ENDP0, EP_RX_VALID);
|
||||
return USB_EVENT_OK;
|
||||
@@ -887,14 +888,14 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
|
||||
data_p->addr = (void *)buf;
|
||||
data_p->len = buflen;
|
||||
|
||||
/* Restrict the data length to be the one host asks for */
|
||||
/* Restrict the data length to be the one which host asks for. */
|
||||
if (data_p->len >= len_asked)
|
||||
data_p->len = len_asked;
|
||||
/* ZLP is only required when host doesn't expect the end of packets. */
|
||||
else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
|
||||
data_p->require_zlp = 1;
|
||||
|
||||
if (data_p->len < USB_MAX_PACKET_SIZE)
|
||||
if (data_p->len <= USB_MAX_PACKET_SIZE)
|
||||
{
|
||||
len = data_p->len;
|
||||
dev->state = LAST_IN_DATA;
|
||||
|
||||
@@ -2175,7 +2175,7 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
|
||||
else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
|
||||
data_p->require_zlp = 1;
|
||||
|
||||
if (data_p->len < USB_MAX_PACKET_SIZE)
|
||||
if (data_p->len <= USB_MAX_PACKET_SIZE)
|
||||
{
|
||||
len = data_p->len;
|
||||
dev->state = LAST_IN_DATA;
|
||||
|
||||
Reference in New Issue
Block a user