ftf mbedos threads lab

Dependencies:   ST7567

Committer:
uLipe
Date:
Sat Nov 05 02:46:29 2016 +0000
Revision:
0:ead5ee0a33fa
Child:
1:e7266223f1fa
first working version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uLipe 0:ead5ee0a33fa 1 /**
uLipe 0:ead5ee0a33fa 2 * @brief NXP FTF LAB3 - Mbed OS Threads control each thread execution
uLipe 0:ead5ee0a33fa 3 */
uLipe 0:ead5ee0a33fa 4
uLipe 0:ead5ee0a33fa 5
uLipe 0:ead5ee0a33fa 6 #include "mbed.h"
uLipe 0:ead5ee0a33fa 7 #include "ST7567.h"
uLipe 0:ead5ee0a33fa 8 #include "rtos.h"
uLipe 0:ead5ee0a33fa 9
uLipe 0:ead5ee0a33fa 10 /* LCD screen dimensions */
uLipe 0:ead5ee0a33fa 11 #define LCD_HEIGHT 64
uLipe 0:ead5ee0a33fa 12 #define LCD_WIDTH 128
uLipe 0:ead5ee0a33fa 13
uLipe 0:ead5ee0a33fa 14 /* LCD font dimensions */
uLipe 0:ead5ee0a33fa 15 #define FONT_HEIGHT 10
uLipe 0:ead5ee0a33fa 16 #define FONT_WIDTH 5
uLipe 0:ead5ee0a33fa 17
uLipe 0:ead5ee0a33fa 18
uLipe 0:ead5ee0a33fa 19 /** Instance a on board GLCD object */
uLipe 0:ead5ee0a33fa 20 ST7567 glcd(D11, D13, D12, D9, D10);
uLipe 0:ead5ee0a33fa 21
uLipe 0:ead5ee0a33fa 22
uLipe 0:ead5ee0a33fa 23 /* allocate statically stacks for the three threads */
uLipe 0:ead5ee0a33fa 24 unsigned char app1_stk[1024];
uLipe 0:ead5ee0a33fa 25 unsigned char app2_stk[1024];
uLipe 0:ead5ee0a33fa 26 unsigned char app3_stk[1024];
uLipe 0:ead5ee0a33fa 27 unsigned char shell_stk[4096];
uLipe 0:ead5ee0a33fa 28
uLipe 0:ead5ee0a33fa 29 /* creates three tread objects with different priorities */
uLipe 0:ead5ee0a33fa 30 Thread app1_thread(osPriorityNormal, 1024, &app1_stk[0]);
uLipe 0:ead5ee0a33fa 31 Thread app2_thread(osPriorityHigh, 1024, &app2_stk[0]);
uLipe 0:ead5ee0a33fa 32 Thread app3_thread(osPriorityNormal, 1024, &app3_stk[0]);
uLipe 0:ead5ee0a33fa 33 Thread shell_thread(osPriorityRealtime, 4096, &shell_stk[0]);
uLipe 0:ead5ee0a33fa 34
uLipe 0:ead5ee0a33fa 35
uLipe 0:ead5ee0a33fa 36 /** Instance a UART class to communicate with pc */
uLipe 0:ead5ee0a33fa 37 Serial pc_serial(USBTX,USBRX);
uLipe 0:ead5ee0a33fa 38
uLipe 0:ead5ee0a33fa 39
uLipe 0:ead5ee0a33fa 40 /**
uLipe 0:ead5ee0a33fa 41 * @brief application demo task
uLipe 0:ead5ee0a33fa 42 */
uLipe 0:ead5ee0a33fa 43 void app1_task(void) {
uLipe 0:ead5ee0a33fa 44 const char thread_message[] = {"app1_task now running! \0"};
uLipe 0:ead5ee0a33fa 45 for(;;) {
uLipe 0:ead5ee0a33fa 46 app1_thread.signal_wait(1);
uLipe 0:ead5ee0a33fa 47 app1_thread.signal_set(1);
uLipe 0:ead5ee0a33fa 48 glcd.locate((LCD_WIDTH - (FONT_WIDTH * sizeof(thread_message)))/2,
uLipe 0:ead5ee0a33fa 49 (LCD_HEIGHT - FONT_HEIGHT) / 2);
uLipe 0:ead5ee0a33fa 50 glcd.printf(thread_message);
uLipe 0:ead5ee0a33fa 51 }
uLipe 0:ead5ee0a33fa 52 }
uLipe 0:ead5ee0a33fa 53
uLipe 0:ead5ee0a33fa 54 /**
uLipe 0:ead5ee0a33fa 55 * @brief application demo task
uLipe 0:ead5ee0a33fa 56 */
uLipe 0:ead5ee0a33fa 57 void app2_task(void) {
uLipe 0:ead5ee0a33fa 58 const char thread_message[] = {"app2_task now running! \0"};
uLipe 0:ead5ee0a33fa 59
uLipe 0:ead5ee0a33fa 60 for(;;) {
uLipe 0:ead5ee0a33fa 61 app2_thread.signal_wait(1);
uLipe 0:ead5ee0a33fa 62 app2_thread.signal_set(1);
uLipe 0:ead5ee0a33fa 63 glcd.locate((LCD_WIDTH - (FONT_WIDTH * sizeof(thread_message)))/2,
uLipe 0:ead5ee0a33fa 64 (LCD_HEIGHT - FONT_HEIGHT) / 2);
uLipe 0:ead5ee0a33fa 65 glcd.printf(thread_message);
uLipe 0:ead5ee0a33fa 66 }
uLipe 0:ead5ee0a33fa 67 }
uLipe 0:ead5ee0a33fa 68
uLipe 0:ead5ee0a33fa 69
uLipe 0:ead5ee0a33fa 70
uLipe 0:ead5ee0a33fa 71 /**
uLipe 0:ead5ee0a33fa 72 * @brief application demo task
uLipe 0:ead5ee0a33fa 73 */
uLipe 0:ead5ee0a33fa 74 void app3_task(void) {
uLipe 0:ead5ee0a33fa 75 const char thread_message[] = {"app3_task now running! \0"};
uLipe 0:ead5ee0a33fa 76
uLipe 0:ead5ee0a33fa 77 for(;;) {
uLipe 0:ead5ee0a33fa 78 app3_thread.signal_wait(1);
uLipe 0:ead5ee0a33fa 79 app3_thread.signal_set(1);
uLipe 0:ead5ee0a33fa 80 glcd.locate((LCD_WIDTH - (FONT_WIDTH * sizeof(thread_message)))/2,
uLipe 0:ead5ee0a33fa 81 (LCD_HEIGHT - FONT_HEIGHT) / 2);
uLipe 0:ead5ee0a33fa 82 glcd.printf(thread_message);
uLipe 0:ead5ee0a33fa 83 }
uLipe 0:ead5ee0a33fa 84 }
uLipe 0:ead5ee0a33fa 85
uLipe 0:ead5ee0a33fa 86
uLipe 0:ead5ee0a33fa 87 /**
uLipe 0:ead5ee0a33fa 88 * @brief thread_command interpreter
uLipe 0:ead5ee0a33fa 89 */
uLipe 0:ead5ee0a33fa 90 void shell_thread_execute_command(int argc, char **argv){
uLipe 0:ead5ee0a33fa 91
uLipe 0:ead5ee0a33fa 92 Thread *ptr;
uLipe 0:ead5ee0a33fa 93
uLipe 0:ead5ee0a33fa 94 /* check the argument number */
uLipe 0:ead5ee0a33fa 95 if(argc < 2) {
uLipe 0:ead5ee0a33fa 96 pc_serial.printf("## thread: too few arguments, exiting \n\r");
uLipe 0:ead5ee0a33fa 97 return;
uLipe 0:ead5ee0a33fa 98 }
uLipe 0:ead5ee0a33fa 99
uLipe 0:ead5ee0a33fa 100 /* check which thread the shell command is claiming */
uLipe 0:ead5ee0a33fa 101 if(strcmp("app1", argv[0])== 0) {
uLipe 0:ead5ee0a33fa 102 ptr = &app1_thread;
uLipe 0:ead5ee0a33fa 103 }else if (strcmp("app2", argv[0])==0) {
uLipe 0:ead5ee0a33fa 104 ptr = &app2_thread;
uLipe 0:ead5ee0a33fa 105 } else if (strcmp("app3", argv[0])==0) {
uLipe 0:ead5ee0a33fa 106 ptr = &app3_thread;
uLipe 0:ead5ee0a33fa 107 }else {
uLipe 0:ead5ee0a33fa 108 /* oops! invalid thread */
uLipe 0:ead5ee0a33fa 109 pc_serial.printf("## thread: invalid thread argument, exiting! \n\r");
uLipe 0:ead5ee0a33fa 110 return;
uLipe 0:ead5ee0a33fa 111 }
uLipe 0:ead5ee0a33fa 112
uLipe 0:ead5ee0a33fa 113
uLipe 0:ead5ee0a33fa 114 /* select which command */
uLipe 0:ead5ee0a33fa 115 if(strcmp("resume", argv[1])== 0) {
uLipe 0:ead5ee0a33fa 116 glcd.cls();
uLipe 0:ead5ee0a33fa 117 ptr->signal_set(1);
uLipe 0:ead5ee0a33fa 118 pc_serial.printf("## thread: Resuming the %s task! \n\r", argv[0]);
uLipe 0:ead5ee0a33fa 119 }else if (strcmp("suspend", argv[1]) == 0) {
uLipe 0:ead5ee0a33fa 120 glcd.cls();
uLipe 0:ead5ee0a33fa 121 ptr->signal_clr(1);
uLipe 0:ead5ee0a33fa 122 pc_serial.printf("## thread: Suspending the %s task! \n\r", argv[0]);
uLipe 0:ead5ee0a33fa 123 }else{
uLipe 0:ead5ee0a33fa 124 /* oops! invalid thread */
uLipe 0:ead5ee0a33fa 125 pc_serial.printf("## thread: invalid option argument, exiting! \n\r");
uLipe 0:ead5ee0a33fa 126 return;
uLipe 0:ead5ee0a33fa 127 }
uLipe 0:ead5ee0a33fa 128
uLipe 0:ead5ee0a33fa 129 }
uLipe 0:ead5ee0a33fa 130
uLipe 0:ead5ee0a33fa 131
uLipe 0:ead5ee0a33fa 132 /**
uLipe 0:ead5ee0a33fa 133 * @brief show help menu
uLipe 0:ead5ee0a33fa 134 */
uLipe 0:ead5ee0a33fa 135 static void print_usage(void) {
uLipe 0:ead5ee0a33fa 136 pc_serial.printf("## use with the syntax below: \n\r");
uLipe 0:ead5ee0a33fa 137 pc_serial.printf("## command <arg1> <arg2> ... <arg16> \n\r");
uLipe 0:ead5ee0a33fa 138 pc_serial.printf("## Available commands: \n\r");
uLipe 0:ead5ee0a33fa 139 pc_serial.printf("## thread <app1/2/3> <suspend|resume> : control thread execution \n\r");
uLipe 0:ead5ee0a33fa 140 pc_serial.printf("## app1/2/3: name of desired thread\n\r");
uLipe 0:ead5ee0a33fa 141 pc_serial.printf("## suspend: suspend selected thread from execution \n\r");
uLipe 0:ead5ee0a33fa 142 pc_serial.printf("## resume: resume selected thread execution \n\r");
uLipe 0:ead5ee0a33fa 143 }
uLipe 0:ead5ee0a33fa 144
uLipe 0:ead5ee0a33fa 145
uLipe 0:ead5ee0a33fa 146 /**
uLipe 0:ead5ee0a33fa 147 * @brief parse the command received via comport
uLipe 0:ead5ee0a33fa 148 */
uLipe 0:ead5ee0a33fa 149 static void shell_parser (char *cmd, int size) {
uLipe 0:ead5ee0a33fa 150 int cmd_ptr = 0;
uLipe 0:ead5ee0a33fa 151 int arg_ptr = 0;
uLipe 0:ead5ee0a33fa 152 int cmd_size = 0;
uLipe 0:ead5ee0a33fa 153 char command_buffer[256];
uLipe 0:ead5ee0a33fa 154
uLipe 0:ead5ee0a33fa 155 int argc = 0;
uLipe 0:ead5ee0a33fa 156 char *argv[16];
uLipe 0:ead5ee0a33fa 157
uLipe 0:ead5ee0a33fa 158 /* copy to the root command */
uLipe 0:ead5ee0a33fa 159 memset(&command_buffer, 0, sizeof(command_buffer));
uLipe 0:ead5ee0a33fa 160
uLipe 0:ead5ee0a33fa 161 /* find the root command terminator (space) */
uLipe 0:ead5ee0a33fa 162 while(cmd_ptr < size) {
uLipe 0:ead5ee0a33fa 163 if(cmd[cmd_ptr] == ' ') break;
uLipe 0:ead5ee0a33fa 164 cmd_ptr++;
uLipe 0:ead5ee0a33fa 165 }
uLipe 0:ead5ee0a33fa 166 cmd_size = size - cmd_ptr;
uLipe 0:ead5ee0a33fa 167
uLipe 0:ead5ee0a33fa 168
uLipe 0:ead5ee0a33fa 169 /* extract command arguments */
uLipe 0:ead5ee0a33fa 170 strncpy(&command_buffer[0], &cmd[cmd_ptr + 1], (size - cmd_ptr));
uLipe 0:ead5ee0a33fa 171
uLipe 0:ead5ee0a33fa 172 /* terminates the root command */
uLipe 0:ead5ee0a33fa 173 cmd[cmd_ptr] = 0;
uLipe 0:ead5ee0a33fa 174 arg_ptr = 0;
uLipe 0:ead5ee0a33fa 175
uLipe 0:ead5ee0a33fa 176 //pc_serial.printf("## command: %s \n\r", cmd);
uLipe 0:ead5ee0a33fa 177 //pc_serial.printf("## arguments: %s \n\r", command_buffer);
uLipe 0:ead5ee0a33fa 178
uLipe 0:ead5ee0a33fa 179
uLipe 0:ead5ee0a33fa 180 /* extract the further arguments */
uLipe 0:ead5ee0a33fa 181 while(arg_ptr < (cmd_size)) {
uLipe 0:ead5ee0a33fa 182
uLipe 0:ead5ee0a33fa 183 argc++;
uLipe 0:ead5ee0a33fa 184 *(argv + (argc- 1)) = &command_buffer[arg_ptr];
uLipe 0:ead5ee0a33fa 185
uLipe 0:ead5ee0a33fa 186 /* find terminator */
uLipe 0:ead5ee0a33fa 187 while(command_buffer[arg_ptr] != ' ') {
uLipe 0:ead5ee0a33fa 188 arg_ptr++;
uLipe 0:ead5ee0a33fa 189 }
uLipe 0:ead5ee0a33fa 190
uLipe 0:ead5ee0a33fa 191 /* adds to argument list */
uLipe 0:ead5ee0a33fa 192 command_buffer[arg_ptr] = 0;
uLipe 0:ead5ee0a33fa 193 arg_ptr++;
uLipe 0:ead5ee0a33fa 194 // pc_serial.printf("## argument no: %d : %s \n\r", argc, argv[argc-1]);
uLipe 0:ead5ee0a33fa 195 }
uLipe 0:ead5ee0a33fa 196
uLipe 0:ead5ee0a33fa 197
uLipe 0:ead5ee0a33fa 198
uLipe 0:ead5ee0a33fa 199 /* finds and execute the command table */
uLipe 0:ead5ee0a33fa 200 if(strcmp("thread", cmd) == 0) {
uLipe 0:ead5ee0a33fa 201 shell_thread_execute_command(argc, argv);
uLipe 0:ead5ee0a33fa 202 } else {
uLipe 0:ead5ee0a33fa 203 print_usage();
uLipe 0:ead5ee0a33fa 204 }
uLipe 0:ead5ee0a33fa 205
uLipe 0:ead5ee0a33fa 206 }
uLipe 0:ead5ee0a33fa 207
uLipe 0:ead5ee0a33fa 208
uLipe 0:ead5ee0a33fa 209
uLipe 0:ead5ee0a33fa 210
uLipe 0:ead5ee0a33fa 211 /**
uLipe 0:ead5ee0a33fa 212 * @brief shell commands processing thread
uLipe 0:ead5ee0a33fa 213 */
uLipe 0:ead5ee0a33fa 214 static void shell_task(void)
uLipe 0:ead5ee0a33fa 215 {
uLipe 0:ead5ee0a33fa 216 char serial_buffer[1024] = {0};
uLipe 0:ead5ee0a33fa 217 int read_ptr = 0;
uLipe 0:ead5ee0a33fa 218 const char msg[] = {"Welcome to NXP FTF !\0"};
uLipe 0:ead5ee0a33fa 219
uLipe 0:ead5ee0a33fa 220 /* setup the serial as 115200 bps */
uLipe 0:ead5ee0a33fa 221 pc_serial.baud(115200);
uLipe 0:ead5ee0a33fa 222
uLipe 0:ead5ee0a33fa 223 /* setup our on-board glcd */
uLipe 0:ead5ee0a33fa 224 glcd.set_contrast(0x35);
uLipe 0:ead5ee0a33fa 225 glcd.cls();
uLipe 0:ead5ee0a33fa 226
uLipe 0:ead5ee0a33fa 227 /* Center the LCD cursor based on message size*/
uLipe 0:ead5ee0a33fa 228 glcd.locate(LCD_WIDTH - (sizeof(msg) * FONT_WIDTH),
uLipe 0:ead5ee0a33fa 229 (LCD_HEIGHT - FONT_HEIGHT) / 2);
uLipe 0:ead5ee0a33fa 230
uLipe 0:ead5ee0a33fa 231
uLipe 0:ead5ee0a33fa 232 /* prints a welcome message */
uLipe 0:ead5ee0a33fa 233 glcd.printf(msg);
uLipe 0:ead5ee0a33fa 234
uLipe 0:ead5ee0a33fa 235 glcd.cls();
uLipe 0:ead5ee0a33fa 236 Thread::wait(1000);
uLipe 0:ead5ee0a33fa 237
uLipe 0:ead5ee0a33fa 238
uLipe 0:ead5ee0a33fa 239 pc_serial.printf("******************************************************************\n\r");
uLipe 0:ead5ee0a33fa 240 pc_serial.printf("*** Welcome to NXP FTF Simple Shell application ****\n\r");
uLipe 0:ead5ee0a33fa 241 pc_serial.printf("*** Type some commands or just Enter key to see the available ****\n\r");
uLipe 0:ead5ee0a33fa 242 pc_serial.printf("******************************************************************\n\r");
uLipe 0:ead5ee0a33fa 243 pc_serial.printf(">>");
uLipe 0:ead5ee0a33fa 244
uLipe 0:ead5ee0a33fa 245 for(;;Thread::wait(50)) {
uLipe 0:ead5ee0a33fa 246 /* check if we have character available */
uLipe 0:ead5ee0a33fa 247 if(pc_serial.readable()) {
uLipe 0:ead5ee0a33fa 248 bool new_cmd = false;
uLipe 0:ead5ee0a33fa 249
uLipe 0:ead5ee0a33fa 250
uLipe 0:ead5ee0a33fa 251 /* get the incoming character */
uLipe 0:ead5ee0a33fa 252 char c = pc_serial.getc();
uLipe 0:ead5ee0a33fa 253 pc_serial.putc(c);
uLipe 0:ead5ee0a33fa 254
uLipe 0:ead5ee0a33fa 255
uLipe 0:ead5ee0a33fa 256 /* is a enter ? */
uLipe 0:ead5ee0a33fa 257 if( (c == '\n') || (c == '\r')) {
uLipe 0:ead5ee0a33fa 258 new_cmd = true;
uLipe 0:ead5ee0a33fa 259 pc_serial.getc();
uLipe 0:ead5ee0a33fa 260
uLipe 0:ead5ee0a33fa 261 } else {
uLipe 0:ead5ee0a33fa 262 serial_buffer[read_ptr] = c;
uLipe 0:ead5ee0a33fa 263 read_ptr = (read_ptr + 1) % 1024;
uLipe 0:ead5ee0a33fa 264 }
uLipe 0:ead5ee0a33fa 265
uLipe 0:ead5ee0a33fa 266 if(new_cmd != false) {
uLipe 0:ead5ee0a33fa 267 /* command arrived, has other characters? */
uLipe 0:ead5ee0a33fa 268 if(read_ptr != 0) {
uLipe 0:ead5ee0a33fa 269 shell_parser(&serial_buffer[0], read_ptr);
uLipe 0:ead5ee0a33fa 270 } else {
uLipe 0:ead5ee0a33fa 271 print_usage();
uLipe 0:ead5ee0a33fa 272 }
uLipe 0:ead5ee0a33fa 273 /* reset the buffer command */
uLipe 0:ead5ee0a33fa 274 memset(&serial_buffer, 0, sizeof(serial_buffer));
uLipe 0:ead5ee0a33fa 275 read_ptr = 0;
uLipe 0:ead5ee0a33fa 276 pc_serial.printf(">>");
uLipe 0:ead5ee0a33fa 277 }
uLipe 0:ead5ee0a33fa 278
uLipe 0:ead5ee0a33fa 279 }
uLipe 0:ead5ee0a33fa 280 }
uLipe 0:ead5ee0a33fa 281 }
uLipe 0:ead5ee0a33fa 282
uLipe 0:ead5ee0a33fa 283 static void idle_hook(void) {
uLipe 0:ead5ee0a33fa 284 const char thread_message[] = {"No thread running! \0"};
uLipe 0:ead5ee0a33fa 285 glcd.locate((LCD_WIDTH - (FONT_WIDTH * sizeof(thread_message)))/2,
uLipe 0:ead5ee0a33fa 286 (LCD_HEIGHT - FONT_HEIGHT) / 2);
uLipe 0:ead5ee0a33fa 287 glcd.printf(thread_message);
uLipe 0:ead5ee0a33fa 288 }
uLipe 0:ead5ee0a33fa 289
uLipe 0:ead5ee0a33fa 290 /**
uLipe 0:ead5ee0a33fa 291 * @brief main application loop
uLipe 0:ead5ee0a33fa 292 */
uLipe 0:ead5ee0a33fa 293 int main(void)
uLipe 0:ead5ee0a33fa 294 {
uLipe 0:ead5ee0a33fa 295
uLipe 0:ead5ee0a33fa 296 glcd.cls();
uLipe 0:ead5ee0a33fa 297
uLipe 0:ead5ee0a33fa 298 /* starts the shell task and applications task*/
uLipe 0:ead5ee0a33fa 299 shell_thread.attach_idle_hook(idle_hook);
uLipe 0:ead5ee0a33fa 300 shell_thread.start(shell_task);
uLipe 0:ead5ee0a33fa 301 app1_thread.start(app1_task);
uLipe 0:ead5ee0a33fa 302 app2_thread.start(app2_task);
uLipe 0:ead5ee0a33fa 303 app3_thread.start(app3_task);
uLipe 0:ead5ee0a33fa 304 return 0;
uLipe 0:ead5ee0a33fa 305 }