diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2013-06-04 10:20:53 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2013-06-04 10:20:53 +0900 |
commit | 7a09ac9a10ece38ec11c9d8588f198eea5c422b1 (patch) | |
tree | 262637b6745bfe0270c31301e393632be6f81241 | |
parent | ca47da23f1f65fe86eef3ced72cbf2d750a17ff7 (diff) |
Now, it works with svc holding lock.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | chopstx.c | 67 | ||||
-rw-r--r-- | example-cdc/sample.c | 38 | ||||
-rw-r--r-- | example-cdc/usb-cdc.c | 7 |
4 files changed, 75 insertions, 46 deletions
@@ -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. @@ -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); } |