Now, it works with svc holding lock.
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2013-06-04 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx.c (AIRCR): New.
|
||||
(chx_init): Setting for PRIGROUP 2-bit:2-bit.
|
||||
(sched): Unlock cpu_sched_lock on return to thread.
|
||||
(preempt, chx_timer_expired, chx_handle_intr): Those can be
|
||||
considered holding cpu_sched_lock (by its equal exception
|
||||
priorities), thus no acquiring lock required.
|
||||
|
||||
2013-06-03 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx.c (chx_spin_lock, chx_spin_unlock): Rename.
|
||||
|
||||
57
chopstx.c
57
chopstx.c
@@ -34,17 +34,22 @@
|
||||
/*
|
||||
* Note: Lower has higher precedence.
|
||||
*
|
||||
* Prio 0: svc
|
||||
* Prio 32: thread temporarily inhibiting schedule for critical region
|
||||
* Prio 64: systick, external interrupt
|
||||
* Prio 96: pendsv
|
||||
* Prio 0x30: svc
|
||||
* ---------------------
|
||||
* Prio 0x40: thread temporarily inhibiting schedule for critical region
|
||||
* Prio 0x50: systick
|
||||
* Prio 0x60: external interrupt
|
||||
* Prio 0x70: pendsv
|
||||
*/
|
||||
|
||||
#define CPU_EXCEPTION_PRIORITY_SVC 0
|
||||
#define CPU_EXCEPTION_PRIORITY_CLEAR 0
|
||||
#define CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED 32
|
||||
#define CPU_EXCEPTION_PRIORITY_INTERRUPT 64
|
||||
#define CPU_EXCEPTION_PRIORITY_PENDSV 96
|
||||
|
||||
#define CPU_EXCEPTION_PRIORITY_SVC 0x30
|
||||
|
||||
#define CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED 0x40
|
||||
#define CPU_EXCEPTION_PRIORITY_SYSTICK 0x50
|
||||
#define CPU_EXCEPTION_PRIORITY_INTERRUPT 0x60
|
||||
#define CPU_EXCEPTION_PRIORITY_PENDSV 0x70
|
||||
|
||||
static void
|
||||
chx_cpu_sched_lock (void)
|
||||
@@ -335,7 +340,6 @@ sched (void)
|
||||
register uint32_t r0 asm ("r0");
|
||||
|
||||
r0 = chx_ready_pop ();
|
||||
|
||||
asm volatile (/* Now, r0 points to the thread to be switched. */
|
||||
/* Put it to *running. */
|
||||
"ldr r1, =running\n\t"
|
||||
@@ -354,8 +358,10 @@ sched (void)
|
||||
"ldr r1, [r0]\n\t"
|
||||
"msr PSP, r1\n\t"
|
||||
/**/
|
||||
"mov r0, #-1\n\t"
|
||||
"sub r0, #2\n\t" /* EXC_RETURN to a thread with PSP */
|
||||
"mov r0, #0\n\t"
|
||||
"msr BASEPRI, r0\n\t" /* Unmask interrupts. */
|
||||
/**/
|
||||
"sub r0, #3\n\t" /* EXC_RETURN to a thread with PSP */
|
||||
"bx r0\n"
|
||||
"3:\n\t"
|
||||
/* Spawn an IDLE thread. */
|
||||
@@ -375,8 +381,7 @@ sched (void)
|
||||
"mov r0, #0\n\t"
|
||||
"msr BASEPRI, r0\n\t" /* Unmask interrupts. */
|
||||
/**/
|
||||
"mov r0, #-1\n\t"
|
||||
"sub r0, #6\n\t" /* EXC_RETURN to a thread with MSP */
|
||||
"sub r0, #7\n\t" /* EXC_RETURN to a thread with MSP */
|
||||
"bx r0\n"
|
||||
: /* no output */ : "r" (r0) : "memory");
|
||||
}
|
||||
@@ -390,8 +395,6 @@ preempt (void)
|
||||
"ldr r0, [r1]\n\t"
|
||||
"cbnz r0, 0f\n\t"
|
||||
/* It's idle which was preempted. */
|
||||
"mov r0, #2\n\t"
|
||||
"msr BASEPRI, r0\n\t" /* mask any interrupts. */
|
||||
"ldr r1, =__main_stack_end__\n\t"
|
||||
"msr MSP, r1\n\t"
|
||||
"b sched\n"
|
||||
@@ -409,7 +412,6 @@ preempt (void)
|
||||
: /* no input */
|
||||
: "r1", "r2", "r3", "r4", "r7", "cc", "memory");
|
||||
|
||||
chx_cpu_sched_lock ();
|
||||
chx_ready_push ((struct chx_thread *)r0);
|
||||
running = NULL;
|
||||
|
||||
@@ -534,7 +536,6 @@ chx_timer_expired (void)
|
||||
struct chx_thread *tp;
|
||||
chopstx_prio_t prio = 0;
|
||||
|
||||
chx_cpu_sched_lock ();
|
||||
chx_spin_lock (&q_timer.lock);
|
||||
if ((tp = ll_pop (&q_timer)))
|
||||
{
|
||||
@@ -566,7 +567,6 @@ chx_timer_expired (void)
|
||||
if (running == NULL || running->prio < prio)
|
||||
chx_request_preemption ();
|
||||
chx_spin_unlock (&q_timer.lock);
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
|
||||
@@ -603,7 +603,6 @@ chx_handle_intr (void)
|
||||
chopstx_intr_t *intr;
|
||||
register uint32_t irq_num;
|
||||
|
||||
chx_cpu_sched_lock ();
|
||||
asm volatile ("mrs %0, IPSR\n\t"
|
||||
"sub %0, #16" /* Exception # - 16 = interrupt number. */
|
||||
: "=r" (irq_num) : /* no input */ : "memory");
|
||||
@@ -622,7 +621,6 @@ chx_handle_intr (void)
|
||||
chx_request_preemption ();
|
||||
}
|
||||
}
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -633,6 +631,7 @@ chx_systick_init (void)
|
||||
*SYST_CSR = 7;
|
||||
}
|
||||
|
||||
static uint32_t *const AIRCR = (uint32_t *const)0xE000ED0C;
|
||||
static uint32_t *const SHPR2 = (uint32_t *const)0xE000ED1C;
|
||||
static uint32_t *const SHPR3 = (uint32_t *const)0xE000ED20;
|
||||
|
||||
@@ -641,9 +640,10 @@ static uint32_t *const SHPR3 = (uint32_t *const)0xE000ED20;
|
||||
void
|
||||
chx_init (struct chx_thread *tp)
|
||||
{
|
||||
*SHPR2 = (CPU_EXCEPTION_PRIORITY_SVC << 24); /* SVCall */
|
||||
*SHPR3 = ((CPU_EXCEPTION_PRIORITY_INTERRUPT << 24) /* SysTick */
|
||||
| (CPU_EXCEPTION_PRIORITY_PENDSV << 16)); /* PendSV */
|
||||
*AIRCR = 0x05FA0000 | ( 5 << 8); /* PRIGROUP = 5, 2-bit:2-bit. */
|
||||
*SHPR2 = (CPU_EXCEPTION_PRIORITY_SVC << 24);
|
||||
*SHPR3 = ((CPU_EXCEPTION_PRIORITY_SYSTICK << 24)
|
||||
| (CPU_EXCEPTION_PRIORITY_PENDSV << 16));
|
||||
|
||||
memset (&tp->tc, 0, sizeof (tp->tc));
|
||||
q_ready.next = q_ready.prev = (struct chx_thread *)&q_ready;
|
||||
@@ -718,7 +718,6 @@ chx_exit (void *retval)
|
||||
asm volatile ("" : : "r" (r8) : "memory");
|
||||
chx_sched ();
|
||||
/* never comes here. */
|
||||
chx_cpu_sched_unlock ();
|
||||
for (;;);
|
||||
}
|
||||
|
||||
@@ -813,6 +812,7 @@ chopstx_create (chopstx_t *thd, const chopstx_attr_t *attr,
|
||||
chx_ready_enqueue (tp);
|
||||
if (tp->prio > running->prio)
|
||||
chx_yield ();
|
||||
else
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
@@ -829,7 +829,6 @@ chopstx_usec_wait (uint32_t usec)
|
||||
chx_timer_insert (running, usec0);
|
||||
chx_spin_unlock (&q_timer.lock);
|
||||
chx_sched ();
|
||||
chx_cpu_sched_unlock ();
|
||||
usec -= usec0;
|
||||
}
|
||||
}
|
||||
@@ -900,7 +899,6 @@ chopstx_mutex_lock (chopstx_mutex_t *mutex)
|
||||
tp->v = (uint32_t)mutex;
|
||||
chx_spin_unlock (&mutex->lock);
|
||||
chx_sched ();
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -918,6 +916,7 @@ chopstx_mutex_unlock (chopstx_mutex_t *mutex)
|
||||
chx_spin_unlock (&mutex->lock);
|
||||
if (prio > running->prio)
|
||||
chx_yield ();
|
||||
else
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
@@ -949,7 +948,6 @@ chopstx_cond_wait (chopstx_cond_t *cond, chopstx_mutex_t *mutex)
|
||||
tp->v = (uint32_t)cond;
|
||||
chx_spin_unlock (&cond->lock);
|
||||
chx_sched ();
|
||||
chx_cpu_sched_unlock ();
|
||||
|
||||
if (mutex)
|
||||
chopstx_mutex_lock (mutex);
|
||||
@@ -974,6 +972,7 @@ chopstx_cond_signal (chopstx_cond_t *cond)
|
||||
chx_spin_unlock (&cond->lock);
|
||||
if (yield)
|
||||
chx_yield ();
|
||||
else
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
@@ -995,6 +994,7 @@ chopstx_cond_broadcast (chopstx_cond_t *cond)
|
||||
chx_spin_unlock (&cond->lock);
|
||||
if (yield)
|
||||
chx_yield ();
|
||||
else
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
@@ -1069,7 +1069,6 @@ chopstx_intr_wait (chopstx_intr_t *intr)
|
||||
chx_sched ();
|
||||
}
|
||||
intr->ready--;
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
|
||||
@@ -1129,7 +1128,6 @@ chopstx_join (chopstx_t thd, void **ret)
|
||||
tp->state = THREAD_FINISHED;
|
||||
if (ret)
|
||||
*ret = (void *)tp->tc.reg[REG_EXIT]; /* R8 */
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
|
||||
@@ -1164,6 +1162,7 @@ chopstx_cancel (chopstx_t thd)
|
||||
}
|
||||
if (yield)
|
||||
chx_yield ();
|
||||
else
|
||||
chx_cpu_sched_unlock ();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <chopstx.h>
|
||||
#include "sys.h" /* for set_led */
|
||||
#include "usb_lld.h" /* for set_led */
|
||||
@@ -9,8 +10,7 @@ static chopstx_cond_t cnd0;
|
||||
static chopstx_cond_t cnd1;
|
||||
|
||||
chopstx_mutex_t usb_mtx;
|
||||
chopstx_cond_t cnd_usb_connection;
|
||||
chopstx_cond_t cnd_usb_buffer_ready;
|
||||
chopstx_cond_t cnd_usb;
|
||||
|
||||
static uint8_t u, v;
|
||||
static uint8_t m; /* 0..100 */
|
||||
@@ -102,12 +102,23 @@ const size_t __stacksize_blk = (size_t)&__process2_stack_size__;
|
||||
const uint32_t __stackaddr_intr = (uint32_t)&__process3_stack_base__;
|
||||
const size_t __stacksize_intr = (size_t)&__process3_stack_size__;
|
||||
|
||||
static char hexchar (uint8_t x)
|
||||
{
|
||||
if (x <= 0x09)
|
||||
return '0' + x;
|
||||
else if (x <= 0x0f)
|
||||
return 'a' + x - 10;
|
||||
else
|
||||
return '?';
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
chopstx_t thd;
|
||||
chopstx_attr_t attr;
|
||||
uint8_t count;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
@@ -117,8 +128,7 @@ main (int argc, const char *argv[])
|
||||
chopstx_cond_init (&cnd1);
|
||||
|
||||
chopstx_mutex_init (&usb_mtx);
|
||||
chopstx_cond_init (&cnd_usb_connection);
|
||||
chopstx_cond_init (&cnd_usb_buffer_ready);
|
||||
chopstx_cond_init (&cnd_usb);
|
||||
|
||||
m = 10;
|
||||
|
||||
@@ -149,21 +159,33 @@ main (int argc, const char *argv[])
|
||||
{
|
||||
extern uint8_t connected;
|
||||
|
||||
count= 0;
|
||||
u = 1;
|
||||
/* waiting USB connection */
|
||||
chopstx_mutex_lock (&usb_mtx);
|
||||
if (!connected)
|
||||
chopstx_cond_wait (&cnd_usb_connection, &usb_mtx);
|
||||
chopstx_cond_wait (&cnd_usb, &usb_mtx);
|
||||
chopstx_mutex_unlock (&usb_mtx);
|
||||
|
||||
while (1)
|
||||
{
|
||||
char s[32];
|
||||
|
||||
u ^= 1;
|
||||
chopstx_usec_wait (200*1000*6);
|
||||
|
||||
usb_lld_write (ENDP1, "Hello, World with Chopstx!\r\n", 28);
|
||||
memcpy (s, "xx: Hello, World with Chopstx!\r\n", 32);
|
||||
s[0] = hexchar (count >> 4);
|
||||
s[1] = hexchar (count & 0x0f);
|
||||
count++;
|
||||
|
||||
chopstx_mutex_lock (&usb_mtx);
|
||||
chopstx_cond_wait (&cnd_usb_buffer_ready, &usb_mtx);
|
||||
if (!connected)
|
||||
if (connected)
|
||||
{
|
||||
usb_lld_write (ENDP1, s, 32);
|
||||
chopstx_cond_wait (&cnd_usb, &usb_mtx);
|
||||
}
|
||||
else
|
||||
break;
|
||||
chopstx_mutex_unlock (&usb_mtx);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
#include "usb_lld.h"
|
||||
|
||||
extern chopstx_mutex_t usb_mtx;
|
||||
extern chopstx_cond_t cnd_usb_connection;
|
||||
extern chopstx_cond_t cnd_usb_buffer_ready;
|
||||
extern chopstx_cond_t cnd_usb;
|
||||
|
||||
#define ENDP0_RXADDR (0x40)
|
||||
#define ENDP0_TXADDR (0x80)
|
||||
@@ -241,7 +240,7 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
|
||||
chopstx_mutex_lock (&usb_mtx);
|
||||
if (connected != connected_saved)
|
||||
chopstx_cond_signal (&cnd_usb_connection);
|
||||
chopstx_cond_signal (&cnd_usb);
|
||||
chopstx_mutex_unlock (&usb_mtx);
|
||||
|
||||
return USB_SUCCESS;
|
||||
@@ -416,7 +415,7 @@ void
|
||||
EP1_IN_Callback (void)
|
||||
{
|
||||
chopstx_mutex_lock (&usb_mtx);
|
||||
chopstx_cond_signal (&cnd_usb_buffer_ready);
|
||||
chopstx_cond_signal (&cnd_usb);
|
||||
chopstx_mutex_unlock (&usb_mtx);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user