summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2013-06-04 10:20:53 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2013-06-04 10:20:53 +0900
commit7a09ac9a10ece38ec11c9d8588f198eea5c422b1 (patch)
tree262637b6745bfe0270c31301e393632be6f81241
parentca47da23f1f65fe86eef3ced72cbf2d750a17ff7 (diff)
Now, it works with svc holding lock.
-rw-r--r--ChangeLog9
-rw-r--r--chopstx.c67
-rw-r--r--example-cdc/sample.c38
-rw-r--r--example-cdc/usb-cdc.c7
4 files changed, 75 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index e4759bf..eceddbf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/chopstx.c b/chopstx.c
index caa3404..6c23d80 100644
--- a/chopstx.c
+++ b/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,7 +812,8 @@ chopstx_create (chopstx_t *thd, const chopstx_attr_t *attr,
chx_ready_enqueue (tp);
if (tp->prio > running->prio)
chx_yield ();
- chx_cpu_sched_unlock ();
+ 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,7 +916,8 @@ chopstx_mutex_unlock (chopstx_mutex_t *mutex)
chx_spin_unlock (&mutex->lock);
if (prio > running->prio)
chx_yield ();
- chx_cpu_sched_unlock ();
+ 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,7 +972,8 @@ chopstx_cond_signal (chopstx_cond_t *cond)
chx_spin_unlock (&cond->lock);
if (yield)
chx_yield ();
- chx_cpu_sched_unlock ();
+ else
+ chx_cpu_sched_unlock ();
}
@@ -995,7 +994,8 @@ chopstx_cond_broadcast (chopstx_cond_t *cond)
chx_spin_unlock (&cond->lock);
if (yield)
chx_yield ();
- chx_cpu_sched_unlock ();
+ 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,7 +1162,8 @@ chopstx_cancel (chopstx_t thd)
}
if (yield)
chx_yield ();
- chx_cpu_sched_unlock ();
+ else
+ chx_cpu_sched_unlock ();
}
diff --git a/example-cdc/sample.c b/example-cdc/sample.c
index 3cc87dc..fbb7bac 100644
--- a/example-cdc/sample.c
+++ b/example-cdc/sample.c
@@ -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);
}
diff --git a/example-cdc/usb-cdc.c b/example-cdc/usb-cdc.c
index 695c2f0..b44cb89 100644
--- a/example-cdc/usb-cdc.c
+++ b/example-cdc/usb-cdc.c
@@ -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);
}