diff options
author | henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2007-11-20 22:52:45 +0000 |
---|---|---|
committer | henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2007-11-20 22:52:45 +0000 |
commit | ac77f6b5c53c4f2afb97564d1d281c5fdc429409 (patch) | |
tree | 2c74d6ce15214d7e93935562dd83dfe1f6c14941 | |
parent | 983595d22cf31a3002ed69d9c843922064f4cc4d (diff) |
Fight synchronization problems
git-svn-id: https://svn.openpcd.org:2342/trunk@334 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
-rw-r--r-- | openpicc/application/usb_print.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/openpicc/application/usb_print.c b/openpicc/application/usb_print.c index 74ffc3c..a01ae8b 100644 --- a/openpicc/application/usb_print.c +++ b/openpicc/application/usb_print.c @@ -18,6 +18,8 @@ */ #include <FreeRTOS.h> +#include <task.h> +#include <semphr.h> #include <USB-CDC.h> #include <string.h> @@ -28,6 +30,7 @@ static char ringbuffer[BUFLEN]; static int ringstart, ringstop; static int default_flush = 1; +static xSemaphoreHandle print_semaphore; void usb_print_buffer(const char* buffer, int start, int stop) { usb_print_buffer_f(buffer,start,stop,default_flush); @@ -90,16 +93,41 @@ int usb_print_set_default_flush(int flush) } +/* Must NOT be called from ISR context */ void usb_print_flush(void) { - while(ringstart != ringstop) { - vUSBSendByte(ringbuffer[ringstart]); - ringstart = (ringstart+1) % BUFLEN; + int oldstop, newstart; + taskENTER_CRITICAL(); + if(print_semaphore == NULL) + usb_print_init(); + if(print_semaphore == NULL) { + taskEXIT_CRITICAL(); + return; } + taskEXIT_CRITICAL(); + + xSemaphoreTake(print_semaphore, portMAX_DELAY); + + taskENTER_CRITICAL(); + oldstop = ringstop; + newstart = ringstart; + taskEXIT_CRITICAL(); + + while(newstart != oldstop) { + vUSBSendByte(ringbuffer[newstart]); + newstart = (newstart+1) % BUFLEN; + } + + taskENTER_CRITICAL(); + ringstart = newstart; + taskEXIT_CRITICAL(); + + xSemaphoreGive(print_semaphore); } void usb_print_init(void) { memset(ringbuffer, 0, BUFLEN); ringstart = ringstop = 0; + vSemaphoreCreateBinary( print_semaphore ); } |