Ye Cheng
/
cmsis_rtos_demo_signal
cmsis rtos demo
main.cpp@1:8289e2db9449, 2013-01-06 (annotated)
- Committer:
- cnhzcy14
- Date:
- Sun Jan 06 15:13:50 2013 +0000
- Revision:
- 1:8289e2db9449
- Parent:
- 0:9a66107976a4
comments
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cnhzcy14 | 1:8289e2db9449 | 1 | /****************************************************************************** |
cnhzcy14 | 1:8289e2db9449 | 2 | * DESCRIPTION: |
cnhzcy14 | 1:8289e2db9449 | 3 | * Example code for using CMSIS RTOS Signal. The main thread |
cnhzcy14 | 1:8289e2db9449 | 4 | * creates three threads. Two of those threads increment a "count" variable, |
cnhzcy14 | 1:8289e2db9449 | 5 | * while the third thread watches the value of "count". When "count" |
cnhzcy14 | 1:8289e2db9449 | 6 | * reaches a predefined limit, the waiting thread is signaled by one of the |
cnhzcy14 | 1:8289e2db9449 | 7 | * incrementing threads. The waiting thread "awakens" and then modifies |
cnhzcy14 | 1:8289e2db9449 | 8 | * count. The program continues until the incrementing threads reach |
cnhzcy14 | 1:8289e2db9449 | 9 | * TCOUNT. The main program prints the final value of count. |
cnhzcy14 | 1:8289e2db9449 | 10 | * SOURCE: Adapted from example code in "Pthreads Programming", B. Nichols |
cnhzcy14 | 1:8289e2db9449 | 11 | * et al. O'Reilly and Associates. |
cnhzcy14 | 1:8289e2db9449 | 12 | * MODIFICATOR: (Simon) CHENG Ye |
cnhzcy14 | 1:8289e2db9449 | 13 | * LAST REVISED: 06/JAN/2013 |
cnhzcy14 | 1:8289e2db9449 | 14 | ******************************************************************************/ |
cnhzcy14 | 1:8289e2db9449 | 15 | |
cnhzcy14 | 0:9a66107976a4 | 16 | #include "mbed.h" |
cnhzcy14 | 0:9a66107976a4 | 17 | #include "cmsis_os.h" |
cnhzcy14 | 0:9a66107976a4 | 18 | |
cnhzcy14 | 0:9a66107976a4 | 19 | #define NUM_THREADS 3 |
cnhzcy14 | 0:9a66107976a4 | 20 | #define TCOUNT 10 |
cnhzcy14 | 0:9a66107976a4 | 21 | #define COUNT_LIMIT 12 |
cnhzcy14 | 0:9a66107976a4 | 22 | |
cnhzcy14 | 0:9a66107976a4 | 23 | int count = 0; |
cnhzcy14 | 0:9a66107976a4 | 24 | osMutexId count_mutex; |
cnhzcy14 | 0:9a66107976a4 | 25 | osMutexDef(count_mutex); |
cnhzcy14 | 0:9a66107976a4 | 26 | |
cnhzcy14 | 0:9a66107976a4 | 27 | struct thread_data |
cnhzcy14 | 0:9a66107976a4 | 28 | { |
cnhzcy14 | 0:9a66107976a4 | 29 | osThreadId id; |
cnhzcy14 | 0:9a66107976a4 | 30 | long my_id; |
cnhzcy14 | 0:9a66107976a4 | 31 | }; |
cnhzcy14 | 0:9a66107976a4 | 32 | |
cnhzcy14 | 0:9a66107976a4 | 33 | struct thread_data thread_data_array[NUM_THREADS-1]; |
cnhzcy14 | 0:9a66107976a4 | 34 | Serial debug(USBTX, USBRX); |
cnhzcy14 | 0:9a66107976a4 | 35 | |
cnhzcy14 | 0:9a66107976a4 | 36 | void inc_count(void const *threadarg) |
cnhzcy14 | 0:9a66107976a4 | 37 | { |
cnhzcy14 | 0:9a66107976a4 | 38 | int i; |
cnhzcy14 | 0:9a66107976a4 | 39 | long my_id; |
cnhzcy14 | 0:9a66107976a4 | 40 | osThreadId id; |
cnhzcy14 | 0:9a66107976a4 | 41 | struct thread_data *my_data; |
cnhzcy14 | 0:9a66107976a4 | 42 | my_data = (struct thread_data *) threadarg; |
cnhzcy14 | 0:9a66107976a4 | 43 | id = my_data->id; |
cnhzcy14 | 0:9a66107976a4 | 44 | my_id = my_data->my_id; |
cnhzcy14 | 0:9a66107976a4 | 45 | |
cnhzcy14 | 0:9a66107976a4 | 46 | for (i=0; i < TCOUNT; i++) { |
cnhzcy14 | 0:9a66107976a4 | 47 | osMutexWait(count_mutex, osWaitForever); |
cnhzcy14 | 0:9a66107976a4 | 48 | count++; |
cnhzcy14 | 0:9a66107976a4 | 49 | |
cnhzcy14 | 0:9a66107976a4 | 50 | /* |
cnhzcy14 | 1:8289e2db9449 | 51 | * Check the value of count and signal waiting thread when condition is |
cnhzcy14 | 1:8289e2db9449 | 52 | * reached. Note that this occurs while mutex is locked. |
cnhzcy14 | 0:9a66107976a4 | 53 | */ |
cnhzcy14 | 1:8289e2db9449 | 54 | if (count == COUNT_LIMIT) |
cnhzcy14 | 1:8289e2db9449 | 55 | { |
cnhzcy14 | 0:9a66107976a4 | 56 | printf("inc_count(): thread %ld, count = %d Threshold reached. ", |
cnhzcy14 | 0:9a66107976a4 | 57 | my_id, count); |
cnhzcy14 | 0:9a66107976a4 | 58 | osSignalSet(id, 0x1); |
cnhzcy14 | 0:9a66107976a4 | 59 | printf("Just sent signal.\n"); |
cnhzcy14 | 0:9a66107976a4 | 60 | } |
cnhzcy14 | 0:9a66107976a4 | 61 | printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", |
cnhzcy14 | 0:9a66107976a4 | 62 | my_id, count); |
cnhzcy14 | 0:9a66107976a4 | 63 | osMutexRelease(count_mutex); |
cnhzcy14 | 0:9a66107976a4 | 64 | |
cnhzcy14 | 0:9a66107976a4 | 65 | /* Do some work so threads can alternate on mutex lock */ |
cnhzcy14 | 0:9a66107976a4 | 66 | osDelay(1000); |
cnhzcy14 | 0:9a66107976a4 | 67 | } |
cnhzcy14 | 0:9a66107976a4 | 68 | id = osThreadGetId(); |
cnhzcy14 | 0:9a66107976a4 | 69 | osThreadTerminate(id); |
cnhzcy14 | 0:9a66107976a4 | 70 | } |
cnhzcy14 | 0:9a66107976a4 | 71 | |
cnhzcy14 | 0:9a66107976a4 | 72 | void watch_count(void const *t) |
cnhzcy14 | 0:9a66107976a4 | 73 | { |
cnhzcy14 | 0:9a66107976a4 | 74 | osThreadId id; |
cnhzcy14 | 0:9a66107976a4 | 75 | long my_id = (long)t; |
cnhzcy14 | 0:9a66107976a4 | 76 | |
cnhzcy14 | 0:9a66107976a4 | 77 | printf("Starting watch_count(): thread %ld\n", my_id); |
cnhzcy14 | 0:9a66107976a4 | 78 | |
cnhzcy14 | 1:8289e2db9449 | 79 | /* |
cnhzcy14 | 1:8289e2db9449 | 80 | * Lock mutex and wait for signal. Note that the pthread_cond_wait routine |
cnhzcy14 | 1:8289e2db9449 | 81 | * will automatically and atomically unlock mutex while it waits. |
cnhzcy14 | 1:8289e2db9449 | 82 | * Also, note that if COUNT_LIMIT is reached before this routine is run by |
cnhzcy14 | 1:8289e2db9449 | 83 | * the waiting thread, the loop will be skipped to prevent pthread_cond_wait |
cnhzcy14 | 1:8289e2db9449 | 84 | * from never returning. |
cnhzcy14 | 1:8289e2db9449 | 85 | */ |
cnhzcy14 | 1:8289e2db9449 | 86 | osMutexWait(count_mutex, osWaitForever); |
cnhzcy14 | 1:8289e2db9449 | 87 | while (count < COUNT_LIMIT) |
cnhzcy14 | 1:8289e2db9449 | 88 | { |
cnhzcy14 | 1:8289e2db9449 | 89 | osMutexRelease(count_mutex); |
cnhzcy14 | 0:9a66107976a4 | 90 | printf("watch_count(): thread %ld Count= %d. Going into wait...\n", my_id,count); |
cnhzcy14 | 0:9a66107976a4 | 91 | osSignalWait(0x1, osWaitForever); |
cnhzcy14 | 1:8289e2db9449 | 92 | osMutexWait(count_mutex, osWaitForever); |
cnhzcy14 | 0:9a66107976a4 | 93 | printf("watch_count(): thread %ld Condition signal received. Count= %d\n", my_id,count); |
cnhzcy14 | 0:9a66107976a4 | 94 | printf("watch_count(): thread %ld Updating the value of count...\n", my_id); |
cnhzcy14 | 0:9a66107976a4 | 95 | count += 125; |
cnhzcy14 | 0:9a66107976a4 | 96 | printf("watch_count(): thread %ld count now = %d.\n", my_id, count); |
cnhzcy14 | 1:8289e2db9449 | 97 | osMutexRelease(count_mutex); |
cnhzcy14 | 0:9a66107976a4 | 98 | } |
cnhzcy14 | 0:9a66107976a4 | 99 | printf("watch_count(): thread %ld Unlocking mutex.\n", my_id); |
cnhzcy14 | 0:9a66107976a4 | 100 | //osMutexRelease(count_mutex); |
cnhzcy14 | 0:9a66107976a4 | 101 | id = osThreadGetId(); |
cnhzcy14 | 0:9a66107976a4 | 102 | osThreadTerminate(id); |
cnhzcy14 | 0:9a66107976a4 | 103 | } |
cnhzcy14 | 0:9a66107976a4 | 104 | |
cnhzcy14 | 0:9a66107976a4 | 105 | void th0(void const *argument) {watch_count(argument);} |
cnhzcy14 | 0:9a66107976a4 | 106 | osThreadDef(th0, osPriorityNormal, DEFAULT_STACK_SIZE); |
cnhzcy14 | 0:9a66107976a4 | 107 | |
cnhzcy14 | 0:9a66107976a4 | 108 | void th1(void const *argument) {inc_count(argument);} |
cnhzcy14 | 0:9a66107976a4 | 109 | osThreadDef(th1, osPriorityNormal, DEFAULT_STACK_SIZE); |
cnhzcy14 | 0:9a66107976a4 | 110 | |
cnhzcy14 | 0:9a66107976a4 | 111 | void th2(void const *argument) {inc_count(argument);} |
cnhzcy14 | 0:9a66107976a4 | 112 | osThreadDef(th2, osPriorityNormal, DEFAULT_STACK_SIZE); |
cnhzcy14 | 0:9a66107976a4 | 113 | |
cnhzcy14 | 0:9a66107976a4 | 114 | int main(int argc, char *argv[]) |
cnhzcy14 | 0:9a66107976a4 | 115 | { |
cnhzcy14 | 0:9a66107976a4 | 116 | debug.baud(57600); |
cnhzcy14 | 0:9a66107976a4 | 117 | long t1=1, t2=2, t3=3; |
cnhzcy14 | 0:9a66107976a4 | 118 | osThreadId id; |
cnhzcy14 | 0:9a66107976a4 | 119 | |
cnhzcy14 | 1:8289e2db9449 | 120 | /* Initialize mutex objects */ |
cnhzcy14 | 0:9a66107976a4 | 121 | count_mutex = osMutexCreate(osMutex(count_mutex)); |
cnhzcy14 | 0:9a66107976a4 | 122 | |
cnhzcy14 | 0:9a66107976a4 | 123 | id = osThreadCreate(osThread(th0), (void *)t1); |
cnhzcy14 | 0:9a66107976a4 | 124 | thread_data_array[0].id = id; |
cnhzcy14 | 0:9a66107976a4 | 125 | thread_data_array[0].my_id = t2; |
cnhzcy14 | 1:8289e2db9449 | 126 | thread_data_array[1].id = id; |
cnhzcy14 | 0:9a66107976a4 | 127 | thread_data_array[1].my_id = t3; |
cnhzcy14 | 0:9a66107976a4 | 128 | osThreadCreate(osThread(th1), (void *)&thread_data_array[0]); |
cnhzcy14 | 0:9a66107976a4 | 129 | osThreadCreate(osThread(th2), (void *)&thread_data_array[1]); |
cnhzcy14 | 0:9a66107976a4 | 130 | |
cnhzcy14 | 0:9a66107976a4 | 131 | printf ("Main(): Waited and joined with %d threads. Final value of count = %d. Done.\n", |
cnhzcy14 | 0:9a66107976a4 | 132 | NUM_THREADS, count); |
cnhzcy14 | 1:8289e2db9449 | 133 | } |