Wio终端不但支持裸机运行,还为其配置了RTOS操作系统。 利用所提供的例程可测试其性能,并可学习其编程思想并加以应用。 该例程含有2个线程,即线程A和线程B,相应的程序内容如下: - //*****************************************************************
- // Create a thread that prints out A to the screen every two seconds
- // this task will delete its self after printing out afew messages
- //*****************************************************************
- static void threadA(void* pvParameters) {
- SERIAL.println("Thread A: Started");
- for (int x = 0; x < 20; ++x) {
- SERIAL.print("A");
- delay(500);
- }
- // delete ourselves.
- // Have to call this or the system crashes when you reach the end bracket and then get scheduled.
- SERIAL.println("Thread A: Deleting");
- vTaskDelete(NULL);
- }
- //*****************************************************************
- // Create a thread that prints out B to the screen every second
- // this task will run forever
- //*****************************************************************
- static void threadB(void* pvParameters) {
- SERIAL.println("Thread B: Started");
- while (1) {
- SERIAL.println("B");
- delay(2000);
- }
- }
复制代码
其中,线程A的作用是通过延时来打印输出字符“A”,以表示是线程A的处理;而线程B的作用也与其基本相同,所打印输出的是字符“B”,并实行换行。两者最大的区别在于延时值的不同,其中线程A的打印间隔是500毫秒,而线程B的打印间隔是2000毫秒,这样将就导致其输出时出现出交叠的情况。 为监控线程的运行,其任务监视器的程序为: - //*****************************************************************
- // Task will periodicallt print out useful information about the tasks running
- // Is a useful tool to help figure out stack sizes being used
- //*****************************************************************
- void taskMonitor(void* pvParameters) {
- int x;
- int measurement;
- SERIAL.println("Task Monitor: Started");
- // run this task afew times before exiting forever
- for (x = 0; x < 10; ++x) {
- SERIAL.println("");
- SERIAL.println("******************************");
- SERIAL.println("[Stacks Free Bytes Remaining] ");
- measurement = uxTaskGetStackHighWaterMark(Handle_aTask);
- SERIAL.print("Thread A: ");
- SERIAL.println(measurement);
- measurement = uxTaskGetStackHighWaterMark(Handle_bTask);
- SERIAL.print("Thread B: ");
- SERIAL.println(measurement);
- measurement = uxTaskGetStackHighWaterMark(Handle_monitorTask);
- SERIAL.print("Monitor Stack: ");
- SERIAL.println(measurement);
- SERIAL.println("******************************");
- delay(10000); // print every 10 seconds
- }
- // delete ourselves.
- // Have to call this or the system crashes when you reach the end bracket and then get scheduled.
- SERIAL.println("Task Monitor: Deleting");
- vTaskDelete(NULL);
- }
复制代码
状态配置和循环程序为: - void setup() {
- SERIAL.begin(115200);
- vNopDelayMS(1000); // prevents usb driver crash on startup, do not omit this
- while (!SERIAL) ; // Wait for serial terminal to open port before starting program
- SERIAL.println("");
- SERIAL.println("******************************");
- SERIAL.println(" Program start ");
- SERIAL.println("******************************");
- // Set the led the rtos will blink when we have a fatal rtos error
- // RTOS also Needs to know if high/low is the state that turns on the led.
- // Error Blink Codes:
- // 3 blinks - Fatal Rtos Error, something bad happened. Think really hard about what you just changed.
- // 2 blinks - Malloc Failed, Happens when you couldn't create a rtos object.
- // Probably ran out of heap.
- // 1 blink - Stack overflow, Task needs more bytes defined for its stack!
- // Use the taskMonitor thread to help gauge how much more you need
- vSetErrorLed(ERROR_LED_PIN, ERROR_LED_LIGHTUP_STATE);
- // Create the threads that will be managed by the rtos
- // Sets the stack size and priority of each task
- // Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks
- xTaskCreate(threadA, "Task A", 256, NULL, tskIDLE_PRIORITY + 3, &Handle_aTask);
- xTaskCreate(threadB, "Task B", 256, NULL, tskIDLE_PRIORITY + 2, &Handle_bTask);
- xTaskCreate(taskMonitor, "Task Monitor", 256, NULL, tskIDLE_PRIORITY + 1, &Handle_monitorTask);
- // Start the RTOS, this function will never return and will schedule the tasks.
- vTaskStartScheduler();
- while(1);
- }
- void loop() {
- }
复制代码
经程序的编译上传,其结果如图1和图2所示。 由于线程A的打印间隔是500毫秒,而线程B的打印间隔是2000毫秒且换行,故每打印4个字符“A”,打印1个字符“B”,且自动换行(2000/500=4 --> AAAAB)。 仿此,我们可以设计自己的并行程度要求较高的线程任务。 图1 程序编译与上传
图2 运行效果
|