From 72782e920325808bbc58fc2344fc52033479b627 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Tue, 8 Jan 2013 05:05:02 -0800 Subject: convert end of line --- examples/file/listdir.c | 112 +- examples/file/readspeed.c | 128 +-- examples/file/readwrite.c | 246 ++--- examples/file/seekdir.c | 100 +- examples/file/writespeed.c | 144 +-- examples/kernel/SConscript | 78 +- examples/kernel/heap_malloc.c | 144 +-- examples/kernel/heap_realloc.c | 166 +-- examples/kernel/mutex_simple.c | 326 +++--- examples/kernel/semaphore_buffer_worker.c | 534 ++++----- examples/kernel/semaphore_dynamic.c | 256 ++--- examples/kernel/semaphore_priority.c | 256 ++--- examples/kernel/semaphore_producer_consumer.c | 308 +++--- examples/kernel/semaphore_static.c | 264 ++--- examples/kernel/tc_comm.c | 352 +++--- examples/kernel/tc_comm.h | 86 +- examples/kernel/thread_delay.c | 140 +-- examples/kernel/thread_delete.c | 288 ++--- examples/kernel/thread_detach.c | 236 ++-- examples/kernel/thread_dynamic.c | 88 +- examples/kernel/thread_dynamic_simple.c | 178 +-- examples/kernel/thread_priority.c | 210 ++-- examples/kernel/thread_resume.c | 246 ++--- examples/kernel/thread_same_priority.c | 192 ++-- examples/kernel/thread_static.c | 104 +- examples/kernel/thread_static_simple.c | 198 ++-- examples/kernel/thread_suspend.c | 202 ++-- examples/kernel/thread_yield.c | 202 ++-- examples/kernel/timer_control.c | 168 +-- examples/kernel/timer_dynamic.c | 182 +-- examples/kernel/timer_stop_self.c | 164 +-- examples/kernel/timer_timeout.c | 244 ++--- examples/libc/SConscript | 12 +- examples/libc/dirent.c | 112 +- examples/libc/env.c | 36 +- examples/libc/file.c | 1032 ++++++++--------- examples/libc/memory.c | 112 +- examples/libc/mq.c | 238 ++-- examples/libc/printf.c | 400 +++---- examples/libc/rand.c | 86 +- examples/libc/sem.c | 130 +-- examples/libc/time.c | 48 +- examples/module/README | 8 +- examples/module/SConstruct | 146 +-- examples/module/basicapp/Sconscript | 12 +- examples/module/extapp/Sconscript | 12 +- examples/module/rtconfig.py | 46 +- examples/module/rtconfig_lm3s.py | 46 +- examples/module/tetris/Sconscript | 12 +- examples/module/tetris/tetris.h | 122 +-- examples/module/tetris/tetris_modal.c | 1460 ++++++++++++------------- examples/module/tetris/tetris_ui.c | 478 ++++---- examples/module/tetris/tetris_view.c | 436 ++++---- examples/network/tcpclient.c | 196 ++-- examples/network/tcpsendpacket.c | 126 +-- examples/network/tcpserver.c | 244 ++--- examples/network/udpclient.c | 100 +- examples/network/udpserver.c | 172 +-- examples/test/dhry.h | 824 +++++++------- examples/test/dhry_1.c | 698 ++++++------ examples/test/fs_test.c | 594 +++++----- examples/test/mem_test.c | 210 ++-- examples/test/net_test.c | 564 +++++----- 63 files changed, 7627 insertions(+), 7627 deletions(-) (limited to 'examples') diff --git a/examples/file/listdir.c b/examples/file/listdir.c index 991351fc6c..cf91bc77d4 100644 --- a/examples/file/listdir.c +++ b/examples/file/listdir.c @@ -1,56 +1,56 @@ -/* - * File : listdir.c - * This file is part of RT-TestCase in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-02-10 Bernard first version - */ -#include -#include - -static char fullpath[256]; -void list_dir(const char* path) -{ - DIR *dir; - - dir = opendir(path); - if (dir != RT_NULL) - { - struct dirent* dirent; - struct stat s; - - do - { - dirent = readdir(dir); - if (dirent == RT_NULL) break; - rt_memset(&s, 0, sizeof(struct stat)); - - /* build full path for each file */ - rt_sprintf(fullpath, "%s/%s", path, dirent->d_name); - - stat(fullpath, &s); - if ( s.st_mode & DFS_S_IFDIR ) - { - rt_kprintf("%s\t\t\n", dirent->d_name); - } - else - { - rt_kprintf("%s\t\t%lu\n", dirent->d_name, s.st_size); - } - } while (dirent != RT_NULL); - - closedir(dir); - } - else rt_kprintf("open %s directory failed\n", path); -} - -#ifdef RT_USING_FINSH -#include -FINSH_FUNCTION_EXPORT(list_dir, list directory); -#endif +/* + * File : listdir.c + * This file is part of RT-TestCase in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-02-10 Bernard first version + */ +#include +#include + +static char fullpath[256]; +void list_dir(const char* path) +{ + DIR *dir; + + dir = opendir(path); + if (dir != RT_NULL) + { + struct dirent* dirent; + struct stat s; + + do + { + dirent = readdir(dir); + if (dirent == RT_NULL) break; + rt_memset(&s, 0, sizeof(struct stat)); + + /* build full path for each file */ + rt_sprintf(fullpath, "%s/%s", path, dirent->d_name); + + stat(fullpath, &s); + if ( s.st_mode & DFS_S_IFDIR ) + { + rt_kprintf("%s\t\t\n", dirent->d_name); + } + else + { + rt_kprintf("%s\t\t%lu\n", dirent->d_name, s.st_size); + } + } while (dirent != RT_NULL); + + closedir(dir); + } + else rt_kprintf("open %s directory failed\n", path); +} + +#ifdef RT_USING_FINSH +#include +FINSH_FUNCTION_EXPORT(list_dir, list directory); +#endif diff --git a/examples/file/readspeed.c b/examples/file/readspeed.c index d83fdcb20f..52f15b627b 100644 --- a/examples/file/readspeed.c +++ b/examples/file/readspeed.c @@ -1,64 +1,64 @@ -/* - * File : readspeed.c - * This file is part of RT-TestCase in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-02-10 Bernard first version - */ - -#include -#include - -void readspeed(const char* filename, int block_size) -{ - int fd; - char *buff_ptr; - rt_size_t total_length; - rt_tick_t tick; - - fd = open(filename, 0, O_RDONLY); - if (fd < 0) - { - rt_kprintf("open file:%s failed\n", filename); - return; - } - - buff_ptr = rt_malloc(block_size); - if (buff_ptr == RT_NULL) - { - rt_kprintf("no memory\n"); - close(fd); - - return; - } - - tick = rt_tick_get(); - total_length = 0; - while (1) - { - int length; - length = read(fd, buff_ptr, block_size); - - if (length <= 0) break; - total_length += length; - } - tick = rt_tick_get() - tick; - - /* close file and release memory */ - close(fd); - rt_free(buff_ptr); - - /* calculate read speed */ - rt_kprintf("File read speed: %d byte/s\n", total_length /tick * RT_TICK_PER_SECOND); -} - -#ifdef RT_USING_FINSH -#include -FINSH_FUNCTION_EXPORT(readspeed, perform file read test); -#endif +/* + * File : readspeed.c + * This file is part of RT-TestCase in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-02-10 Bernard first version + */ + +#include +#include + +void readspeed(const char* filename, int block_size) +{ + int fd; + char *buff_ptr; + rt_size_t total_length; + rt_tick_t tick; + + fd = open(filename, 0, O_RDONLY); + if (fd < 0) + { + rt_kprintf("open file:%s failed\n", filename); + return; + } + + buff_ptr = rt_malloc(block_size); + if (buff_ptr == RT_NULL) + { + rt_kprintf("no memory\n"); + close(fd); + + return; + } + + tick = rt_tick_get(); + total_length = 0; + while (1) + { + int length; + length = read(fd, buff_ptr, block_size); + + if (length <= 0) break; + total_length += length; + } + tick = rt_tick_get() - tick; + + /* close file and release memory */ + close(fd); + rt_free(buff_ptr); + + /* calculate read speed */ + rt_kprintf("File read speed: %d byte/s\n", total_length /tick * RT_TICK_PER_SECOND); +} + +#ifdef RT_USING_FINSH +#include +FINSH_FUNCTION_EXPORT(readspeed, perform file read test); +#endif diff --git a/examples/file/readwrite.c b/examples/file/readwrite.c index 17d173c353..6f25249c61 100644 --- a/examples/file/readwrite.c +++ b/examples/file/readwrite.c @@ -1,123 +1,123 @@ -/* - * 代码清单:文件读写例子 - * - * 这个例子演示了如何读写一个文件,特别是写的时候应该如何操作。 - */ - -#include -#include /* 当需要使用文件操作时,需要包含这个头文件 */ - -#define TEST_FN "/test.dat" - -/* 测试用的数据和缓冲 */ -static char test_data[120], buffer[120]; - -/* 文件读写测试 */ -void readwrite(const char* filename) -{ - int fd; - int index, length; - - /* 只写 & 创建 打开 */ - fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0); - if (fd < 0) - { - rt_kprintf("open file for write failed\n"); - return; - } - - /* 准备写入数据 */ - for (index = 0; index < sizeof(test_data); index ++) - { - test_data[index] = index + 27; - } - - /* 写入数据 */ - length = write(fd, test_data, sizeof(test_data)); - if (length != sizeof(test_data)) - { - rt_kprintf("write data failed\n"); - close(fd); - return; - } - - /* 关闭文件 */ - close(fd); - - /* 只写并在末尾添加打开 */ - fd = open(TEST_FN, O_WRONLY | O_CREAT | O_APPEND, 0); - if (fd < 0) - { - rt_kprintf("open file for append write failed\n"); - return; - } - - length = write(fd, test_data, sizeof(test_data)); - if (length != sizeof(test_data)) - { - rt_kprintf("append write data failed\n"); - close(fd); - return; - } - /* 关闭文件 */ - close(fd); - - /* 只读打开进行数据校验 */ - fd = open(TEST_FN, O_RDONLY, 0); - if (fd < 0) - { - rt_kprintf("check: open file for read failed\n"); - return; - } - - /* 读取数据(应该为第一次写入的数据) */ - length = read(fd, buffer, sizeof(buffer)); - if (length != sizeof(buffer)) - { - rt_kprintf("check: read file failed\n"); - close(fd); - return; - } - - /* 检查数据是否正确 */ - for (index = 0; index < sizeof(test_data); index ++) - { - if (test_data[index] != buffer[index]) - { - rt_kprintf("check: check data failed at %d\n", index); - close(fd); - return; - } - } - - /* 读取数据(应该为第二次写入的数据) */ - length = read(fd, buffer, sizeof(buffer)); - if (length != sizeof(buffer)) - { - rt_kprintf("check: read file failed\n"); - close(fd); - return; - } - - /* 检查数据是否正确 */ - for (index = 0; index < sizeof(test_data); index ++) - { - if (test_data[index] != buffer[index]) - { - rt_kprintf("check: check data failed at %d\n", index); - close(fd); - return; - } - } - - /* 检查数据完毕,关闭文件 */ - close(fd); - /* 打印结果 */ - rt_kprintf("read/write done.\n"); -} - -#ifdef RT_USING_FINSH -#include -/* 输出函数到finsh shell命令行中 */ -FINSH_FUNCTION_EXPORT(readwrite, perform file read and write test); -#endif +/* + * 代码清单:文件读写例子 + * + * 这个例子演示了如何读写一个文件,特别是写的时候应该如何操作。 + */ + +#include +#include /* 当需要使用文件操作时,需要包含这个头文件 */ + +#define TEST_FN "/test.dat" + +/* 测试用的数据和缓冲 */ +static char test_data[120], buffer[120]; + +/* 文件读写测试 */ +void readwrite(const char* filename) +{ + int fd; + int index, length; + + /* 只写 & 创建 打开 */ + fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0); + if (fd < 0) + { + rt_kprintf("open file for write failed\n"); + return; + } + + /* 准备写入数据 */ + for (index = 0; index < sizeof(test_data); index ++) + { + test_data[index] = index + 27; + } + + /* 写入数据 */ + length = write(fd, test_data, sizeof(test_data)); + if (length != sizeof(test_data)) + { + rt_kprintf("write data failed\n"); + close(fd); + return; + } + + /* 关闭文件 */ + close(fd); + + /* 只写并在末尾添加打开 */ + fd = open(TEST_FN, O_WRONLY | O_CREAT | O_APPEND, 0); + if (fd < 0) + { + rt_kprintf("open file for append write failed\n"); + return; + } + + length = write(fd, test_data, sizeof(test_data)); + if (length != sizeof(test_data)) + { + rt_kprintf("append write data failed\n"); + close(fd); + return; + } + /* 关闭文件 */ + close(fd); + + /* 只读打开进行数据校验 */ + fd = open(TEST_FN, O_RDONLY, 0); + if (fd < 0) + { + rt_kprintf("check: open file for read failed\n"); + return; + } + + /* 读取数据(应该为第一次写入的数据) */ + length = read(fd, buffer, sizeof(buffer)); + if (length != sizeof(buffer)) + { + rt_kprintf("check: read file failed\n"); + close(fd); + return; + } + + /* 检查数据是否正确 */ + for (index = 0; index < sizeof(test_data); index ++) + { + if (test_data[index] != buffer[index]) + { + rt_kprintf("check: check data failed at %d\n", index); + close(fd); + return; + } + } + + /* 读取数据(应该为第二次写入的数据) */ + length = read(fd, buffer, sizeof(buffer)); + if (length != sizeof(buffer)) + { + rt_kprintf("check: read file failed\n"); + close(fd); + return; + } + + /* 检查数据是否正确 */ + for (index = 0; index < sizeof(test_data); index ++) + { + if (test_data[index] != buffer[index]) + { + rt_kprintf("check: check data failed at %d\n", index); + close(fd); + return; + } + } + + /* 检查数据完毕,关闭文件 */ + close(fd); + /* 打印结果 */ + rt_kprintf("read/write done.\n"); +} + +#ifdef RT_USING_FINSH +#include +/* 输出函数到finsh shell命令行中 */ +FINSH_FUNCTION_EXPORT(readwrite, perform file read and write test); +#endif diff --git a/examples/file/seekdir.c b/examples/file/seekdir.c index 831023f8eb..1cf8b5fd78 100644 --- a/examples/file/seekdir.c +++ b/examples/file/seekdir.c @@ -1,50 +1,50 @@ -/* - * File : seekdir.c - * This file is part of RT-TestCase in RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2011-06-02 Bernard first version - */ -#include - -void seekdir_test(void) -{ - DIR * dirp; - long save3 = 0; - long cur; - int i = 0; - struct dirent *dp; - - dirp = opendir ("/"); - save3 = telldir(dirp); - for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp)) - { - rt_kprintf("direntry: %s\n", dp->d_name); - - /* ±£´æµÚÈý¸öĿ¼ÏîµÄĿ¼ָÕë */ - if (i++ == 3) - { - save3 = telldir(dirp); - } - } - - /* »ص½¸ղű£´æµĵÚÈý¸öĿ¼ÏîµÄĿ¼ָÕë */ - seekdir (dirp, save3); - rt_kprintf("seek dientry to: %d\n", save3); - for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp)) - { - rt_kprintf("direntry: %s\n", dp->d_name); - } - - /* ¹رÕĿ¼ */ - closedir (dirp); -} - -#include -FINSH_FUNCTION_EXPORT(seekdir_test, perform directory seek test); +/* + * File : seekdir.c + * This file is part of RT-TestCase in RT-Thread RTOS + * COPYRIGHT (C) 2011, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-06-02 Bernard first version + */ +#include + +void seekdir_test(void) +{ + DIR * dirp; + long save3 = 0; + long cur; + int i = 0; + struct dirent *dp; + + dirp = opendir ("/"); + save3 = telldir(dirp); + for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp)) + { + rt_kprintf("direntry: %s\n", dp->d_name); + + /* ±£´æµÚÈý¸öĿ¼ÏîµÄĿ¼ָÕë */ + if (i++ == 3) + { + save3 = telldir(dirp); + } + } + + /* »ص½¸ղű£´æµĵÚÈý¸öĿ¼ÏîµÄĿ¼ָÕë */ + seekdir (dirp, save3); + rt_kprintf("seek dientry to: %d\n", save3); + for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp)) + { + rt_kprintf("direntry: %s\n", dp->d_name); + } + + /* ¹رÕĿ¼ */ + closedir (dirp); +} + +#include +FINSH_FUNCTION_EXPORT(seekdir_test, perform directory seek test); diff --git a/examples/file/writespeed.c b/examples/file/writespeed.c index 5fa2f44452..ab6946888f 100644 --- a/examples/file/writespeed.c +++ b/examples/file/writespeed.c @@ -1,72 +1,72 @@ -/* - * File : writespeed.c - * This file is part of RT-TestCase in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-02-10 Bernard first version - */ -#include -#include - -void writespeed(const char* filename, int total_length, int block_size) -{ - int fd, index, length; - char *buff_ptr; - rt_tick_t tick; - - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0); - if (fd < 0) - { - rt_kprintf("open file:%s failed\n", filename); - return; - } - - buff_ptr = rt_malloc(block_size); - if (buff_ptr == RT_NULL) - { - rt_kprintf("no memory\n"); - close(fd); - - return; - } - - /* prepare write data */ - for (index = 0; index < block_size; index++) - { - buff_ptr[index] = index; - } - index = 0; - - /* get the beginning tick */ - tick = rt_tick_get(); - while (index < total_length / block_size) - { - length = write(fd, buff_ptr, block_size); - if (length != block_size) - { - rt_kprintf("write failed\n"); - break; - } - - index ++; - } - tick = rt_tick_get() - tick; - - /* close file and release memory */ - close(fd); - rt_free(buff_ptr); - - /* calculate write speed */ - rt_kprintf("File write speed: %d byte/s\n", total_length / tick * RT_TICK_PER_SECOND); -} - -#ifdef RT_USING_FINSH -#include -FINSH_FUNCTION_EXPORT(writespeed, perform file write test); -#endif +/* + * File : writespeed.c + * This file is part of RT-TestCase in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-02-10 Bernard first version + */ +#include +#include + +void writespeed(const char* filename, int total_length, int block_size) +{ + int fd, index, length; + char *buff_ptr; + rt_tick_t tick; + + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0); + if (fd < 0) + { + rt_kprintf("open file:%s failed\n", filename); + return; + } + + buff_ptr = rt_malloc(block_size); + if (buff_ptr == RT_NULL) + { + rt_kprintf("no memory\n"); + close(fd); + + return; + } + + /* prepare write data */ + for (index = 0; index < block_size; index++) + { + buff_ptr[index] = index; + } + index = 0; + + /* get the beginning tick */ + tick = rt_tick_get(); + while (index < total_length / block_size) + { + length = write(fd, buff_ptr, block_size); + if (length != block_size) + { + rt_kprintf("write failed\n"); + break; + } + + index ++; + } + tick = rt_tick_get() - tick; + + /* close file and release memory */ + close(fd); + rt_free(buff_ptr); + + /* calculate write speed */ + rt_kprintf("File write speed: %d byte/s\n", total_length / tick * RT_TICK_PER_SECOND); +} + +#ifdef RT_USING_FINSH +#include +FINSH_FUNCTION_EXPORT(writespeed, perform file write test); +#endif diff --git a/examples/kernel/SConscript b/examples/kernel/SConscript index 3610085157..bfbc80b54a 100644 --- a/examples/kernel/SConscript +++ b/examples/kernel/SConscript @@ -1,39 +1,39 @@ -from building import * - -src = Split(""" -tc_comm.c -thread_static.c -thread_dynamic.c -thread_priority.c -thread_same_priority.c -thread_static_simple.c -thread_dynamic_simple.c -thread_delete.c -thread_detach.c -thread_yield.c -thread_suspend.c -thread_resume.c -semaphore_static.c -semaphore_dynamic.c -semaphore_priority.c -semaphore_buffer_worker.c -semaphore_producer_consumer.c -mutex_simple.c -event_simple.c -mbox_simple.c -mbox_send_wait.c -messageq_simple.c -timer_static.c -timer_dynamic.c -timer_stop_self.c -timer_control.c -timer_timeout.c -heap_malloc.c -heap_realloc.c -memp_simple.c -tc_sample.c -""") - -group = DefineGroup('examples', src, depend = ['RT_USING_TC']) - -Return('group') +from building import * + +src = Split(""" +tc_comm.c +thread_static.c +thread_dynamic.c +thread_priority.c +thread_same_priority.c +thread_static_simple.c +thread_dynamic_simple.c +thread_delete.c +thread_detach.c +thread_yield.c +thread_suspend.c +thread_resume.c +semaphore_static.c +semaphore_dynamic.c +semaphore_priority.c +semaphore_buffer_worker.c +semaphore_producer_consumer.c +mutex_simple.c +event_simple.c +mbox_simple.c +mbox_send_wait.c +messageq_simple.c +timer_static.c +timer_dynamic.c +timer_stop_self.c +timer_control.c +timer_timeout.c +heap_malloc.c +heap_realloc.c +memp_simple.c +tc_sample.c +""") + +group = DefineGroup('examples', src, depend = ['RT_USING_TC']) + +Return('group') diff --git a/examples/kernel/heap_malloc.c b/examples/kernel/heap_malloc.c index 236a982fdf..0a6b46cc95 100644 --- a/examples/kernel/heap_malloc.c +++ b/examples/kernel/heap_malloc.c @@ -1,72 +1,72 @@ -#include -#include "tc_comm.h" - -/* - * This is an example for heap malloc - */ - -static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) -{ - while (len) - { - if (*ptr != value) return RT_FALSE; - - ptr ++; - len --; - } - - return RT_TRUE; -} - -static void heap_malloc_init() -{ - rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; - - ptr1 = rt_malloc(1); - ptr2 = rt_malloc(13); - ptr3 = rt_malloc(31); - ptr4 = rt_malloc(127); - ptr5 = rt_malloc(0); - - memset(ptr1, 1, 1); - memset(ptr2, 2, 13); - memset(ptr3, 3, 31); - memset(ptr4, 4, 127); - - if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; - if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; - if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; - if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed; - - rt_free(ptr4); - rt_free(ptr3); - rt_free(ptr3); - rt_free(ptr1); - - if (ptr5 != RT_NULL) - { - rt_free(ptr5); - } - - tc_done(TC_STAT_PASSED); - -_failed: - tc_done(TC_STAT_FAILED); -} - -#ifdef RT_USING_TC -int _tc_heap_malloc() -{ - heap_malloc_init(); - - return 0; -} -FINSH_FUNCTION_EXPORT(_tc_heap_malloc, a heap malloc test); -#else -int rt_application_init() -{ - heap_malloc_init(); - - return 0; -} -#endif +#include +#include "tc_comm.h" + +/* + * This is an example for heap malloc + */ + +static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) +{ + while (len) + { + if (*ptr != value) return RT_FALSE; + + ptr ++; + len --; + } + + return RT_TRUE; +} + +static void heap_malloc_init() +{ + rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; + + ptr1 = rt_malloc(1); + ptr2 = rt_malloc(13); + ptr3 = rt_malloc(31); + ptr4 = rt_malloc(127); + ptr5 = rt_malloc(0); + + memset(ptr1, 1, 1); + memset(ptr2, 2, 13); + memset(ptr3, 3, 31); + memset(ptr4, 4, 127); + + if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; + if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; + if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; + if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed; + + rt_free(ptr4); + rt_free(ptr3); + rt_free(ptr3); + rt_free(ptr1); + + if (ptr5 != RT_NULL) + { + rt_free(ptr5); + } + + tc_done(TC_STAT_PASSED); + +_failed: + tc_done(TC_STAT_FAILED); +} + +#ifdef RT_USING_TC +int _tc_heap_malloc() +{ + heap_malloc_init(); + + return 0; +} +FINSH_FUNCTION_EXPORT(_tc_heap_malloc, a heap malloc test); +#else +int rt_application_init() +{ + heap_malloc_init(); + + return 0; +} +#endif diff --git a/examples/kernel/heap_realloc.c b/examples/kernel/heap_realloc.c index 5fa96c7f30..a4974d5bf3 100644 --- a/examples/kernel/heap_realloc.c +++ b/examples/kernel/heap_realloc.c @@ -1,83 +1,83 @@ -#include -#include "tc_comm.h" - -/* - * This is an example for heap malloc - */ - -static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) -{ - while (len) - { - if (*ptr != value) return RT_FALSE; - - ptr ++; - len --; - } - - return RT_TRUE; -} - -static void heap_realloc_init() -{ - rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; - - ptr1 = rt_malloc(1); - ptr2 = rt_malloc(13); - ptr3 = rt_malloc(31); - ptr4 = rt_malloc(127); - ptr5 = rt_malloc(0); - - memset(ptr1, 1, 1); - memset(ptr2, 2, 13); - memset(ptr3, 3, 31); - memset(ptr4, 4, 127); - - if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; - if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; - if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; - if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed; - - ptr1 = rt_realloc(ptr1, 13); - ptr2 = rt_realloc(ptr2, 31); - ptr3 = rt_realloc(ptr3, 127); - ptr4 = rt_realloc(ptr4, 1); - ptr5 = rt_realloc(ptr5, 0); - - if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; - if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; - if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; - if (mem_check(ptr4, 4, 1) != RT_FALSE) goto _failed; - - rt_free(ptr4); - rt_free(ptr3); - rt_free(ptr3); - rt_free(ptr1); - - if (ptr5 != RT_NULL) - { - rt_free(ptr5); - } - - tc_done(TC_STAT_PASSED); - -_failed: - tc_done(TC_STAT_FAILED); -} - -#ifdef RT_USING_TC -int _tc_heap_realloc() -{ - heap_realloc_init(); - - return 0; -} -FINSH_FUNCTION_EXPORT(_tc_heap_realloc, a heap re-malloc test); -#else -int rt_application_init() -{ - heap_realloc_init(); - - return 0; -} -#endif +#include +#include "tc_comm.h" + +/* + * This is an example for heap malloc + */ + +static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) +{ + while (len) + { + if (*ptr != value) return RT_FALSE; + + ptr ++; + len --; + } + + return RT_TRUE; +} + +static void heap_realloc_init() +{ + rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; + + ptr1 = rt_malloc(1); + ptr2 = rt_malloc(13); + ptr3 = rt_malloc(31); + ptr4 = rt_malloc(127); + ptr5 = rt_malloc(0); + + memset(ptr1, 1, 1); + memset(ptr2, 2, 13); + memset(ptr3, 3, 31); + memset(ptr4, 4, 127); + + if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; + if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; + if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; + if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed; + + ptr1 = rt_realloc(ptr1, 13); + ptr2 = rt_realloc(ptr2, 31); + ptr3 = rt_realloc(ptr3, 127); + ptr4 = rt_realloc(ptr4, 1); + ptr5 = rt_realloc(ptr5, 0); + + if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; + if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; + if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; + if (mem_check(ptr4, 4, 1) != RT_FALSE) goto _failed; + + rt_free(ptr4); + rt_free(ptr3); + rt_free(ptr3); + rt_free(ptr1); + + if (ptr5 != RT_NULL) + { + rt_free(ptr5); + } + + tc_done(TC_STAT_PASSED); + +_failed: + tc_done(TC_STAT_FAILED); +} + +#ifdef RT_USING_TC +int _tc_heap_realloc() +{ + heap_realloc_init(); + + return 0; +} +FINSH_FUNCTION_EXPORT(_tc_heap_realloc, a heap re-malloc test); +#else +int rt_application_init() +{ + heap_realloc_init(); + + return 0; +} +#endif diff --git a/examples/kernel/mutex_simple.c b/examples/kernel/mutex_simple.c index c098018da0..8545ddc660 100644 --- a/examples/kernel/mutex_simple.c +++ b/examples/kernel/mutex_simple.c @@ -1,163 +1,163 @@ -/* - * 程序清单: - */ -#include -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -static rt_thread_t tid3 = RT_NULL; -static rt_mutex_t mutex = RT_NULL; - -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - /* 先让低优先级线程运行 */ - rt_thread_delay(10); - - /* 此时thread3持有mutex,并且thread2等待持有mutex */ - - /* 检查thread2与thread3的优先级情况 */ - if (tid2->current_priority != tid3->current_priority) - { - /* 优先级不相同,测试失败 */ - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return; - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - rt_err_t result; - - /* 先让低优先级线程运行 */ - rt_thread_delay(5); - - while (1) - { - /* - * 试图持有互斥锁,此时thread3持有,应把thread3的优先级提升到thread2相同 - * 的优先级 - */ - result = rt_mutex_take(mutex, RT_WAITING_FOREVER); - - if (result == RT_EOK) - { - /* 释放互斥锁 */ - rt_mutex_release(mutex); - } - } -} - -/* 线程3入口 */ -static void thread3_entry(void* parameter) -{ - rt_tick_t tick; - rt_err_t result; - - while (1) - { - result = rt_mutex_take(mutex, RT_WAITING_FOREVER); - result = rt_mutex_take(mutex, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - } - - /* 做一个长时间的循环,总共50个OS Tick */ - tick = rt_tick_get(); - while (rt_tick_get() - tick < 50) ; - - rt_mutex_release(mutex); - rt_mutex_release(mutex); - } -} - -int mutex_simple_init() -{ - /* 创建互斥锁 */ - mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); - if (mutex == RT_NULL) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程3 */ - tid3 = rt_thread_create("t3", - thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); - if (tid3 != RT_NULL) - rt_thread_startup(tid3); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid3); - - if (mutex != RT_NULL) - { - rt_mutex_delete(mutex); - } - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_mutex_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - mutex_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_mutex_simple, sime mutex example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - mutex_simple_init(); - - return 0; -} -#endif +/* + * 程序清单: + */ +#include +#include "tc_comm.h" + +/* 指向线程控制块的指针 */ +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +static rt_thread_t tid3 = RT_NULL; +static rt_mutex_t mutex = RT_NULL; + +/* 线程1入口 */ +static void thread1_entry(void* parameter) +{ + /* 先让低优先级线程运行 */ + rt_thread_delay(10); + + /* 此时thread3持有mutex,并且thread2等待持有mutex */ + + /* 检查thread2与thread3的优先级情况 */ + if (tid2->current_priority != tid3->current_priority) + { + /* 优先级不相同,测试失败 */ + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return; + } +} + +/* 线程2入口 */ +static void thread2_entry(void* parameter) +{ + rt_err_t result; + + /* 先让低优先级线程运行 */ + rt_thread_delay(5); + + while (1) + { + /* + * 试图持有互斥锁,此时thread3持有,应把thread3的优先级提升到thread2相同 + * 的优先级 + */ + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + + if (result == RT_EOK) + { + /* 释放互斥锁 */ + rt_mutex_release(mutex); + } + } +} + +/* 线程3入口 */ +static void thread3_entry(void* parameter) +{ + rt_tick_t tick; + rt_err_t result; + + while (1) + { + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + } + + /* 做一个长时间的循环,总共50个OS Tick */ + tick = rt_tick_get(); + while (rt_tick_get() - tick < 50) ; + + rt_mutex_release(mutex); + rt_mutex_release(mutex); + } +} + +int mutex_simple_init() +{ + /* 创建互斥锁 */ + mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); + if (mutex == RT_NULL) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + /* 创建线程1 */ + tid1 = rt_thread_create("t1", + thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程2 */ + tid2 = rt_thread_create("t2", + thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程3 */ + tid3 = rt_thread_create("t3", + thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); + if (tid3 != RT_NULL) + rt_thread_startup(tid3); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除线程 */ + if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid1); + if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid2); + if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid3); + + if (mutex != RT_NULL) + { + rt_mutex_delete(mutex); + } + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_mutex_simple() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + mutex_simple_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_mutex_simple, sime mutex example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + mutex_simple_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_buffer_worker.c b/examples/kernel/semaphore_buffer_worker.c index af5722547a..6e5920dd6f 100644 --- a/examples/kernel/semaphore_buffer_worker.c +++ b/examples/kernel/semaphore_buffer_worker.c @@ -1,267 +1,267 @@ -/* - * 程序清单:信号量实现生产者消费者间的互斥 - * - * 在这个程序中,会创建两个线程,一个是生成者线程worker一个是消费者线程thread - * - * 在数据信息生产、消费的过程中,worker负责把数据将写入到环形buffer中,而thread - * 则从环形buffer中读出。 - */ -#include -#include "tc_comm.h" - -/* 一个环形buffer的实现 */ -struct rb -{ - rt_uint16_t read_index, write_index; - rt_uint8_t *buffer_ptr; - rt_uint16_t buffer_size; -}; - -/* 指向信号量控制块的指针 */ -static rt_sem_t sem = RT_NULL; -/* 指向线程控制块的指针 */ -static rt_thread_t tid = RT_NULL, worker = RT_NULL; - -/* 环形buffer的内存块(用数组体现出来) */ -#define BUFFER_SIZE 256 -#define BUFFER_ITEM 32 -static rt_uint8_t working_buffer[BUFFER_SIZE]; -struct rb working_rb; - -/* 初始化环形buffer,size指的是buffer的大小。注:这里并没对数据地址对齐做处理 */ -static void rb_init(struct rb* rb, rt_uint8_t *pool, rt_uint16_t size) -{ - RT_ASSERT(rb != RT_NULL); - - /* 对读写指针清零*/ - rb->read_index = rb->write_index = 0; - - /* 设置环形buffer的内存数据块 */ - rb->buffer_ptr = pool; - rb->buffer_size = size; -} - -/* 向环形buffer中写入数据 */ -static rt_bool_t rb_put(struct rb* rb, const rt_uint8_t *ptr, rt_uint16_t length) -{ - rt_size_t size; - - /* 判断是否有足够的剩余空间 */ - if (rb->read_index > rb->write_index) - size = rb->read_index - rb->write_index; - else - size = rb->buffer_size - rb->write_index + rb->read_index; - - /* 没有多余的空间 */ - if (size < length) return RT_FALSE; - - if (rb->read_index > rb->write_index) - { - /* read_index - write_index 即为总的空余空间 */ - memcpy(&rb->buffer_ptr[rb->write_index], ptr, length); - rb->write_index += length; - } - else - { - if (rb->buffer_size - rb->write_index > length) - { - /* write_index 后面剩余的空间有足够的长度 */ - memcpy(&rb->buffer_ptr[rb->write_index], ptr, length); - rb->write_index += length; - } - else - { - /* - * write_index 后面剩余的空间不存在足够的长度,需要把部分数据复制到 - * 前面的剩余空间中 - */ - memcpy(&rb->buffer_ptr[rb->write_index], ptr, - rb->buffer_size - rb->write_index); - memcpy(&rb->buffer_ptr[0], &ptr[rb->buffer_size - rb->write_index], - length - (rb->buffer_size - rb->write_index)); - rb->write_index = length - (rb->buffer_size - rb->write_index); - } - } - - return RT_TRUE; -} - -/* 从环形buffer中读出数据 */ -static rt_bool_t rb_get(struct rb* rb, rt_uint8_t *ptr, rt_uint16_t length) -{ - rt_size_t size; - - /* 判断是否有足够的数据 */ - if (rb->read_index > rb->write_index) - size = rb->buffer_size - rb->read_index + rb->write_index; - else - size = rb->write_index - rb->read_index; - - /* 没有足够的数据 */ - if (size < length) return RT_FALSE; - - if (rb->read_index > rb->write_index) - { - if (rb->buffer_size - rb->read_index > length) - { - /* read_index的数据足够多,直接复制 */ - memcpy(ptr, &rb->buffer_ptr[rb->read_index], length); - rb->read_index += length; - } - else - { - /* read_index的数据不够,需要分段复制 */ - memcpy(ptr, &rb->buffer_ptr[rb->read_index], - rb->buffer_size - rb->read_index); - memcpy(&ptr[rb->buffer_size - rb->read_index], &rb->buffer_ptr[0], - length - rb->buffer_size + rb->read_index); - rb->read_index = length - rb->buffer_size + rb->read_index; - } - } - else - { - /* - * read_index要比write_index小,总的数据量够(前面已经有总数据量的判 - * 断),直接复制出数据。 - */ - memcpy(ptr, &rb->buffer_ptr[rb->read_index], length); - rb->read_index += length; - } - - return RT_TRUE; -} - -/* 生产者线程入口 */ -static void thread_entry(void* parameter) -{ - rt_bool_t result; - rt_uint8_t data_buffer[BUFFER_ITEM + 1]; - - while (1) - { - /* 持有信号量 */ - rt_sem_take(sem, RT_WAITING_FOREVER); - /* 从环buffer中获得数据 */ - result = rb_get(&working_rb, &data_buffer[0], BUFFER_ITEM); - /* 释放信号量 */ - rt_sem_release(sem); - data_buffer[BUFFER_ITEM] = '\0'; - - if (result == RT_TRUE) - { - /* 获取数据成功,打印数据 */ - rt_kprintf("%s\n", data_buffer); - } - - /* 做一个5 OS Tick的休眠 */ - rt_thread_delay(5); - } -} - -/* worker线程入口 */ -static void worker_entry(void* parameter) -{ - rt_bool_t result; - rt_uint32_t index, setchar; - rt_uint8_t data_buffer[BUFFER_ITEM]; - - setchar = 0x21; - while (1) - { - /* 构造数据 */ - for(index = 0; index < BUFFER_ITEM; index++) - { - data_buffer[index] = setchar; - if (++setchar == 0x7f) - setchar = 0x21; - } - - /* 持有信号量 */ - rt_sem_take(sem, RT_WAITING_FOREVER); - /* 把数据放到环形buffer中 */ - result = rb_put(&working_rb, &data_buffer[0], BUFFER_ITEM); - /* 释放信号量 */ - rt_sem_release(sem); - - /* 放入成功,做一个10 OS Tick的休眠 */ - rt_thread_delay(10); - } -} - -int semaphore_buffer_worker_init() -{ - /* 初始化ring buffer */ - rb_init(&working_rb, working_buffer, BUFFER_SIZE); - - /* 创建信号量 */ - sem = rt_sem_create("sem", 1, RT_IPC_FLAG_FIFO); - if (sem == RT_NULL) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - /* 创建线程1 */ - tid = rt_thread_create("thread", - thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - worker = rt_thread_create("worker", - worker_entry, RT_NULL, /* 线程入口是worker_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (worker != RT_NULL) - rt_thread_startup(worker); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除信号量 */ - if (sem != RT_NULL) - rt_sem_delete(sem); - - /* 删除线程 */ - if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid); - if (worker != RT_NULL && worker->stat != RT_THREAD_CLOSE) - rt_thread_delete(worker); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_semaphore_buffer_worker() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - semaphore_buffer_worker_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, a buffer worker with semaphore example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - semaphore_buffer_worker_init(); - - return 0; -} -#endif +/* + * 程序清单:信号量实现生产者消费者间的互斥 + * + * 在这个程序中,会创建两个线程,一个是生成者线程worker一个是消费者线程thread + * + * 在数据信息生产、消费的过程中,worker负责把数据将写入到环形buffer中,而thread + * 则从环形buffer中读出。 + */ +#include +#include "tc_comm.h" + +/* 一个环形buffer的实现 */ +struct rb +{ + rt_uint16_t read_index, write_index; + rt_uint8_t *buffer_ptr; + rt_uint16_t buffer_size; +}; + +/* 指向信号量控制块的指针 */ +static rt_sem_t sem = RT_NULL; +/* 指向线程控制块的指针 */ +static rt_thread_t tid = RT_NULL, worker = RT_NULL; + +/* 环形buffer的内存块(用数组体现出来) */ +#define BUFFER_SIZE 256 +#define BUFFER_ITEM 32 +static rt_uint8_t working_buffer[BUFFER_SIZE]; +struct rb working_rb; + +/* 初始化环形buffer,size指的是buffer的大小。注:这里并没对数据地址对齐做处理 */ +static void rb_init(struct rb* rb, rt_uint8_t *pool, rt_uint16_t size) +{ + RT_ASSERT(rb != RT_NULL); + + /* 对读写指针清零*/ + rb->read_index = rb->write_index = 0; + + /* 设置环形buffer的内存数据块 */ + rb->buffer_ptr = pool; + rb->buffer_size = size; +} + +/* 向环形buffer中写入数据 */ +static rt_bool_t rb_put(struct rb* rb, const rt_uint8_t *ptr, rt_uint16_t length) +{ + rt_size_t size; + + /* 判断是否有足够的剩余空间 */ + if (rb->read_index > rb->write_index) + size = rb->read_index - rb->write_index; + else + size = rb->buffer_size - rb->write_index + rb->read_index; + + /* 没有多余的空间 */ + if (size < length) return RT_FALSE; + + if (rb->read_index > rb->write_index) + { + /* read_index - write_index 即为总的空余空间 */ + memcpy(&rb->buffer_ptr[rb->write_index], ptr, length); + rb->write_index += length; + } + else + { + if (rb->buffer_size - rb->write_index > length) + { + /* write_index 后面剩余的空间有足够的长度 */ + memcpy(&rb->buffer_ptr[rb->write_index], ptr, length); + rb->write_index += length; + } + else + { + /* + * write_index 后面剩余的空间不存在足够的长度,需要把部分数据复制到 + * 前面的剩余空间中 + */ + memcpy(&rb->buffer_ptr[rb->write_index], ptr, + rb->buffer_size - rb->write_index); + memcpy(&rb->buffer_ptr[0], &ptr[rb->buffer_size - rb->write_index], + length - (rb->buffer_size - rb->write_index)); + rb->write_index = length - (rb->buffer_size - rb->write_index); + } + } + + return RT_TRUE; +} + +/* 从环形buffer中读出数据 */ +static rt_bool_t rb_get(struct rb* rb, rt_uint8_t *ptr, rt_uint16_t length) +{ + rt_size_t size; + + /* 判断是否有足够的数据 */ + if (rb->read_index > rb->write_index) + size = rb->buffer_size - rb->read_index + rb->write_index; + else + size = rb->write_index - rb->read_index; + + /* 没有足够的数据 */ + if (size < length) return RT_FALSE; + + if (rb->read_index > rb->write_index) + { + if (rb->buffer_size - rb->read_index > length) + { + /* read_index的数据足够多,直接复制 */ + memcpy(ptr, &rb->buffer_ptr[rb->read_index], length); + rb->read_index += length; + } + else + { + /* read_index的数据不够,需要分段复制 */ + memcpy(ptr, &rb->buffer_ptr[rb->read_index], + rb->buffer_size - rb->read_index); + memcpy(&ptr[rb->buffer_size - rb->read_index], &rb->buffer_ptr[0], + length - rb->buffer_size + rb->read_index); + rb->read_index = length - rb->buffer_size + rb->read_index; + } + } + else + { + /* + * read_index要比write_index小,总的数据量够(前面已经有总数据量的判 + * 断),直接复制出数据。 + */ + memcpy(ptr, &rb->buffer_ptr[rb->read_index], length); + rb->read_index += length; + } + + return RT_TRUE; +} + +/* 生产者线程入口 */ +static void thread_entry(void* parameter) +{ + rt_bool_t result; + rt_uint8_t data_buffer[BUFFER_ITEM + 1]; + + while (1) + { + /* 持有信号量 */ + rt_sem_take(sem, RT_WAITING_FOREVER); + /* 从环buffer中获得数据 */ + result = rb_get(&working_rb, &data_buffer[0], BUFFER_ITEM); + /* 释放信号量 */ + rt_sem_release(sem); + data_buffer[BUFFER_ITEM] = '\0'; + + if (result == RT_TRUE) + { + /* 获取数据成功,打印数据 */ + rt_kprintf("%s\n", data_buffer); + } + + /* 做一个5 OS Tick的休眠 */ + rt_thread_delay(5); + } +} + +/* worker线程入口 */ +static void worker_entry(void* parameter) +{ + rt_bool_t result; + rt_uint32_t index, setchar; + rt_uint8_t data_buffer[BUFFER_ITEM]; + + setchar = 0x21; + while (1) + { + /* 构造数据 */ + for(index = 0; index < BUFFER_ITEM; index++) + { + data_buffer[index] = setchar; + if (++setchar == 0x7f) + setchar = 0x21; + } + + /* 持有信号量 */ + rt_sem_take(sem, RT_WAITING_FOREVER); + /* 把数据放到环形buffer中 */ + result = rb_put(&working_rb, &data_buffer[0], BUFFER_ITEM); + /* 释放信号量 */ + rt_sem_release(sem); + + /* 放入成功,做一个10 OS Tick的休眠 */ + rt_thread_delay(10); + } +} + +int semaphore_buffer_worker_init() +{ + /* 初始化ring buffer */ + rb_init(&working_rb, working_buffer, BUFFER_SIZE); + + /* 创建信号量 */ + sem = rt_sem_create("sem", 1, RT_IPC_FLAG_FIFO); + if (sem == RT_NULL) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + /* 创建线程1 */ + tid = rt_thread_create("thread", + thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid != RT_NULL) + rt_thread_startup(tid); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程2 */ + worker = rt_thread_create("worker", + worker_entry, RT_NULL, /* 线程入口是worker_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (worker != RT_NULL) + rt_thread_startup(worker); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除信号量 */ + if (sem != RT_NULL) + rt_sem_delete(sem); + + /* 删除线程 */ + if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid); + if (worker != RT_NULL && worker->stat != RT_THREAD_CLOSE) + rt_thread_delete(worker); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_semaphore_buffer_worker() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + semaphore_buffer_worker_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, a buffer worker with semaphore example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + semaphore_buffer_worker_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_dynamic.c b/examples/kernel/semaphore_dynamic.c index bea4060e38..7f2c2ffd42 100644 --- a/examples/kernel/semaphore_dynamic.c +++ b/examples/kernel/semaphore_dynamic.c @@ -1,128 +1,128 @@ -/* - * 程序清单:动态信号量 - * - * 这个例子中将创建一个动态信号量(初始值为0 )及一个动态线程,在这个动态线程中 - * 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并 - * 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。 - */ -#include -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid = RT_NULL; -/* 指向信号量的指针 */ -static rt_sem_t sem = RT_NULL; -/* 线程入口 */ -static void thread_entry(void* parameter) -{ - rt_err_t result; - rt_tick_t tick; - - /* 获得当前的OS Tick */ - tick = rt_tick_get(); - - /* 试图持有一个信号量,如果10个OS Tick依然没拿到,则超时返回 */ - result = rt_sem_take(sem, 10); - if (result == -RT_ETIMEOUT) - { - /* 判断是否刚好过去10个OS Tick */ - if (rt_tick_get() - tick != 10) - { - /* 如果失败,则测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_delete(sem); - return; - } - rt_kprintf("take semaphore timeout\n"); - } - else - { - /* 因为并没释放信号量,应该是超时返回,否则测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_delete(sem); - return; - } - - /* 释放一次信号量 */ - rt_sem_release(sem); - - /* 继续持有信号量,并永远等待直到持有到信号量 */ - result = rt_sem_take(sem, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - /* 返回不正确,测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_delete(sem); - return; - } - - /* 测试成功 */ - tc_done(TC_STAT_PASSED); - /* 删除信号量 */ - rt_sem_delete(sem); -} - -int semaphore_dynamic_init() -{ - /* 创建一个信号量,初始值是0 */ - sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO); - if (sem == RT_NULL) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - /* 创建线程 */ - tid = rt_thread_create("thread", - thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) - { - rt_thread_delete(tid); - - /* 删除信号量 */ - rt_sem_delete(sem); - } - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_semaphore_dynamic() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - semaphore_dynamic_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - semaphore_dynamic_init(); - - return 0; -} -#endif +/* + * 程序清单:动态信号量 + * + * 这个例子中将创建一个动态信号量(初始值为0 )及一个动态线程,在这个动态线程中 + * 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并 + * 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。 + */ +#include +#include "tc_comm.h" + +/* 指向线程控制块的指针 */ +static rt_thread_t tid = RT_NULL; +/* 指向信号量的指针 */ +static rt_sem_t sem = RT_NULL; +/* 线程入口 */ +static void thread_entry(void* parameter) +{ + rt_err_t result; + rt_tick_t tick; + + /* 获得当前的OS Tick */ + tick = rt_tick_get(); + + /* 试图持有一个信号量,如果10个OS Tick依然没拿到,则超时返回 */ + result = rt_sem_take(sem, 10); + if (result == -RT_ETIMEOUT) + { + /* 判断是否刚好过去10个OS Tick */ + if (rt_tick_get() - tick != 10) + { + /* 如果失败,则测试失败 */ + tc_done(TC_STAT_FAILED); + rt_sem_delete(sem); + return; + } + rt_kprintf("take semaphore timeout\n"); + } + else + { + /* 因为并没释放信号量,应该是超时返回,否则测试失败 */ + tc_done(TC_STAT_FAILED); + rt_sem_delete(sem); + return; + } + + /* 释放一次信号量 */ + rt_sem_release(sem); + + /* 继续持有信号量,并永远等待直到持有到信号量 */ + result = rt_sem_take(sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + /* 返回不正确,测试失败 */ + tc_done(TC_STAT_FAILED); + rt_sem_delete(sem); + return; + } + + /* 测试成功 */ + tc_done(TC_STAT_PASSED); + /* 删除信号量 */ + rt_sem_delete(sem); +} + +int semaphore_dynamic_init() +{ + /* 创建一个信号量,初始值是0 */ + sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO); + if (sem == RT_NULL) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + /* 创建线程 */ + tid = rt_thread_create("thread", + thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid != RT_NULL) + rt_thread_startup(tid); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除线程 */ + if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) + { + rt_thread_delete(tid); + + /* 删除信号量 */ + rt_sem_delete(sem); + } + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_semaphore_dynamic() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + semaphore_dynamic_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + semaphore_dynamic_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_priority.c b/examples/kernel/semaphore_priority.c index 4ee8d889e3..c106a25d5e 100644 --- a/examples/kernel/semaphore_priority.c +++ b/examples/kernel/semaphore_priority.c @@ -1,128 +1,128 @@ -#include -#include "tc_comm.h" - -static rt_sem_t sem; -static rt_uint8_t t1_count, t2_count; -static rt_thread_t t1, t2, worker; -static void thread1_entry(void* parameter) -{ - rt_err_t result; - - while (1) - { - result = rt_sem_take(sem, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - tc_done(TC_STAT_FAILED); - return; - } - - t1_count ++; - rt_kprintf("thread1: got semaphore, count: %d\n", t1_count); - } -} - -static void thread2_entry(void* parameter) -{ - rt_err_t result; - - while (1) - { - result = rt_sem_take(sem, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - tc_done(TC_STAT_FAILED); - return; - } - - t2_count ++; - rt_kprintf("thread2: got semaphore, count: %d\n", t2_count); - } -} - -static void worker_thread_entry(void* parameter) -{ - rt_thread_delay(10); - - while (1) - { - rt_sem_release(sem); - rt_thread_delay(5); - } -} - -int semaphore_priority_init() -{ - sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO); - if (sem == RT_NULL) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - t1_count = t2_count = 0; - - t1 = rt_thread_create("t1", - thread1_entry, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); - if (t1 != RT_NULL) - rt_thread_startup(t1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - t2 = rt_thread_create("t2", - thread2_entry, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (t2 != RT_NULL) - rt_thread_startup(t2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - worker = rt_thread_create("worker", - worker_thread_entry, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (worker != RT_NULL) - rt_thread_startup(worker); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - - /* delete t1, t2 and worker thread */ - rt_thread_delete(t1); - rt_thread_delete(t2); - rt_thread_delete(worker); - - if (t1_count > t2_count) - tc_done(TC_STAT_FAILED); - else - tc_done(TC_STAT_PASSED); - - /* unlock scheduler */ - rt_exit_critical(); -} - -int _tc_semaphore_priority() -{ - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - semaphore_priority_init(); - - return 50; -} -FINSH_FUNCTION_EXPORT(_tc_semaphore_priority, a priority semaphore test); -#else -int rt_application_init() -{ - semaphore_priority_init(); - - return 0; -} -#endif +#include +#include "tc_comm.h" + +static rt_sem_t sem; +static rt_uint8_t t1_count, t2_count; +static rt_thread_t t1, t2, worker; +static void thread1_entry(void* parameter) +{ + rt_err_t result; + + while (1) + { + result = rt_sem_take(sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_done(TC_STAT_FAILED); + return; + } + + t1_count ++; + rt_kprintf("thread1: got semaphore, count: %d\n", t1_count); + } +} + +static void thread2_entry(void* parameter) +{ + rt_err_t result; + + while (1) + { + result = rt_sem_take(sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_done(TC_STAT_FAILED); + return; + } + + t2_count ++; + rt_kprintf("thread2: got semaphore, count: %d\n", t2_count); + } +} + +static void worker_thread_entry(void* parameter) +{ + rt_thread_delay(10); + + while (1) + { + rt_sem_release(sem); + rt_thread_delay(5); + } +} + +int semaphore_priority_init() +{ + sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO); + if (sem == RT_NULL) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + t1_count = t2_count = 0; + + t1 = rt_thread_create("t1", + thread1_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); + if (t1 != RT_NULL) + rt_thread_startup(t1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + t2 = rt_thread_create("t2", + thread2_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); + if (t2 != RT_NULL) + rt_thread_startup(t2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + worker = rt_thread_create("worker", + worker_thread_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (worker != RT_NULL) + rt_thread_startup(worker); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* lock scheduler */ + rt_enter_critical(); + + /* delete t1, t2 and worker thread */ + rt_thread_delete(t1); + rt_thread_delete(t2); + rt_thread_delete(worker); + + if (t1_count > t2_count) + tc_done(TC_STAT_FAILED); + else + tc_done(TC_STAT_PASSED); + + /* unlock scheduler */ + rt_exit_critical(); +} + +int _tc_semaphore_priority() +{ + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + semaphore_priority_init(); + + return 50; +} +FINSH_FUNCTION_EXPORT(_tc_semaphore_priority, a priority semaphore test); +#else +int rt_application_init() +{ + semaphore_priority_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_producer_consumer.c b/examples/kernel/semaphore_producer_consumer.c index f85acc3b70..ec0bf2234c 100644 --- a/examples/kernel/semaphore_producer_consumer.c +++ b/examples/kernel/semaphore_producer_consumer.c @@ -1,154 +1,154 @@ -/* - * 程序清单:生产者消费者例子 - * - * 这个例子中将创建两个线程用于实现生产者消费者问题 - */ -#include -#include "tc_comm.h" - -/* 定义最大5个元素能够被产生 */ -#define MAXSEM 5 - -/* 用于放置生产的整数数组 */ -rt_uint32_t array[MAXSEM]; -/* 指向生产者、消费者在array数组中的读写位置 */ -static rt_uint32_t set, get; - -/* 指向线程控制块的指针 */ -static rt_thread_t producer_tid = RT_NULL; -static rt_thread_t consumer_tid = RT_NULL; - -struct rt_semaphore sem_lock; -struct rt_semaphore sem_empty, sem_full; - -/* 生成者线程入口 */ -void producer_thread_entry(void* parameter) -{ - int cnt = 0; - - /* 运行100次 */ - while( cnt < 100) - { - /* 获取一个空位 */ - rt_sem_take(&sem_empty, RT_WAITING_FOREVER); - - /* 修改array内容,上锁 */ - rt_sem_take(&sem_lock, RT_WAITING_FOREVER); - array[set%MAXSEM] = cnt + 1; - rt_kprintf("the producer generates a number: %d\n", array[set%MAXSEM]); - set++; - rt_sem_release(&sem_lock); - - /* 发布一个满位 */ - rt_sem_release(&sem_full); - cnt++; - - /* 暂停一段时间 */ - rt_thread_delay(50); - } - - rt_kprintf("the producer exit!\n"); -} - -/* 消费者线程入口 */ -void consumer_thread_entry(void* parameter) -{ - rt_uint32_t no; - rt_uint32_t sum; - - /* 第n个线程,由入口参数传进来 */ - no = (rt_uint32_t)parameter; - - while(1) - { - /* 获取一个满位 */ - rt_sem_take(&sem_full, RT_WAITING_FOREVER); - - /* 临界区,上锁进行操作 */ - rt_sem_take(&sem_lock, RT_WAITING_FOREVER); - sum += array[get%MAXSEM]; - rt_kprintf("the consumer[%d] get a number: %d\n", no, array[get%MAXSEM] ); - get++; - rt_sem_release(&sem_lock); - - /* 释放一个空位 */ - rt_sem_release(&sem_empty); - - /* 生产者生产到100个数目,停止,消费者线程相应停止 */ - if (get == 100) break; - - /* 暂停一小会时间 */ - rt_thread_delay(10); - } - - rt_kprintf("the consumer[%d] sum is %d \n ", no, sum); - rt_kprintf("the consumer[%d] exit!\n"); -} - -int semaphore_producer_consumer_init() -{ - /* 初始化3个信号量 */ - rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_FIFO); - rt_sem_init(&sem_empty, "empty", MAXSEM, RT_IPC_FLAG_FIFO); - rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO); - - /* 创建线程1 */ - producer_tid = rt_thread_create("producer", - producer_thread_entry, RT_NULL, /* 线程入口是producer_thread_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (producer_tid != RT_NULL) - rt_thread_startup(producer_tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - consumer_tid = rt_thread_create("consumer", - consumer_thread_entry, RT_NULL, /* 线程入口是consumer_thread_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); - if (consumer_tid != RT_NULL) - rt_thread_startup(consumer_tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (producer_tid != RT_NULL && producer_tid->stat != RT_THREAD_CLOSE) - rt_thread_delete(producer_tid); - if (consumer_tid != RT_NULL && consumer_tid->stat != RT_THREAD_CLOSE) - rt_thread_delete(consumer_tid); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_semaphore_producer_consumer() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - semaphore_producer_consumer_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_semaphore_producer_consumer, producer and consumer example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - semaphore_producer_consumer_init(); - - return 0; -} -#endif +/* + * 程序清单:生产者消费者例子 + * + * 这个例子中将创建两个线程用于实现生产者消费者问题 + */ +#include +#include "tc_comm.h" + +/* 定义最大5个元素能够被产生 */ +#define MAXSEM 5 + +/* 用于放置生产的整数数组 */ +rt_uint32_t array[MAXSEM]; +/* 指向生产者、消费者在array数组中的读写位置 */ +static rt_uint32_t set, get; + +/* 指向线程控制块的指针 */ +static rt_thread_t producer_tid = RT_NULL; +static rt_thread_t consumer_tid = RT_NULL; + +struct rt_semaphore sem_lock; +struct rt_semaphore sem_empty, sem_full; + +/* 生成者线程入口 */ +void producer_thread_entry(void* parameter) +{ + int cnt = 0; + + /* 运行100次 */ + while( cnt < 100) + { + /* 获取一个空位 */ + rt_sem_take(&sem_empty, RT_WAITING_FOREVER); + + /* 修改array内容,上锁 */ + rt_sem_take(&sem_lock, RT_WAITING_FOREVER); + array[set%MAXSEM] = cnt + 1; + rt_kprintf("the producer generates a number: %d\n", array[set%MAXSEM]); + set++; + rt_sem_release(&sem_lock); + + /* 发布一个满位 */ + rt_sem_release(&sem_full); + cnt++; + + /* 暂停一段时间 */ + rt_thread_delay(50); + } + + rt_kprintf("the producer exit!\n"); +} + +/* 消费者线程入口 */ +void consumer_thread_entry(void* parameter) +{ + rt_uint32_t no; + rt_uint32_t sum; + + /* 第n个线程,由入口参数传进来 */ + no = (rt_uint32_t)parameter; + + while(1) + { + /* 获取一个满位 */ + rt_sem_take(&sem_full, RT_WAITING_FOREVER); + + /* 临界区,上锁进行操作 */ + rt_sem_take(&sem_lock, RT_WAITING_FOREVER); + sum += array[get%MAXSEM]; + rt_kprintf("the consumer[%d] get a number: %d\n", no, array[get%MAXSEM] ); + get++; + rt_sem_release(&sem_lock); + + /* 释放一个空位 */ + rt_sem_release(&sem_empty); + + /* 生产者生产到100个数目,停止,消费者线程相应停止 */ + if (get == 100) break; + + /* 暂停一小会时间 */ + rt_thread_delay(10); + } + + rt_kprintf("the consumer[%d] sum is %d \n ", no, sum); + rt_kprintf("the consumer[%d] exit!\n"); +} + +int semaphore_producer_consumer_init() +{ + /* 初始化3个信号量 */ + rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_FIFO); + rt_sem_init(&sem_empty, "empty", MAXSEM, RT_IPC_FLAG_FIFO); + rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO); + + /* 创建线程1 */ + producer_tid = rt_thread_create("producer", + producer_thread_entry, RT_NULL, /* 线程入口是producer_thread_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); + if (producer_tid != RT_NULL) + rt_thread_startup(producer_tid); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程2 */ + consumer_tid = rt_thread_create("consumer", + consumer_thread_entry, RT_NULL, /* 线程入口是consumer_thread_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); + if (consumer_tid != RT_NULL) + rt_thread_startup(consumer_tid); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除线程 */ + if (producer_tid != RT_NULL && producer_tid->stat != RT_THREAD_CLOSE) + rt_thread_delete(producer_tid); + if (consumer_tid != RT_NULL && consumer_tid->stat != RT_THREAD_CLOSE) + rt_thread_delete(consumer_tid); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_semaphore_producer_consumer() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + semaphore_producer_consumer_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_semaphore_producer_consumer, producer and consumer example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + semaphore_producer_consumer_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_static.c b/examples/kernel/semaphore_static.c index 717ff25c57..167b5e9055 100644 --- a/examples/kernel/semaphore_static.c +++ b/examples/kernel/semaphore_static.c @@ -1,132 +1,132 @@ -/* - * 程序清单:静态信号量 - * - * 这个例子中将创建一个静态信号量(初始值为0 )及一个静态线程,在这个静态线程中 - * 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并 - * 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。 - */ -#include -#include "tc_comm.h" - -/* 线程控制块及栈 */ -static struct rt_thread thread; -static rt_uint8_t thread_stack[THREAD_STACK_SIZE]; -/* 信号量控制块 */ -static struct rt_semaphore sem; - -/* 线程入口 */ -static void thread_entry(void* parameter) -{ - rt_err_t result; - rt_tick_t tick; - - /* 获得当前的OS Tick */ - tick = rt_tick_get(); - - /* 试图持有信号量,最大等待10个OS Tick后返回 */ - result = rt_sem_take(&sem, 10); - if (result == -RT_ETIMEOUT) - { - /* 超时后判断是否刚好是10个OS Tick */ - if (rt_tick_get() - tick != 10) - { - tc_done(TC_STAT_FAILED); - rt_sem_detach(&sem); - return; - } - rt_kprintf("take semaphore timeout\n"); - } - else - { - /* 因为没有其他地方是否信号量,所以不应该成功持有信号量,否则测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_detach(&sem); - return; - } - - /* 释放一次信号量 */ - rt_sem_release(&sem); - - /* 永久等待方式持有信号量 */ - result = rt_sem_take(&sem, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - /* 不成功则测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_detach(&sem); - return; - } - - /* 测试通过 */ - tc_done(TC_STAT_PASSED); - /* 脱离信号量对象 */ - rt_sem_detach(&sem); -} - -int semaphore_static_init() -{ - rt_err_t result; - - /* 初始化信号量,初始值是0 */ - result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO); - if (result != RT_EOK) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - /* 初始化线程1 */ - result = rt_thread_init(&thread, "thread", /* 线程名:thread */ - thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是RT_NULL*/ - &thread_stack[0], sizeof(thread_stack), /* 线程栈是thread_stack */ - THREAD_PRIORITY, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程1 */ - rt_thread_startup(&thread); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 执行线程脱离 */ - if (thread.stat != RT_THREAD_CLOSE) - { - rt_thread_detach(&thread); - - /* 执行信号量对象脱离 */ - rt_sem_detach(&sem); - } - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_semaphore_static() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - semaphore_static_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_static_init(); - - return 0; -} -#endif +/* + * 程序清单:静态信号量 + * + * 这个例子中将创建一个静态信号量(初始值为0 )及一个静态线程,在这个静态线程中 + * 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并 + * 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。 + */ +#include +#include "tc_comm.h" + +/* 线程控制块及栈 */ +static struct rt_thread thread; +static rt_uint8_t thread_stack[THREAD_STACK_SIZE]; +/* 信号量控制块 */ +static struct rt_semaphore sem; + +/* 线程入口 */ +static void thread_entry(void* parameter) +{ + rt_err_t result; + rt_tick_t tick; + + /* 获得当前的OS Tick */ + tick = rt_tick_get(); + + /* 试图持有信号量,最大等待10个OS Tick后返回 */ + result = rt_sem_take(&sem, 10); + if (result == -RT_ETIMEOUT) + { + /* 超时后判断是否刚好是10个OS Tick */ + if (rt_tick_get() - tick != 10) + { + tc_done(TC_STAT_FAILED); + rt_sem_detach(&sem); + return; + } + rt_kprintf("take semaphore timeout\n"); + } + else + { + /* 因为没有其他地方是否信号量,所以不应该成功持有信号量,否则测试失败 */ + tc_done(TC_STAT_FAILED); + rt_sem_detach(&sem); + return; + } + + /* 释放一次信号量 */ + rt_sem_release(&sem); + + /* 永久等待方式持有信号量 */ + result = rt_sem_take(&sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + /* 不成功则测试失败 */ + tc_done(TC_STAT_FAILED); + rt_sem_detach(&sem); + return; + } + + /* 测试通过 */ + tc_done(TC_STAT_PASSED); + /* 脱离信号量对象 */ + rt_sem_detach(&sem); +} + +int semaphore_static_init() +{ + rt_err_t result; + + /* 初始化信号量,初始值是0 */ + result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO); + if (result != RT_EOK) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + /* 初始化线程1 */ + result = rt_thread_init(&thread, "thread", /* 线程名:thread */ + thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是RT_NULL*/ + &thread_stack[0], sizeof(thread_stack), /* 线程栈是thread_stack */ + THREAD_PRIORITY, 10); + if (result == RT_EOK) /* 如果返回正确,启动线程1 */ + rt_thread_startup(&thread); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 执行线程脱离 */ + if (thread.stat != RT_THREAD_CLOSE) + { + rt_thread_detach(&thread); + + /* 执行信号量对象脱离 */ + rt_sem_detach(&sem); + } + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_semaphore_static() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + semaphore_static_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + thread_static_init(); + + return 0; +} +#endif diff --git a/examples/kernel/tc_comm.c b/examples/kernel/tc_comm.c index 1ec48f5398..60d843171f 100644 --- a/examples/kernel/tc_comm.c +++ b/examples/kernel/tc_comm.c @@ -1,176 +1,176 @@ -#include "tc_comm.h" -#ifdef RT_USING_FINSH -#include -#endif - -#ifdef RT_USING_TC -#define TC_PRIORITY 25 -#define TC_STACK_SIZE 0x400 - -static rt_uint8_t _tc_stat; -static struct rt_semaphore _tc_sem; -static struct rt_thread _tc_thread; -static rt_uint8_t _tc_stack[TC_STACK_SIZE]; -static char _tc_prefix[64]; -static const char* _tc_current; -static void (*_tc_cleanup)(void) = RT_NULL; - -static rt_uint32_t _tc_scale = 1; -FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale) - -void tc_thread_entry(void* parameter) -{ - struct finsh_syscall* index; - - /* create tc semaphore */ - rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO); - - while (_tc_stat & TC_STAT_RUNNING) - { - for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index)) - { - /* search testcase */ - if (rt_strstr(index->name, _tc_prefix) == index->name) - { - long tick; - - _tc_current = index->name + 4; - rt_kprintf("Run TestCase: %s\n", _tc_current); - _tc_stat = TC_STAT_PASSED | TC_STAT_RUNNING; - tick = index->func(); - if (tick > 0) - { - rt_sem_take(&_tc_sem, tick * _tc_scale); - - if (_tc_cleanup != RT_NULL) - { - /* perform testcase cleanup */ - _tc_cleanup(); - _tc_cleanup = RT_NULL; - } - - rt_sem_trytake(&_tc_sem);/* by nl1031 */ - - if (_tc_stat & TC_STAT_FAILED) - rt_kprintf("TestCase[%s] failed\n", _tc_current); - else - rt_kprintf("TestCase[%s] passed\n", _tc_current); - } - else - { - if (_tc_cleanup != RT_NULL) - { - /* perform testcase cleanup */ - _tc_cleanup(); - _tc_cleanup = RT_NULL; - } - } - } - } - } - - rt_kprintf("RT-Thread TestCase Running Done!\n"); - /* detach tc semaphore */ - rt_sem_detach(&_tc_sem); -} - -void tc_stop() -{ - _tc_stat &= ~TC_STAT_RUNNING; - - rt_thread_delay(RT_TICK_PER_SECOND/2); - if (_tc_thread.stat != RT_THREAD_INIT) - { - /* lock scheduler */ - rt_enter_critical(); - - /* detach old tc thread */ - rt_thread_detach(&_tc_thread); - rt_sem_detach(&_tc_sem); - - /* unlock scheduler */ - rt_exit_critical(); - } - rt_thread_delay(RT_TICK_PER_SECOND/2); -} -FINSH_FUNCTION_EXPORT(tc_stop, stop testcase thread); - -void tc_done(rt_uint8_t stat) -{ - _tc_stat |= stat; - _tc_stat &= ~TC_STAT_RUNNING; - - /* release semaphore */ - rt_sem_release(&_tc_sem); -} - -void tc_stat(rt_uint8_t stat) -{ - if (stat & TC_STAT_FAILED) - { - rt_kprintf("TestCases[%s] failed\n", _tc_current); - } - _tc_stat |= stat; -} - -void tc_cleanup(void (*cleanup)()) -{ - _tc_cleanup = cleanup; -} - -void tc_start(const char* tc_prefix) -{ - rt_err_t result; - - /* tesecase prefix is null */ - if (tc_prefix == RT_NULL) - { - rt_kprintf("TestCase Usage: tc_start(prefix)\n\n"); - rt_kprintf("list_tc() can list all testcases.\n"); - return ; - } - - /* init tc thread */ - if (_tc_stat & TC_STAT_RUNNING) - { - /* stop old tc thread */ - tc_stop(); - } - - rt_memset(_tc_prefix, 0, sizeof(_tc_prefix)); - rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix); - - result = rt_thread_init(&_tc_thread, "tc", - tc_thread_entry, RT_NULL, - &_tc_stack[0], sizeof(_tc_stack), - TC_PRIORITY - 3, 5); - - /* set tc stat */ - _tc_stat = TC_STAT_RUNNING | TC_STAT_FAILED; - - if (result == RT_EOK) - rt_thread_startup(&_tc_thread); -} -FINSH_FUNCTION_EXPORT(tc_start, start testcase with testcase prefix or name); - -void list_tc() -{ - struct finsh_syscall* index; - - rt_kprintf("TestCases List:\n"); - for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index)) - { - /* search testcase */ - if (rt_strstr(index->name, "_tc_") == index->name) - { -#ifdef FINSH_USING_DESCRIPTION - rt_kprintf("%-16s -- %s\n", index->name + 4, index->desc); -#else - rt_kprintf("%s\n", index->name + 4); -#endif - } - } -} -FINSH_FUNCTION_EXPORT(list_tc, list all testcases); -#endif - +#include "tc_comm.h" +#ifdef RT_USING_FINSH +#include +#endif + +#ifdef RT_USING_TC +#define TC_PRIORITY 25 +#define TC_STACK_SIZE 0x400 + +static rt_uint8_t _tc_stat; +static struct rt_semaphore _tc_sem; +static struct rt_thread _tc_thread; +static rt_uint8_t _tc_stack[TC_STACK_SIZE]; +static char _tc_prefix[64]; +static const char* _tc_current; +static void (*_tc_cleanup)(void) = RT_NULL; + +static rt_uint32_t _tc_scale = 1; +FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale) + +void tc_thread_entry(void* parameter) +{ + struct finsh_syscall* index; + + /* create tc semaphore */ + rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO); + + while (_tc_stat & TC_STAT_RUNNING) + { + for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index)) + { + /* search testcase */ + if (rt_strstr(index->name, _tc_prefix) == index->name) + { + long tick; + + _tc_current = index->name + 4; + rt_kprintf("Run TestCase: %s\n", _tc_current); + _tc_stat = TC_STAT_PASSED | TC_STAT_RUNNING; + tick = index->func(); + if (tick > 0) + { + rt_sem_take(&_tc_sem, tick * _tc_scale); + + if (_tc_cleanup != RT_NULL) + { + /* perform testcase cleanup */ + _tc_cleanup(); + _tc_cleanup = RT_NULL; + } + + rt_sem_trytake(&_tc_sem);/* by nl1031 */ + + if (_tc_stat & TC_STAT_FAILED) + rt_kprintf("TestCase[%s] failed\n", _tc_current); + else + rt_kprintf("TestCase[%s] passed\n", _tc_current); + } + else + { + if (_tc_cleanup != RT_NULL) + { + /* perform testcase cleanup */ + _tc_cleanup(); + _tc_cleanup = RT_NULL; + } + } + } + } + } + + rt_kprintf("RT-Thread TestCase Running Done!\n"); + /* detach tc semaphore */ + rt_sem_detach(&_tc_sem); +} + +void tc_stop() +{ + _tc_stat &= ~TC_STAT_RUNNING; + + rt_thread_delay(RT_TICK_PER_SECOND/2); + if (_tc_thread.stat != RT_THREAD_INIT) + { + /* lock scheduler */ + rt_enter_critical(); + + /* detach old tc thread */ + rt_thread_detach(&_tc_thread); + rt_sem_detach(&_tc_sem); + + /* unlock scheduler */ + rt_exit_critical(); + } + rt_thread_delay(RT_TICK_PER_SECOND/2); +} +FINSH_FUNCTION_EXPORT(tc_stop, stop testcase thread); + +void tc_done(rt_uint8_t stat) +{ + _tc_stat |= stat; + _tc_stat &= ~TC_STAT_RUNNING; + + /* release semaphore */ + rt_sem_release(&_tc_sem); +} + +void tc_stat(rt_uint8_t stat) +{ + if (stat & TC_STAT_FAILED) + { + rt_kprintf("TestCases[%s] failed\n", _tc_current); + } + _tc_stat |= stat; +} + +void tc_cleanup(void (*cleanup)()) +{ + _tc_cleanup = cleanup; +} + +void tc_start(const char* tc_prefix) +{ + rt_err_t result; + + /* tesecase prefix is null */ + if (tc_prefix == RT_NULL) + { + rt_kprintf("TestCase Usage: tc_start(prefix)\n\n"); + rt_kprintf("list_tc() can list all testcases.\n"); + return ; + } + + /* init tc thread */ + if (_tc_stat & TC_STAT_RUNNING) + { + /* stop old tc thread */ + tc_stop(); + } + + rt_memset(_tc_prefix, 0, sizeof(_tc_prefix)); + rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix); + + result = rt_thread_init(&_tc_thread, "tc", + tc_thread_entry, RT_NULL, + &_tc_stack[0], sizeof(_tc_stack), + TC_PRIORITY - 3, 5); + + /* set tc stat */ + _tc_stat = TC_STAT_RUNNING | TC_STAT_FAILED; + + if (result == RT_EOK) + rt_thread_startup(&_tc_thread); +} +FINSH_FUNCTION_EXPORT(tc_start, start testcase with testcase prefix or name); + +void list_tc() +{ + struct finsh_syscall* index; + + rt_kprintf("TestCases List:\n"); + for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index)) + { + /* search testcase */ + if (rt_strstr(index->name, "_tc_") == index->name) + { +#ifdef FINSH_USING_DESCRIPTION + rt_kprintf("%-16s -- %s\n", index->name + 4, index->desc); +#else + rt_kprintf("%s\n", index->name + 4); +#endif + } + } +} +FINSH_FUNCTION_EXPORT(list_tc, list all testcases); +#endif + diff --git a/examples/kernel/tc_comm.h b/examples/kernel/tc_comm.h index 9333b96815..7146097684 100644 --- a/examples/kernel/tc_comm.h +++ b/examples/kernel/tc_comm.h @@ -1,43 +1,43 @@ -#ifndef __TC_COMM_H__ -#define __TC_COMM_H__ - -/* - * RT-Thread TestCase - * - */ -#include -#ifdef RT_USING_FINSH -#include -#endif - -#if RT_THREAD_PRIORITY_MAX == 8 -#define THREAD_PRIORITY 6 -#elif RT_THREAD_PRIORITY_MAX == 32 -#define THREAD_PRIORITY 25 -#elif RT_THREAD_PRIORITY_MAX == 256 -#define THREAD_PRIORITY 200 -#endif -#define THREAD_STACK_SIZE 512 -#define THREAD_TIMESLICE 5 - -#define TC_STAT_END 0x00 -#define TC_STAT_RUNNING 0x01 -#define TC_STAT_FAILED 0x10 -#define TC_STAT_PASSED 0x00 - -#ifdef RT_USING_TC -void tc_start(const char* tc_prefix); -void tc_stop(void); -void tc_done(rt_uint8_t state); -void tc_stat(rt_uint8_t state); -void tc_cleanup(void (*cleanup)(void)); -#else -#define tc_start(x) -#define tc_stop() -#define tc_done(s) -#define tc_stat(s) -#define tc_cleanup(c) -#endif - -#endif - +#ifndef __TC_COMM_H__ +#define __TC_COMM_H__ + +/* + * RT-Thread TestCase + * + */ +#include +#ifdef RT_USING_FINSH +#include +#endif + +#if RT_THREAD_PRIORITY_MAX == 8 +#define THREAD_PRIORITY 6 +#elif RT_THREAD_PRIORITY_MAX == 32 +#define THREAD_PRIORITY 25 +#elif RT_THREAD_PRIORITY_MAX == 256 +#define THREAD_PRIORITY 200 +#endif +#define THREAD_STACK_SIZE 512 +#define THREAD_TIMESLICE 5 + +#define TC_STAT_END 0x00 +#define TC_STAT_RUNNING 0x01 +#define TC_STAT_FAILED 0x10 +#define TC_STAT_PASSED 0x00 + +#ifdef RT_USING_TC +void tc_start(const char* tc_prefix); +void tc_stop(void); +void tc_done(rt_uint8_t state); +void tc_stat(rt_uint8_t state); +void tc_cleanup(void (*cleanup)(void)); +#else +#define tc_start(x) +#define tc_stop() +#define tc_done(s) +#define tc_stat(s) +#define tc_cleanup(c) +#endif + +#endif + diff --git a/examples/kernel/thread_delay.c b/examples/kernel/thread_delay.c index 28b579487a..23d25d6d5c 100644 --- a/examples/kernel/thread_delay.c +++ b/examples/kernel/thread_delay.c @@ -1,70 +1,70 @@ -#include -#include "tc_comm.h" - -/* - * This is an example for delay thread - */ -static struct rt_thread thread; -static char thread_stack[THREAD_STACK_SIZE]; -static void thread_entry(void* parameter) -{ - rt_tick_t tick; - rt_kprintf("thread inited ok\n"); - - rt_kprintf("thread delay 10 tick\n"); - tick = rt_tick_get(); - rt_thread_delay(10); - if (rt_tick_get() - tick > 10) - { - tc_done(TC_STAT_FAILED); - return; - } - - rt_kprintf("thread delay 15 tick\n"); - tick = rt_tick_get(); - rt_thread_delay(15); - if (rt_tick_get() - tick > 15) - { - tc_done(TC_STAT_FAILED); - return; - } - - rt_kprintf("thread exit\n"); - - tc_done(TC_STAT_PASSED); -} - -rt_err_t thread_delay_init() -{ - rt_err_t result; - - result = rt_thread_init(&thread, - "test", - thread_entry, RT_NULL, - &thread_stack[0], sizeof(thread_stack), - THREAD_PRIORITY, 10); - - if (result == RT_EOK) - rt_thread_startup(&thread); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return result; -} - -#ifdef RT_USING_TC -int _tc_thread_delay() -{ - thread_delay_init(); - - return 30; -} -FINSH_FUNCTION_EXPORT(_tc_thread_delay, a thread delay test); -#else -int rt_application_init() -{ - thread_delay_init(); - - return 0; -} -#endif +#include +#include "tc_comm.h" + +/* + * This is an example for delay thread + */ +static struct rt_thread thread; +static char thread_stack[THREAD_STACK_SIZE]; +static void thread_entry(void* parameter) +{ + rt_tick_t tick; + rt_kprintf("thread inited ok\n"); + + rt_kprintf("thread delay 10 tick\n"); + tick = rt_tick_get(); + rt_thread_delay(10); + if (rt_tick_get() - tick > 10) + { + tc_done(TC_STAT_FAILED); + return; + } + + rt_kprintf("thread delay 15 tick\n"); + tick = rt_tick_get(); + rt_thread_delay(15); + if (rt_tick_get() - tick > 15) + { + tc_done(TC_STAT_FAILED); + return; + } + + rt_kprintf("thread exit\n"); + + tc_done(TC_STAT_PASSED); +} + +rt_err_t thread_delay_init() +{ + rt_err_t result; + + result = rt_thread_init(&thread, + "test", + thread_entry, RT_NULL, + &thread_stack[0], sizeof(thread_stack), + THREAD_PRIORITY, 10); + + if (result == RT_EOK) + rt_thread_startup(&thread); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return result; +} + +#ifdef RT_USING_TC +int _tc_thread_delay() +{ + thread_delay_init(); + + return 30; +} +FINSH_FUNCTION_EXPORT(_tc_thread_delay, a thread delay test); +#else +int rt_application_init() +{ + thread_delay_init(); + + return 0; +} +#endif diff --git a/examples/kernel/thread_delete.c b/examples/kernel/thread_delete.c index 4c8336ca5d..6bae53994e 100644 --- a/examples/kernel/thread_delete.c +++ b/examples/kernel/thread_delete.c @@ -1,144 +1,144 @@ -/* - * 程序清单:删除线程 - * - * 这个例子会创建两个线程,在一个线程中删除另外一个线程。 - */ -#include -#include "tc_comm.h" - -/* - * 线程删除(rt_thread_delete)函数仅适合于动态线程,为了在一个线程 - * 中访问另一个线程的控制块,所以把线程块指针声明成全局类型以供全 - * 局访问 - */ -static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL; -/* 线程1的入口函数 */ -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 线程1采用低优先级运行,一直打印计数值 */ - // rt_kprintf("thread count: %d\n", count ++); - count ++; - } -} -static void thread1_cleanup(struct rt_thread *tid) -{ - if (tid != tid1) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return ; - } - rt_kprintf("thread1 end\n"); - tid1 = RT_NULL; -} - -/* 线程2的入口函数 */ -static void thread2_entry(void* parameter) -{ - /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */ - - /* 线程2启动后先睡眠10个OS Tick */ - rt_thread_delay(10); - - /* - * 线程2唤醒后直接删除线程1,删除线程1后,线程1自动脱离就绪线程 - * 队列 - */ - rt_thread_delete(tid1); - - /* - * 线程2继续休眠10个OS Tick然后退出,线程2休眠后应切换到idle线程 - * idle线程将执行真正的线程1控制块和线程栈的删除 - */ - rt_thread_delay(10); -} - -static void thread2_cleanup(struct rt_thread *tid) -{ - /* - * 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线 - * 程中释放) - */ - - if (tid != tid2) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return ; - } - rt_kprintf("thread2 end\n"); - tid2 = RT_NULL; - tc_done(TC_STAT_PASSED); -} - -/* 线程删除示例的初始化 */ -int thread_delete_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */ - thread1_entry, RT_NULL, /* 入口是thread1_entry,参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */ - { - tid1->cleanup = thread1_cleanup; - rt_thread_startup(tid1); - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程1 */ - tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */ - thread2_entry, RT_NULL, /* 入口是thread2_entry,参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */ - { - tid2->cleanup = thread2_cleanup; - rt_thread_startup(tid2); - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - - /* delete thread */ - if (tid1 != RT_NULL) - { - rt_kprintf("tid1 is bad\n"); - tc_stat(TC_STAT_FAILED); - } - if (tid2 != RT_NULL) - { - rt_kprintf("tid2 is bad\n"); - tc_stat(TC_STAT_FAILED); - } - - /* unlock scheduler */ - rt_exit_critical(); -} - -int _tc_thread_delete() -{ - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - thread_delete_init(); - - return 27; -} -FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example); -#else -int rt_application_init() -{ - thread_delete_init(); - - return 0; -} -#endif +/* + * 程序清单:删除线程 + * + * 这个例子会创建两个线程,在一个线程中删除另外一个线程。 + */ +#include +#include "tc_comm.h" + +/* + * 线程删除(rt_thread_delete)函数仅适合于动态线程,为了在一个线程 + * 中访问另一个线程的控制块,所以把线程块指针声明成全局类型以供全 + * 局访问 + */ +static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL; +/* 线程1的入口函数 */ +static void thread1_entry(void* parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + /* 线程1采用低优先级运行,一直打印计数值 */ + // rt_kprintf("thread count: %d\n", count ++); + count ++; + } +} +static void thread1_cleanup(struct rt_thread *tid) +{ + if (tid != tid1) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return ; + } + rt_kprintf("thread1 end\n"); + tid1 = RT_NULL; +} + +/* 线程2的入口函数 */ +static void thread2_entry(void* parameter) +{ + /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */ + + /* 线程2启动后先睡眠10个OS Tick */ + rt_thread_delay(10); + + /* + * 线程2唤醒后直接删除线程1,删除线程1后,线程1自动脱离就绪线程 + * 队列 + */ + rt_thread_delete(tid1); + + /* + * 线程2继续休眠10个OS Tick然后退出,线程2休眠后应切换到idle线程 + * idle线程将执行真正的线程1控制块和线程栈的删除 + */ + rt_thread_delay(10); +} + +static void thread2_cleanup(struct rt_thread *tid) +{ + /* + * 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线 + * 程中释放) + */ + + if (tid != tid2) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return ; + } + rt_kprintf("thread2 end\n"); + tid2 = RT_NULL; + tc_done(TC_STAT_PASSED); +} + +/* 线程删除示例的初始化 */ +int thread_delete_init() +{ + /* 创建线程1 */ + tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */ + thread1_entry, RT_NULL, /* 入口是thread1_entry,参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */ + { + tid1->cleanup = thread1_cleanup; + rt_thread_startup(tid1); + } + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程1 */ + tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */ + thread2_entry, RT_NULL, /* 入口是thread2_entry,参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); + if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */ + { + tid2->cleanup = thread2_cleanup; + rt_thread_startup(tid2); + } + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* lock scheduler */ + rt_enter_critical(); + + /* delete thread */ + if (tid1 != RT_NULL) + { + rt_kprintf("tid1 is bad\n"); + tc_stat(TC_STAT_FAILED); + } + if (tid2 != RT_NULL) + { + rt_kprintf("tid2 is bad\n"); + tc_stat(TC_STAT_FAILED); + } + + /* unlock scheduler */ + rt_exit_critical(); +} + +int _tc_thread_delete() +{ + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + thread_delete_init(); + + return 27; +} +FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example); +#else +int rt_application_init() +{ + thread_delete_init(); + + return 0; +} +#endif diff --git a/examples/kernel/thread_detach.c b/examples/kernel/thread_detach.c index 84c85977fb..af1824ae30 100644 --- a/examples/kernel/thread_detach.c +++ b/examples/kernel/thread_detach.c @@ -1,118 +1,118 @@ -/* - * 程序清单:线程脱离 - * - * 这个例子会创建两个线程,在其中一个线程中执行对另一个线程的脱离。 - */ -#include -#include "tc_comm.h" - -/* 线程1控制块 */ -static struct rt_thread thread1; -/* 线程1栈 */ -static rt_uint8_t thread1_stack[THREAD_STACK_SIZE]; -/* 线程2控制块 */ -static struct rt_thread thread2; -/* 线程2栈 */ -static rt_uint8_t thread2_stack[THREAD_STACK_SIZE]; - -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 线程1采用低优先级运行,一直打印计数值 */ - rt_kprintf("thread count: %d\n", count ++); - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */ - - /* 线程2启动后先睡眠10个OS Tick */ - rt_thread_delay(10); - - /* - * 线程2唤醒后直接执行线程1脱离,线程1将从就绪线程队列中删除 - */ - rt_thread_detach(&thread1); - - /* - * 线程2继续休眠10个OS Tick然后退出 - */ - rt_thread_delay(10); - - /* - * 线程2运行结束后也将自动被从就绪队列中删除,并脱离线程队列 - */ -} - -int thread_detach_init() -{ - rt_err_t result; - - /* 初始化线程1 */ - result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */ - thread1_entry, RT_NULL, /* 线程的入口是thread1_entry,入口参数是RT_NULL*/ - &thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */ - THREAD_PRIORITY, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程1 */ - rt_thread_startup(&thread1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 初始化线程2 */ - result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */ - thread2_entry, RT_NULL, /* 线程的入口是thread2_entry,入口参数是RT_NULL*/ - &thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */ - THREAD_PRIORITY - 1, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程2 */ - rt_thread_startup(&thread2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 执行线程脱离 */ - if (thread1.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread1); - if (thread2.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_detach() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_detach_init(); - - /* 返回TestCase运行的最长时间 */ - return 25; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_detach, a static thread example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_detach_init(); - - return 0; -} -#endif +/* + * 程序清单:线程脱离 + * + * 这个例子会创建两个线程,在其中一个线程中执行对另一个线程的脱离。 + */ +#include +#include "tc_comm.h" + +/* 线程1控制块 */ +static struct rt_thread thread1; +/* 线程1栈 */ +static rt_uint8_t thread1_stack[THREAD_STACK_SIZE]; +/* 线程2控制块 */ +static struct rt_thread thread2; +/* 线程2栈 */ +static rt_uint8_t thread2_stack[THREAD_STACK_SIZE]; + +/* 线程1入口 */ +static void thread1_entry(void* parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + /* 线程1采用低优先级运行,一直打印计数值 */ + rt_kprintf("thread count: %d\n", count ++); + } +} + +/* 线程2入口 */ +static void thread2_entry(void* parameter) +{ + /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */ + + /* 线程2启动后先睡眠10个OS Tick */ + rt_thread_delay(10); + + /* + * 线程2唤醒后直接执行线程1脱离,线程1将从就绪线程队列中删除 + */ + rt_thread_detach(&thread1); + + /* + * 线程2继续休眠10个OS Tick然后退出 + */ + rt_thread_delay(10); + + /* + * 线程2运行结束后也将自动被从就绪队列中删除,并脱离线程队列 + */ +} + +int thread_detach_init() +{ + rt_err_t result; + + /* 初始化线程1 */ + result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */ + thread1_entry, RT_NULL, /* 线程的入口是thread1_entry,入口参数是RT_NULL*/ + &thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */ + THREAD_PRIORITY, 10); + if (result == RT_EOK) /* 如果返回正确,启动线程1 */ + rt_thread_startup(&thread1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 初始化线程2 */ + result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */ + thread2_entry, RT_NULL, /* 线程的入口是thread2_entry,入口参数是RT_NULL*/ + &thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */ + THREAD_PRIORITY - 1, 10); + if (result == RT_EOK) /* 如果返回正确,启动线程2 */ + rt_thread_startup(&thread2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 执行线程脱离 */ + if (thread1.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread1); + if (thread2.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread2); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_thread_detach() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + thread_detach_init(); + + /* 返回TestCase运行的最长时间 */ + return 25; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_thread_detach, a static thread example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + thread_detach_init(); + + return 0; +} +#endif diff --git a/examples/kernel/thread_dynamic.c b/examples/kernel/thread_dynamic.c index 9d1218be5d..960a40de9d 100644 --- a/examples/kernel/thread_dynamic.c +++ b/examples/kernel/thread_dynamic.c @@ -1,44 +1,44 @@ -#include -#include "tc_comm.h" - -static void thread_entry(void* parameter) -{ - rt_kprintf("thread dynamicly created ok\n"); - rt_thread_delay(10); - rt_kprintf("thread exit\n"); - - tc_done(TC_STAT_PASSED); -} - -int thread_dynamic_init() -{ - rt_thread_t tid; - - tid = rt_thread_create("test", - thread_entry, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -int _tc_thread_dynamic() -{ - thread_dynamic_init(); - - return 20; -} -FINSH_FUNCTION_EXPORT(_tc_thread_dynamic, a dynamic thread test); -#else -int rt_application_init() -{ - thread_dynamic_init(); - - return 0; -} -#endif - +#include +#include "tc_comm.h" + +static void thread_entry(void* parameter) +{ + rt_kprintf("thread dynamicly created ok\n"); + rt_thread_delay(10); + rt_kprintf("thread exit\n"); + + tc_done(TC_STAT_PASSED); +} + +int thread_dynamic_init() +{ + rt_thread_t tid; + + tid = rt_thread_create("test", + thread_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid != RT_NULL) + rt_thread_startup(tid); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +int _tc_thread_dynamic() +{ + thread_dynamic_init(); + + return 20; +} +FINSH_FUNCTION_EXPORT(_tc_thread_dynamic, a dynamic thread test); +#else +int rt_application_init() +{ + thread_dynamic_init(); + + return 0; +} +#endif + diff --git a/examples/kernel/thread_dynamic_simple.c b/examples/kernel/thread_dynamic_simple.c index c8a4b905aa..9d7612bddc 100644 --- a/examples/kernel/thread_dynamic_simple.c +++ b/examples/kernel/thread_dynamic_simple.c @@ -1,89 +1,89 @@ -/* - * 程序清单:动态线程 - * - * 这个程序会初始化2个动态线程,它们拥有共同的入口函数,但参数不相同 - */ -#include -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -/* 线程入口 */ -static void thread_entry(void* parameter) -{ - rt_uint32_t count = 0; - rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */ - - while (1) - { - /* 打印线程计数值输出 */ - rt_kprintf("thread%d count: %d\n", no, count ++); - - /* 休眠10个OS Tick */ - rt_thread_delay(10); - } -} - -int thread_dynamic_simple_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread_entry, (void*)1, /* 线程入口是thread_entry, 入口参数是1 */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread_entry, (void*)2, /* 线程入口是thread_entry, 入口参数是2 */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_dynamic_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_dynamic_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_dynamic_simple, a dynamic thread example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_dynamic_simple_init(); - - return 0; -} -#endif +/* + * 程序清单:动态线程 + * + * 这个程序会初始化2个动态线程,它们拥有共同的入口函数,但参数不相同 + */ +#include +#include "tc_comm.h" + +/* 指向线程控制块的指针 */ +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +/* 线程入口 */ +static void thread_entry(void* parameter) +{ + rt_uint32_t count = 0; + rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */ + + while (1) + { + /* 打印线程计数值输出 */ + rt_kprintf("thread%d count: %d\n", no, count ++); + + /* 休眠10个OS Tick */ + rt_thread_delay(10); + } +} + +int thread_dynamic_simple_init() +{ + /* 创建线程1 */ + tid1 = rt_thread_create("t1", + thread_entry, (void*)1, /* 线程入口是thread_entry, 入口参数是1 */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程2 */ + tid2 = rt_thread_create("t2", + thread_entry, (void*)2, /* 线程入口是thread_entry, 入口参数是2 */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除线程 */ + if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid1); + if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid2); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_thread_dynamic_simple() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + thread_dynamic_simple_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_thread_dynamic_simple, a dynamic thread example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + thread_dynamic_simple_init(); + + return 0; +} +#endif diff --git a/examples/kernel/thread_priority.c b/examples/kernel/thread_priority.c index 6d0692e4dc..1d6fb4a80e 100644 --- a/examples/kernel/thread_priority.c +++ b/examples/kernel/thread_priority.c @@ -1,105 +1,105 @@ -#include -#include "tc_comm.h" - -struct rt_thread thread1; -struct rt_thread thread2; -static char thread1_stack[THREAD_STACK_SIZE]; -static char thread2_stack[THREAD_STACK_SIZE]; -static rt_uint32_t count = 0; - -/* - * the priority of thread1 > the priority of thread2 - */ -static void thread1_entry(void* parameter) -{ - while (1) - { - count ++; - rt_kprintf("count = %d\n", count); - - rt_thread_delay(10); - } -} - -static void thread2_entry(void* parameter) -{ - rt_tick_t tick; - - tick = rt_tick_get(); - while (1) - { - if (rt_tick_get() - tick >= 50) - { - if (count == 0) - tc_done(TC_STAT_FAILED); - else - tc_done(TC_STAT_PASSED); - - break; - } - } -} - -int thread_priority_init() -{ - rt_err_t result; - - result = rt_thread_init(&thread1, - "t1", - thread1_entry, RT_NULL, - &thread1_stack[0], sizeof(thread1_stack), - THREAD_PRIORITY - 1, THREAD_TIMESLICE); - - if (result == RT_EOK) - rt_thread_startup(&thread1); - else - tc_stat(TC_STAT_FAILED); - - rt_thread_init(&thread2, - "t2", - thread2_entry, RT_NULL, - &thread2_stack[0], sizeof(thread2_stack), - THREAD_PRIORITY + 1, THREAD_TIMESLICE); - - if (result == RT_EOK) - rt_thread_startup(&thread2); - else - tc_stat(TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - - if (thread1.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread1); - if (thread2.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread2); - - /* unlock scheduler */ - rt_exit_critical(); -} -int _tc_thread_priority() -{ - count = 0; - - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - thread_priority_init(); - - return RT_TICK_PER_SECOND; -} -FINSH_FUNCTION_EXPORT(_tc_thread_priority, a priority thread test); -#else -int rt_application_init() -{ - thread_priority_init(); - - return 0; -} -#endif - +#include +#include "tc_comm.h" + +struct rt_thread thread1; +struct rt_thread thread2; +static char thread1_stack[THREAD_STACK_SIZE]; +static char thread2_stack[THREAD_STACK_SIZE]; +static rt_uint32_t count = 0; + +/* + * the priority of thread1 > the priority of thread2 + */ +static void thread1_entry(void* parameter) +{ + while (1) + { + count ++; + rt_kprintf("count = %d\n", count); + + rt_thread_delay(10); + } +} + +static void thread2_entry(void* parameter) +{ + rt_tick_t tick; + + tick = rt_tick_get(); + while (1) + { + if (rt_tick_get() - tick >= 50) + { + if (count == 0) + tc_done(TC_STAT_FAILED); + else + tc_done(TC_STAT_PASSED); + + break; + } + } +} + +int thread_priority_init() +{ + rt_err_t result; + + result = rt_thread_init(&thread1, + "t1", + thread1_entry, RT_NULL, + &thread1_stack[0], sizeof(thread1_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); + + if (result == RT_EOK) + rt_thread_startup(&thread1); + else + tc_stat(TC_STAT_FAILED); + + rt_thread_init(&thread2, + "t2", + thread2_entry, RT_NULL, + &thread2_stack[0], sizeof(thread2_stack), + THREAD_PRIORITY + 1, THREAD_TIMESLICE); + + if (result == RT_EOK) + rt_thread_startup(&thread2); + else + tc_stat(TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* lock scheduler */ + rt_enter_critical(); + + if (thread1.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread1); + if (thread2.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread2); + + /* unlock scheduler */ + rt_exit_critical(); +} +int _tc_thread_priority() +{ + count = 0; + + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + thread_priority_init(); + + return RT_TICK_PER_SECOND; +} +FINSH_FUNCTION_EXPORT(_tc_thread_priority, a priority thread test); +#else +int rt_application_init() +{ + thread_priority_init(); + + return 0; +} +#endif + diff --git a/examples/kernel/thread_resume.c b/examples/kernel/thread_resume.c index e0ed6fa5f7..ac8b6cb489 100644 --- a/examples/kernel/thread_resume.c +++ b/examples/kernel/thread_resume.c @@ -1,123 +1,123 @@ -/* - * 程序清单:唤醒线程 - * - * 这个例子中将创建两个动态线程,低优先级线程将挂起自身,然后 - * 高优先级线程将在一定时刻后唤醒低优先级线程。 - */ -#include -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - /* 低优先级线程1开始运行 */ - rt_kprintf("thread1 startup%d\n"); - - /* 挂起自身 */ - rt_kprintf("suspend thread self\n"); - rt_thread_suspend(tid1); - /* 主动执行线程调度 */ - rt_schedule(); - - /* 当线程1被唤醒时 */ - rt_kprintf("thread1 resumed\n"); -} -static void thread_cleanup(rt_thread_t tid) -{ - if (tid == tid1) - { - tid1 = RT_NULL; - } - if (tid == tid2) - { - tid = RT_NULL; - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - /* 延时10个OS Tick */ - rt_thread_delay(10); - - /* 唤醒线程1 */ - rt_thread_resume(tid1); - rt_kprintf("thread2: to resume thread1\n"); - - /* 延时10个OS Tick */ - rt_thread_delay(10); - - /* 线程2自动退出 */ -} - -int thread_resume_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("thread", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - { - tid1->cleanup = thread_cleanup; - rt_thread_startup(tid1); - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("thread", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - { - tid2->cleanup = thread_cleanup; - rt_thread_startup(tid2); - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_resume() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_resume_init(); - - /* 返回TestCase运行的最长时间 */ - return 25; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_resume, a thread resume example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_resume_init(); - - return 0; -} -#endif +/* + * 程序清单:唤醒线程 + * + * 这个例子中将创建两个动态线程,低优先级线程将挂起自身,然后 + * 高优先级线程将在一定时刻后唤醒低优先级线程。 + */ +#include +#include "tc_comm.h" + +/* 指向线程控制块的指针 */ +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +/* 线程1入口 */ +static void thread1_entry(void* parameter) +{ + /* 低优先级线程1开始运行 */ + rt_kprintf("thread1 startup%d\n"); + + /* 挂起自身 */ + rt_kprintf("suspend thread self\n"); + rt_thread_suspend(tid1); + /* 主动执行线程调度 */ + rt_schedule(); + + /* 当线程1被唤醒时 */ + rt_kprintf("thread1 resumed\n"); +} +static void thread_cleanup(rt_thread_t tid) +{ + if (tid == tid1) + { + tid1 = RT_NULL; + } + if (tid == tid2) + { + tid = RT_NULL; + } +} + +/* 线程2入口 */ +static void thread2_entry(void* parameter) +{ + /* 延时10个OS Tick */ + rt_thread_delay(10); + + /* 唤醒线程1 */ + rt_thread_resume(tid1); + rt_kprintf("thread2: to resume thread1\n"); + + /* 延时10个OS Tick */ + rt_thread_delay(10); + + /* 线程2自动退出 */ +} + +int thread_resume_init() +{ + /* 创建线程1 */ + tid1 = rt_thread_create("thread", + thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid1 != RT_NULL) + { + tid1->cleanup = thread_cleanup; + rt_thread_startup(tid1); + } + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程2 */ + tid2 = rt_thread_create("thread", + thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); + if (tid2 != RT_NULL) + { + tid2->cleanup = thread_cleanup; + rt_thread_startup(tid2); + } + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除线程 */ + if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid1); + if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid2); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_thread_resume() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + thread_resume_init(); + + /* 返回TestCase运行的最长时间 */ + return 25; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_thread_resume, a thread resume example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + thread_resume_init(); + + return 0; +} +#endif diff --git a/examples/kernel/thread_same_priority.c b/examples/kernel/thread_same_priority.c index 228990ba1a..5e0fb81116 100644 --- a/examples/kernel/thread_same_priority.c +++ b/examples/kernel/thread_same_priority.c @@ -1,96 +1,96 @@ -#include -#include "tc_comm.h" - -static struct rt_thread thread1; -static struct rt_thread thread2; -static char thread1_stack[THREAD_STACK_SIZE]; -static char thread2_stack[THREAD_STACK_SIZE]; - -volatile static rt_uint32_t t1_count = 0; -volatile static rt_uint32_t t2_count = 0; -static void thread1_entry(void* parameter) -{ - while (1) - { - t1_count ++; - } -} - -static void thread2_entry(void* parameter) -{ - while (1) - { - t2_count ++; - } -} - -rt_err_t thread_same_priority_init() -{ - rt_err_t result; - - result = rt_thread_init(&thread1, - "t1", - thread1_entry, RT_NULL, - &thread1_stack[0], sizeof(thread1_stack), - THREAD_PRIORITY, 10); - if (result == RT_EOK) - rt_thread_startup(&thread1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - result = rt_thread_init(&thread2, - "t2", - thread2_entry, RT_NULL, - &thread2_stack[0], sizeof(thread2_stack), - THREAD_PRIORITY, 5); - if (result == RT_EOK) - rt_thread_startup(&thread2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return result; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - - if (thread1.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread1); - if (thread2.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread2); - - /* unlock scheduler */ - rt_exit_critical(); - - rt_kprintf("t1_count=%d t2_count=%d\n",t1_count,t2_count); - - if (t1_count / t2_count != 2) - tc_stat(TC_STAT_END | TC_STAT_FAILED); - else - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_same_priority() -{ - t1_count = 0; - t2_count = 0; - - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - - thread_same_priority_init(); - - return 100; -} -FINSH_FUNCTION_EXPORT(_tc_thread_same_priority, a same priority thread test); -#else -int rt_application_init() -{ - thread_same_priority_init(); - - return 0; -} -#endif +#include +#include "tc_comm.h" + +static struct rt_thread thread1; +static struct rt_thread thread2; +static char thread1_stack[THREAD_STACK_SIZE]; +static char thread2_stack[THREAD_STACK_SIZE]; + +volatile static rt_uint32_t t1_count = 0; +volatile static rt_uint32_t t2_count = 0; +static void thread1_entry(void* parameter) +{ + while (1) + { + t1_count ++; + } +} + +static void thread2_entry(void* parameter) +{ + while (1) + { + t2_count ++; + } +} + +rt_err_t thread_same_priority_init() +{ + rt_err_t result; + + result = rt_thread_init(&thread1, + "t1", + thread1_entry, RT_NULL, + &thread1_stack[0], sizeof(thread1_stack), + THREAD_PRIORITY, 10); + if (result == RT_EOK) + rt_thread_startup(&thread1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + result = rt_thread_init(&thread2, + "t2", + thread2_entry, RT_NULL, + &thread2_stack[0], sizeof(thread2_stack), + THREAD_PRIORITY, 5); + if (result == RT_EOK) + rt_thread_startup(&thread2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return result; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* lock scheduler */ + rt_enter_critical(); + + if (thread1.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread1); + if (thread2.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread2); + + /* unlock scheduler */ + rt_exit_critical(); + + rt_kprintf("t1_count=%d t2_count=%d\n",t1_count,t2_count); + + if (t1_count / t2_count != 2) + tc_stat(TC_STAT_END | TC_STAT_FAILED); + else + tc_done(TC_STAT_PASSED); +} + +int _tc_thread_same_priority() +{ + t1_count = 0; + t2_count = 0; + + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + + thread_same_priority_init(); + + return 100; +} +FINSH_FUNCTION_EXPORT(_tc_thread_same_priority, a same priority thread test); +#else +int rt_application_init() +{ + thread_same_priority_init(); + + return 0; +} +#endif diff --git a/examples/kernel/thread_static.c b/examples/kernel/thread_static.c index 9a8c158c86..4547304b58 100644 --- a/examples/kernel/thread_static.c +++ b/examples/kernel/thread_static.c @@ -1,52 +1,52 @@ -#include -#include "tc_comm.h" - -/* - * This is an example for static thread - */ -static struct rt_thread thread; -static char thread_stack[THREAD_STACK_SIZE]; -static void thread_entry(void* parameter) -{ - rt_kprintf("thread staticly inited ok\n"); - rt_thread_delay(10); - rt_kprintf("thread exit\n"); - - tc_done(TC_STAT_PASSED); -} - -rt_err_t thread_static_init() -{ - rt_err_t result; - - result = rt_thread_init(&thread, - "test", - thread_entry, RT_NULL, - &thread_stack[0], sizeof(thread_stack), - THREAD_PRIORITY, 10); - - if (result == RT_EOK) - rt_thread_startup(&thread); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return result; -} - -#ifdef RT_USING_TC -int _tc_thread_static() -{ - thread_static_init(); - - return 20; -} -FINSH_FUNCTION_EXPORT(_tc_thread_static, a static thread test); -#else -int rt_application_init() -{ - thread_static_init(); - - return 0; -} -#endif - +#include +#include "tc_comm.h" + +/* + * This is an example for static thread + */ +static struct rt_thread thread; +static char thread_stack[THREAD_STACK_SIZE]; +static void thread_entry(void* parameter) +{ + rt_kprintf("thread staticly inited ok\n"); + rt_thread_delay(10); + rt_kprintf("thread exit\n"); + + tc_done(TC_STAT_PASSED); +} + +rt_err_t thread_static_init() +{ + rt_err_t result; + + result = rt_thread_init(&thread, + "test", + thread_entry, RT_NULL, + &thread_stack[0], sizeof(thread_stack), + THREAD_PRIORITY, 10); + + if (result == RT_EOK) + rt_thread_startup(&thread); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return result; +} + +#ifdef RT_USING_TC +int _tc_thread_static() +{ + thread_static_init(); + + return 20; +} +FINSH_FUNCTION_EXPORT(_tc_thread_static, a static thread test); +#else +int rt_application_init() +{ + thread_static_init(); + + return 0; +} +#endif + diff --git a/examples/kernel/thread_static_simple.c b/examples/kernel/thread_static_simple.c index 61005fd23b..3ab8ffda01 100644 --- a/examples/kernel/thread_static_simple.c +++ b/examples/kernel/thread_static_simple.c @@ -1,99 +1,99 @@ -/* - * 程序清单:静态线程 - * - * 这个程序会初始化2个静态线程,它们拥有共同的入口函数,但参数不相同 - */ -#include -#include "tc_comm.h" - -/* 线程1控制块 */ -static struct rt_thread thread1; -/* 线程1栈 */ -static rt_uint8_t thread1_stack[THREAD_STACK_SIZE]; -/* 线程2控制块 */ -static struct rt_thread thread2; -/* 线程2栈 */ -static rt_uint8_t thread2_stack[THREAD_STACK_SIZE]; - -/* 线程入口 */ -static void thread_entry(void* parameter) -{ - rt_uint32_t count = 0; - rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */ - - while (1) - { - /* 打印线程计数值输出 */ - rt_kprintf("thread%d count: %d\n", no, count ++); - - /* 休眠10个OS Tick */ - rt_thread_delay(10); - } -} - -int thread_static_simple_init() -{ - rt_err_t result; - - /* 初始化线程1 */ - result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */ - thread_entry, (void*)1, /* 线程的入口是thread_entry,入口参数是1 */ - &thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */ - THREAD_PRIORITY, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程1 */ - rt_thread_startup(&thread1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 初始化线程2 */ - result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */ - thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是2 */ - &thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */ - THREAD_PRIORITY + 1, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程2 */ - rt_thread_startup(&thread2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 执行线程脱离 */ - if (thread1.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread1); - if (thread2.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_static_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_static_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_static_simple_init(); - - return 0; -} -#endif +/* + * 程序清单:静态线程 + * + * 这个程序会初始化2个静态线程,它们拥有共同的入口函数,但参数不相同 + */ +#include +#include "tc_comm.h" + +/* 线程1控制块 */ +static struct rt_thread thread1; +/* 线程1栈 */ +static rt_uint8_t thread1_stack[THREAD_STACK_SIZE]; +/* 线程2控制块 */ +static struct rt_thread thread2; +/* 线程2栈 */ +static rt_uint8_t thread2_stack[THREAD_STACK_SIZE]; + +/* 线程入口 */ +static void thread_entry(void* parameter) +{ + rt_uint32_t count = 0; + rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */ + + while (1) + { + /* 打印线程计数值输出 */ + rt_kprintf("thread%d count: %d\n", no, count ++); + + /* 休眠10个OS Tick */ + rt_thread_delay(10); + } +} + +int thread_static_simple_init() +{ + rt_err_t result; + + /* 初始化线程1 */ + result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */ + thread_entry, (void*)1, /* 线程的入口是thread_entry,入口参数是1 */ + &thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */ + THREAD_PRIORITY, 10); + if (result == RT_EOK) /* 如果返回正确,启动线程1 */ + rt_thread_startup(&thread1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 初始化线程2 */ + result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */ + thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是2 */ + &thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */ + THREAD_PRIORITY + 1, 10); + if (result == RT_EOK) /* 如果返回正确,启动线程2 */ + rt_thread_startup(&thread2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 执行线程脱离 */ + if (thread1.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread1); + if (thread2.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread2); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_thread_static_simple() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + thread_static_simple_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + thread_static_simple_init(); + + return 0; +} +#endif diff --git a/examples/kernel/thread_suspend.c b/examples/kernel/thread_suspend.c index b38cb8fdfb..7c019573b1 100644 --- a/examples/kernel/thread_suspend.c +++ b/examples/kernel/thread_suspend.c @@ -1,101 +1,101 @@ -/* - * 程序清单:挂起线程 - * - * 这个例子中将创建两个动态线程,高优先级线程将在一定时刻后挂起低优先级线程。 - */ -#include -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 线程1采用低优先级运行,一直打印计数值 */ - rt_kprintf("thread count: %d\n", count ++); - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - /* 延时10个OS Tick */ - rt_thread_delay(10); - - /* 挂起线程1 */ - rt_thread_suspend(tid1); - - /* 延时10个OS Tick */ - rt_thread_delay(10); - - /* 线程2自动退出 */ - tid2 = RT_NULL; -} - -int thread_suspend_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("thread", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("thread", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_suspend() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_suspend_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_suspend, a thread suspend example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_suspend_init(); - - return 0; -} -#endif +/* + * 程序清单:挂起线程 + * + * 这个例子中将创建两个动态线程,高优先级线程将在一定时刻后挂起低优先级线程。 + */ +#include +#include "tc_comm.h" + +/* 指向线程控制块的指针 */ +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +/* 线程1入口 */ +static void thread1_entry(void* parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + /* 线程1采用低优先级运行,一直打印计数值 */ + rt_kprintf("thread count: %d\n", count ++); + } +} + +/* 线程2入口 */ +static void thread2_entry(void* parameter) +{ + /* 延时10个OS Tick */ + rt_thread_delay(10); + + /* 挂起线程1 */ + rt_thread_suspend(tid1); + + /* 延时10个OS Tick */ + rt_thread_delay(10); + + /* 线程2自动退出 */ + tid2 = RT_NULL; +} + +int thread_suspend_init() +{ + /* 创建线程1 */ + tid1 = rt_thread_create("thread", + thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程2 */ + tid2 = rt_thread_create("thread", + thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除线程 */ + if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid1); + if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid2); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_thread_suspend() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + thread_suspend_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_thread_suspend, a thread suspend example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + thread_suspend_init(); + + return 0; +} +#endif diff --git a/examples/kernel/thread_yield.c b/examples/kernel/thread_yield.c index 71244589b8..de2c3a53ac 100644 --- a/examples/kernel/thread_yield.c +++ b/examples/kernel/thread_yield.c @@ -1,101 +1,101 @@ -/* - * 程序清单: - */ -#include -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 打印线程1的输出 */ - rt_kprintf("thread1: count = %d\n", count ++); - - /* 执行yield后应该切换到thread2执行 */ - rt_thread_yield(); - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 打印线程2的输出 */ - rt_kprintf("thread2: count = %d\n", count ++); - - /* 执行yield后应该切换到thread1执行 */ - rt_thread_yield(); - } -} - -int thread_yield_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("thread", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("thread", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_yield() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_yield_init(); - - /* 返回TestCase运行的最长时间 */ - return 30; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_yield, a thread yield example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_yield_init(); - - return 0; -} -#endif +/* + * 程序清单: + */ +#include +#include "tc_comm.h" + +/* 指向线程控制块的指针 */ +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +/* 线程1入口 */ +static void thread1_entry(void* parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + /* 打印线程1的输出 */ + rt_kprintf("thread1: count = %d\n", count ++); + + /* 执行yield后应该切换到thread2执行 */ + rt_thread_yield(); + } +} + +/* 线程2入口 */ +static void thread2_entry(void* parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + /* 打印线程2的输出 */ + rt_kprintf("thread2: count = %d\n", count ++); + + /* 执行yield后应该切换到thread1执行 */ + rt_thread_yield(); + } +} + +int thread_yield_init() +{ + /* 创建线程1 */ + tid1 = rt_thread_create("thread", + thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建线程2 */ + tid2 = rt_thread_create("thread", + thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除线程 */ + if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid1); + if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid2); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_thread_yield() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + thread_yield_init(); + + /* 返回TestCase运行的最长时间 */ + return 30; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_thread_yield, a thread yield example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + thread_yield_init(); + + return 0; +} +#endif diff --git a/examples/kernel/timer_control.c b/examples/kernel/timer_control.c index f04521a752..f685f140eb 100644 --- a/examples/kernel/timer_control.c +++ b/examples/kernel/timer_control.c @@ -1,84 +1,84 @@ -/* - * 程序清单:动态定时器例程 - * - * 这个例程会创建1个动态周期型定时器对象,然后控制它进行定时时间长度的更改。 - */ -#include -#include "tc_comm.h" - -/* 定时器的控制块 */ -static rt_timer_t timer1; -static rt_uint8_t count; - -/* 定时器超时函数 */ -static void timeout1(void* parameter) -{ - rt_tick_t timeout = 50; - - rt_kprintf("periodic timer is timeout\n"); - - count ++; - /* 停止定时器自身 */ - if (count >= 8) - { - /* 控制定时器然后更改超时时间长度 */ - rt_timer_control(timer1, RT_TIMER_CTRL_SET_TIME, (void *)&timeout); - count = 0; - } -} - -void timer_control_init() -{ - /* 创建定时器1 */ - timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ - timeout1, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ - RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ - /* 启动定时器 */ - if (timer1 != RT_NULL) - rt_timer_start(timer1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除定时器对象 */ - rt_timer_delete(timer1); - timer1 = RT_NULL; - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_control() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - - /* 执行定时器例程 */ - count = 0; - timer_control_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_timer_control, a timer control example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - timer_control_init(); - - return 0; -} -#endif +/* + * 程序清单:动态定时器例程 + * + * 这个例程会创建1个动态周期型定时器对象,然后控制它进行定时时间长度的更改。 + */ +#include +#include "tc_comm.h" + +/* 定时器的控制块 */ +static rt_timer_t timer1; +static rt_uint8_t count; + +/* 定时器超时函数 */ +static void timeout1(void* parameter) +{ + rt_tick_t timeout = 50; + + rt_kprintf("periodic timer is timeout\n"); + + count ++; + /* 停止定时器自身 */ + if (count >= 8) + { + /* 控制定时器然后更改超时时间长度 */ + rt_timer_control(timer1, RT_TIMER_CTRL_SET_TIME, (void *)&timeout); + count = 0; + } +} + +void timer_control_init() +{ + /* 创建定时器1 */ + timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ + timeout1, /* 超时时回调的处理函数 */ + RT_NULL, /* 超时函数的入口参数 */ + 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ + RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ + /* 启动定时器 */ + if (timer1 != RT_NULL) + rt_timer_start(timer1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除定时器对象 */ + rt_timer_delete(timer1); + timer1 = RT_NULL; + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_timer_control() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + + /* 执行定时器例程 */ + count = 0; + timer_control_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_timer_control, a timer control example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + timer_control_init(); + + return 0; +} +#endif diff --git a/examples/kernel/timer_dynamic.c b/examples/kernel/timer_dynamic.c index b28a4c9056..49262b8193 100644 --- a/examples/kernel/timer_dynamic.c +++ b/examples/kernel/timer_dynamic.c @@ -1,91 +1,91 @@ -/* - * 程序清单:动态定时器例程 - * - * 这个例程会创建两个动态定时器对象,一个是单次定时,一个是周期性的定时 - */ -#include -#include "tc_comm.h" - -/* 定时器的控制块 */ -static rt_timer_t timer1; -static rt_timer_t timer2; - -/* 定时器1超时函数 */ -static void timeout1(void* parameter) -{ - rt_kprintf("periodic timer is timeout\n"); -} - -/* 定时器2超时函数 */ -static void timeout2(void* parameter) -{ - rt_kprintf("one shot timer is timeout\n"); -} - -void timer_create_init() -{ - /* 创建定时器1 */ - timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ - timeout1, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ - RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ - /* 启动定时器 */ - if (timer1 != RT_NULL) - rt_timer_start(timer1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建定时器2 */ - timer2 = rt_timer_create("timer2", /* 定时器名字是 timer2 */ - timeout2, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 30, /* 定时长度为30个OS Tick */ - RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */ - - /* 启动定时器 */ - if (timer2 != RT_NULL) - rt_timer_start(timer2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除定时器对象 */ - rt_timer_delete(timer1); - rt_timer_delete(timer2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_create() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - - /* 执行定时器例程 */ - timer_create_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_timer_create, a dynamic timer example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - timer_create_init(); - - return 0; -} -#endif +/* + * 程序清单:动态定时器例程 + * + * 这个例程会创建两个动态定时器对象,一个是单次定时,一个是周期性的定时 + */ +#include +#include "tc_comm.h" + +/* 定时器的控制块 */ +static rt_timer_t timer1; +static rt_timer_t timer2; + +/* 定时器1超时函数 */ +static void timeout1(void* parameter) +{ + rt_kprintf("periodic timer is timeout\n"); +} + +/* 定时器2超时函数 */ +static void timeout2(void* parameter) +{ + rt_kprintf("one shot timer is timeout\n"); +} + +void timer_create_init() +{ + /* 创建定时器1 */ + timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ + timeout1, /* 超时时回调的处理函数 */ + RT_NULL, /* 超时函数的入口参数 */ + 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ + RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ + /* 启动定时器 */ + if (timer1 != RT_NULL) + rt_timer_start(timer1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + /* 创建定时器2 */ + timer2 = rt_timer_create("timer2", /* 定时器名字是 timer2 */ + timeout2, /* 超时时回调的处理函数 */ + RT_NULL, /* 超时函数的入口参数 */ + 30, /* 定时长度为30个OS Tick */ + RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */ + + /* 启动定时器 */ + if (timer2 != RT_NULL) + rt_timer_start(timer2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除定时器对象 */ + rt_timer_delete(timer1); + rt_timer_delete(timer2); + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_timer_create() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + + /* 执行定时器例程 */ + timer_create_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_timer_create, a dynamic timer example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + timer_create_init(); + + return 0; +} +#endif diff --git a/examples/kernel/timer_stop_self.c b/examples/kernel/timer_stop_self.c index 8a19637e52..6d1e287e54 100644 --- a/examples/kernel/timer_stop_self.c +++ b/examples/kernel/timer_stop_self.c @@ -1,82 +1,82 @@ -/* - * 程序清单:动态定时器例程 - * - * 这个例程会创建1个动态周期型定时器对象 - */ -#include -#include "tc_comm.h" - -/* 定时器的控制块 */ -static rt_timer_t timer1; -static rt_uint8_t count; - -/* 定时器超时函数 */ -static void timeout1(void* parameter) -{ - rt_kprintf("periodic timer is timeout\n"); - - count ++; - /* 停止定时器自身 */ - if (count >= 8) - { - /* 停止定时器 */ - rt_timer_stop(timer1); - count = 0; - } -} - -void timer_stop_self_init() -{ - /* 创建定时器1 */ - timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ - timeout1, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ - RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ - /* 启动定时器 */ - if (timer1 != RT_NULL) - rt_timer_start(timer1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除定时器对象 */ - rt_timer_delete(timer1); - timer1 = RT_NULL; - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_stop_self() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - - /* 执行定时器例程 */ - count = 0; - timer_stop_self_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_timer_stop_self, a dynamic timer example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - timer_stop_self_init(); - - return 0; -} -#endif +/* + * 程序清单:动态定时器例程 + * + * 这个例程会创建1个动态周期型定时器对象 + */ +#include +#include "tc_comm.h" + +/* 定时器的控制块 */ +static rt_timer_t timer1; +static rt_uint8_t count; + +/* 定时器超时函数 */ +static void timeout1(void* parameter) +{ + rt_kprintf("periodic timer is timeout\n"); + + count ++; + /* 停止定时器自身 */ + if (count >= 8) + { + /* 停止定时器 */ + rt_timer_stop(timer1); + count = 0; + } +} + +void timer_stop_self_init() +{ + /* 创建定时器1 */ + timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ + timeout1, /* 超时时回调的处理函数 */ + RT_NULL, /* 超时函数的入口参数 */ + 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ + RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ + /* 启动定时器 */ + if (timer1 != RT_NULL) + rt_timer_start(timer1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ + rt_enter_critical(); + + /* 删除定时器对象 */ + rt_timer_delete(timer1); + timer1 = RT_NULL; + + /* 调度器解锁 */ + rt_exit_critical(); + + /* 设置TestCase状态 */ + tc_done(TC_STAT_PASSED); +} + +int _tc_timer_stop_self() +{ + /* 设置TestCase清理回调函数 */ + tc_cleanup(_tc_cleanup); + + /* 执行定时器例程 */ + count = 0; + timer_stop_self_init(); + + /* 返回TestCase运行的最长时间 */ + return 100; +} +/* 输出函数命令到finsh shell中 */ +FINSH_FUNCTION_EXPORT(_tc_timer_stop_self, a dynamic timer example); +#else +/* 用户应用入口 */ +int rt_application_init() +{ + timer_stop_self_init(); + + return 0; +} +#endif diff --git a/examples/kernel/timer_timeout.c b/examples/kernel/timer_timeout.c index d82754e557..80241e53f2 100644 --- a/examples/kernel/timer_timeout.c +++ b/examples/kernel/timer_timeout.c @@ -1,122 +1,122 @@ -/* - * ³ÌÐòÇ嵥£ºÏûϢ¶ÓÁÐÀý³Ì - * - * Õâ¸ö³ÌÐò»ᴴ½¨3¸ö¶¯̬Ị̈߳¬һ¸öÏ̻߳á´ÓÏûϢ¶ÓÁÐÖÐÊÕȡÏûϢ£»һ¸öÏ̻߳ᶨʱ¸øÏû - * Ϣ¶ÓÁз¢ËÍÏûϢ£»һ¸öÏ̻߳ᶨʱ¸øÏûϢ¶ÓÁз¢Ëͽô¼±ÏûϢ¡£ - */ -#include -#include "tc_comm.h" - -/* ָÏòÏ߳̿ØÖƿéµÄָÕë */ -static rt_thread_t tid = RT_NULL; - -/* ÏûϢ¶ÓÁпØÖƿé */ -static struct rt_messagequeue mq; -/* ÏûϢ¶ÓÁÐÖÐÓõ½µķÅÖÃÏûϢµÄÄڴæ³Ø */ -static char msg_pool[2048]; - -/* ¶¨ʱÆ÷µĿØÖƿé */ -static struct rt_timer timer; -static rt_uint16_t no = 0; -static void timer_timeout(void* parameter) -{ - char buf[32]; - rt_uint32_t length; - - length = rt_snprintf(buf, sizeof(buf), "message %d", no++); - rt_mq_send(&mq, &buf[0], length); -} - -/* Ï߳ÌÈë¿ں¯Êý */ -static void thread_entry(void* parameter) -{ - char buf[64]; - rt_err_t result; - - /* ³õʼ»¯¶¨ʱÆ÷ */ - rt_timer_init(&timer, "timer", /* ¶¨ʱÆ÷Ãû×ÖÊÇ timer1 */ - timer_timeout, /* ³¬ʱʱ»ص÷µĴ¦Àíº¯Êý */ - RT_NULL, /* ³¬ʱº¯ÊýµÄÈë¿ڲÎÊý */ - 1, /* ¶¨ʱ³¤¶ȣ¬ÒÔOS TickΪµ¥λ£¬¼´1¸öOS Tick */ - RT_TIMER_FLAG_PERIODIC); /* ÖÜÆÚÐԶ¨ʱÆ÷ */ - - while (1) - { - rt_memset(&buf[0], 0, sizeof(buf)); - - /* ´ÓÏûϢ¶ÓÁÐÖнÓÊÕÏûϢ */ - result = rt_mq_recv(&mq, &buf[0], sizeof(buf), 1); - if (result == RT_EOK) - { - rt_kprintf("recv msg: %s\n", buf); - } - else if (result == -RT_ETIMEOUT) - { - rt_kprintf("recv msg timeout\n"); - } - } -} - -int timer_timeout_init() -{ - /* ³õʼ»¯ÏûϢ¶ÓÁÐ */ - rt_mq_init(&mq, "mqt", - &msg_pool[0], /* Äڴæ³ØָÏòmsg_pool */ - 128 - sizeof(void*), /* ÿ¸öÏûϢµĴóСÊÇ 128 - void* */ - sizeof(msg_pool), /* Äڴæ³صĴóСÊÇmsg_poolµĴóС */ - RT_IPC_FLAG_FIFO); /* Èç¹ûÓжà¸öÏ̵߳ȴý£¬°´ÕÕÏÈÀ´Ïȵõ½µķ½·¨·ÖÅäÏûϢ */ - - /* ´´½¨Ï߳Ì */ - tid = rt_thread_create("t", - thread_entry, RT_NULL, /* Ï߳ÌÈë¿ÚÊÇthread_entry, Èë¿ڲÎÊýÊÇRT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* µ÷¶ÈÆ÷ÉÏËø£¬ÉÏËøº󣬽«²»ÔÙÇл»µ½ÆäËûỊ̈߳¬½öÏìӦÖжÏ */ - rt_enter_critical(); - - /* ɾ³ýÏ߳Ì */ - if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid); - - /* ִÐÐÏûϢ¶ÓÁжÔÏóÍÑÀë */ - rt_mq_detach(&mq); - /* ִÐж¨ʱÆ÷ÍÑÀë */ - rt_timer_detach(&timer); - - /* µ÷¶ÈÆ÷½âËø */ - rt_exit_critical(); - - /* ÉèÖÃTestCase״̬ */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_timeout() -{ - /* ÉèÖÃTestCaseÇåÀí»ص÷º¯Êý */ - tc_cleanup(_tc_cleanup); - timer_timeout_init(); - - /* ·µ»ØTestCaseÔËÐеÄ×ʱ¼ä */ - return 100; -} -/* Êä³öº¯ÊýÃüÁfinsh shellÖÐ */ -FINSH_FUNCTION_EXPORT(_tc_timer_timeout, a thread timer testcase); -#else -/* Óû§ӦÓÃÈë¿Ú */ -int rt_application_init() -{ - timer_timeout_init(); - - return 0; -} -#endif +/* + * ³ÌÐòÇ嵥£ºÏûϢ¶ÓÁÐÀý³Ì + * + * Õâ¸ö³ÌÐò»ᴴ½¨3¸ö¶¯̬Ị̈߳¬һ¸öÏ̻߳á´ÓÏûϢ¶ÓÁÐÖÐÊÕȡÏûϢ£»һ¸öÏ̻߳ᶨʱ¸øÏû + * Ϣ¶ÓÁз¢ËÍÏûϢ£»һ¸öÏ̻߳ᶨʱ¸øÏûϢ¶ÓÁз¢Ëͽô¼±ÏûϢ¡£ + */ +#include +#include "tc_comm.h" + +/* ָÏòÏ߳̿ØÖƿéµÄָÕë */ +static rt_thread_t tid = RT_NULL; + +/* ÏûϢ¶ÓÁпØÖƿé */ +static struct rt_messagequeue mq; +/* ÏûϢ¶ÓÁÐÖÐÓõ½µķÅÖÃÏûϢµÄÄڴæ³Ø */ +static char msg_pool[2048]; + +/* ¶¨ʱÆ÷µĿØÖƿé */ +static struct rt_timer timer; +static rt_uint16_t no = 0; +static void timer_timeout(void* parameter) +{ + char buf[32]; + rt_uint32_t length; + + length = rt_snprintf(buf, sizeof(buf), "message %d", no++); + rt_mq_send(&mq, &buf[0], length); +} + +/* Ï߳ÌÈë¿ں¯Êý */ +static void thread_entry(void* parameter) +{ + char buf[64]; + rt_err_t result; + + /* ³õʼ»¯¶¨ʱÆ÷ */ + rt_timer_init(&timer, "timer", /* ¶¨ʱÆ÷Ãû×ÖÊÇ timer1 */ + timer_timeout, /* ³¬ʱʱ»ص÷µĴ¦Àíº¯Êý */ + RT_NULL, /* ³¬ʱº¯ÊýµÄÈë¿ڲÎÊý */ + 1, /* ¶¨ʱ³¤¶ȣ¬ÒÔOS TickΪµ¥λ£¬¼´1¸öOS Tick */ + RT_TIMER_FLAG_PERIODIC); /* ÖÜÆÚÐԶ¨ʱÆ÷ */ + + while (1) + { + rt_memset(&buf[0], 0, sizeof(buf)); + + /* ´ÓÏûϢ¶ÓÁÐÖнÓÊÕÏûϢ */ + result = rt_mq_recv(&mq, &buf[0], sizeof(buf), 1); + if (result == RT_EOK) + { + rt_kprintf("recv msg: %s\n", buf); + } + else if (result == -RT_ETIMEOUT) + { + rt_kprintf("recv msg timeout\n"); + } + } +} + +int timer_timeout_init() +{ + /* ³õʼ»¯ÏûϢ¶ÓÁÐ */ + rt_mq_init(&mq, "mqt", + &msg_pool[0], /* Äڴæ³ØָÏòmsg_pool */ + 128 - sizeof(void*), /* ÿ¸öÏûϢµĴóСÊÇ 128 - void* */ + sizeof(msg_pool), /* Äڴæ³صĴóСÊÇmsg_poolµĴóС */ + RT_IPC_FLAG_FIFO); /* Èç¹ûÓжà¸öÏ̵߳ȴý£¬°´ÕÕÏÈÀ´Ïȵõ½µķ½·¨·ÖÅäÏûϢ */ + + /* ´´½¨Ï߳Ì */ + tid = rt_thread_create("t", + thread_entry, RT_NULL, /* Ï߳ÌÈë¿ÚÊÇthread_entry, Èë¿ڲÎÊýÊÇRT_NULL */ + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid != RT_NULL) + rt_thread_startup(tid); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* µ÷¶ÈÆ÷ÉÏËø£¬ÉÏËøº󣬽«²»ÔÙÇл»µ½ÆäËûỊ̈߳¬½öÏìӦÖжÏ */ + rt_enter_critical(); + + /* ɾ³ýÏ߳Ì */ + if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) + rt_thread_delete(tid); + + /* ִÐÐÏûϢ¶ÓÁжÔÏóÍÑÀë */ + rt_mq_detach(&mq); + /* ִÐж¨ʱÆ÷ÍÑÀë */ + rt_timer_detach(&timer); + + /* µ÷¶ÈÆ÷½âËø */ + rt_exit_critical(); + + /* ÉèÖÃTestCase״̬ */ + tc_done(TC_STAT_PASSED); +} + +int _tc_timer_timeout() +{ + /* ÉèÖÃTestCaseÇåÀí»ص÷º¯Êý */ + tc_cleanup(_tc_cleanup); + timer_timeout_init(); + + /* ·µ»ØTestCaseÔËÐеÄ×ʱ¼ä */ + return 100; +} +/* Êä³öº¯ÊýÃüÁfinsh shellÖÐ */ +FINSH_FUNCTION_EXPORT(_tc_timer_timeout, a thread timer testcase); +#else +/* Óû§ӦÓÃÈë¿Ú */ +int rt_application_init() +{ + timer_timeout_init(); + + return 0; +} +#endif diff --git a/examples/libc/SConscript b/examples/libc/SConscript index 60a48fd376..7801049c07 100644 --- a/examples/libc/SConscript +++ b/examples/libc/SConscript @@ -1,6 +1,6 @@ -from building import * - -src = Glob('*.c') -group = DefineGroup('libc_test', src, depend = ['RT_USING_NEWLIB', 'RT_USING_PTHREADS']) - -Return('group') +from building import * + +src = Glob('*.c') +group = DefineGroup('libc_test', src, depend = ['RT_USING_NEWLIB', 'RT_USING_PTHREADS']) + +Return('group') diff --git a/examples/libc/dirent.c b/examples/libc/dirent.c index a763ecb022..75604f6067 100644 --- a/examples/libc/dirent.c +++ b/examples/libc/dirent.c @@ -1,56 +1,56 @@ -/* - * dirent.c - * - * Created on: 2010-11-17 - * Author: bernard - */ -#include -#include -#include - -#include -int libc_dirent() -{ - DIR * dirp; - long int save3 = 0; - long int cur; - int i = 0; - int result = 0; - struct dirent *dp; - - dirp = opendir("/"); - for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) - { - /* save position 3 (after fourth entry) */ - if (i++ == 3) - save3 = telldir(dirp); - - printf("%s\n", dp->d_name); - - /* stop at 400 (just to make sure dirp->__offset and dirp->__size are - scrambled */ - if (i == 400) - break; - } - - printf("going back past 4-th entry...\n"); - - /* go back to saved entry */ - seekdir(dirp, save3); - - /* Check whether telldir equals to save3 now. */ - cur = telldir(dirp); - if (cur != save3) - { - printf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur); - result = 1; - } - - /* print remaining files (3-last) */ - for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) - printf("%s\n", dp->d_name); - - closedir(dirp); - return result; -} -FINSH_FUNCTION_EXPORT(libc_dirent, dirent test for libc); +/* + * dirent.c + * + * Created on: 2010-11-17 + * Author: bernard + */ +#include +#include +#include + +#include +int libc_dirent() +{ + DIR * dirp; + long int save3 = 0; + long int cur; + int i = 0; + int result = 0; + struct dirent *dp; + + dirp = opendir("/"); + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) + { + /* save position 3 (after fourth entry) */ + if (i++ == 3) + save3 = telldir(dirp); + + printf("%s\n", dp->d_name); + + /* stop at 400 (just to make sure dirp->__offset and dirp->__size are + scrambled */ + if (i == 400) + break; + } + + printf("going back past 4-th entry...\n"); + + /* go back to saved entry */ + seekdir(dirp, save3); + + /* Check whether telldir equals to save3 now. */ + cur = telldir(dirp); + if (cur != save3) + { + printf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur); + result = 1; + } + + /* print remaining files (3-last) */ + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) + printf("%s\n", dp->d_name); + + closedir(dirp); + return result; +} +FINSH_FUNCTION_EXPORT(libc_dirent, dirent test for libc); diff --git a/examples/libc/env.c b/examples/libc/env.c index 56f906774f..ca67ac2e2a 100644 --- a/examples/libc/env.c +++ b/examples/libc/env.c @@ -1,18 +1,18 @@ -/* - * env.c - * - * Created on: 2010-11-17 - * Author: bernard - */ -#include -#include -#include - -int libc_env() -{ - printf("PATH=%s\n", getenv("PATH")); - putenv("foo=bar"); - printf("foo=%s\n", getenv("foo")); - return 0; -} -FINSH_FUNCTION_EXPORT(libc_env, get/set_env test); +/* + * env.c + * + * Created on: 2010-11-17 + * Author: bernard + */ +#include +#include +#include + +int libc_env() +{ + printf("PATH=%s\n", getenv("PATH")); + putenv("foo=bar"); + printf("foo=%s\n", getenv("foo")); + return 0; +} +FINSH_FUNCTION_EXPORT(libc_env, get/set_env test); diff --git a/examples/libc/file.c b/examples/libc/file.c index 94aa206ce9..f366e04702 100644 --- a/examples/libc/file.c +++ b/examples/libc/file.c @@ -1,516 +1,516 @@ -/* - * fstat.c - * - * Created on: 2010-11-17 - * Author: bernard - */ -#include -#include -#include -#include -#include -#include - -const char* text = "this is a test string\n"; -void libc_fstat() -{ - int fd; - struct stat s; - - fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0); - if (fd < 0) - { - printf("open failed\n"); - return; - } - - write(fd, text, strlen(text) + 1); - printf("begin: %d\n", lseek(fd, 0, SEEK_SET)); - printf("end: %d\n", lseek(fd, 0, SEEK_END)); - - printf("fstat result: %d\n", fstat(fd, &s)); - close(fd); -} -FINSH_FUNCTION_EXPORT(libc_fstat, fstat test for libc); - -void libc_lseek() -{ - int fd; - - fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0); - if (fd < 0) - { - printf("open failed\n"); - return; - } - - write(fd, text, strlen(text) + 1); - printf("begin: %d\n", lseek(fd, 0, SEEK_SET)); - printf("end: %d\n", lseek(fd, 0, SEEK_END)); - close(fd); -} -FINSH_FUNCTION_EXPORT(libc_lseek, lseek test for libc); - -void sleep(int tick) -{ - rt_thread_sleep(tick); -} - -int libc_fseek(void) -{ - const char *tmpdir; - char *fname; - int fd; - FILE *fp; - const char outstr[] = "hello world!\n"; - char strbuf[sizeof outstr]; - char buf[200]; - struct stat st1; - struct stat st2; - int result = 0; - - tmpdir = getenv("TMPDIR"); - if (tmpdir == NULL || tmpdir[0] == '\0') - tmpdir = "/tmp"; - - asprintf(&fname, "%s/tst-fseek.XXXXXX", tmpdir); - if (fname == NULL) - { - fprintf(stderr, "cannot generate name for temporary file: %s\n", - strerror(errno)); - return 1; - } - - /* Create a temporary file. */ - fd = mkstemp(fname); - if (fd == -1) - { - fprintf(stderr, "cannot open temporary file: %s\n", strerror(errno)); - return 1; - } - - fp = fdopen(fd, "w+"); - if (fp == NULL) - { - fprintf(stderr, "cannot get FILE for temporary file: %s\n", strerror( - errno)); - return 1; - } - setbuffer(fp, strbuf, sizeof(outstr) - 1); - - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error\n", __LINE__); - result = 1; - goto out; - } - - /* The EOF flag must be reset. */ - if (fgetc(fp) != EOF) - { - printf("%d: managed to read at end of file\n", __LINE__); - result = 1; - } - else if (!feof(fp)) - { - printf("%d: EOF flag not set\n", __LINE__); - result = 1; - } - if (fseek(fp, 0, SEEK_CUR) != 0) - { - printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__); - result = 1; - } - else if (feof(fp)) - { - printf("%d: fseek() didn't reset EOF flag\n", __LINE__); - result = 1; - } - - /* Do the same for fseeko(). */ - if (fgetc(fp) != EOF) - { - printf("%d: managed to read at end of file\n", __LINE__); - result = 1; - } - else if (!feof(fp)) - { - printf("%d: EOF flag not set\n", __LINE__); - result = 1; - } - if (fseeko(fp, 0, SEEK_CUR) != 0) - { - printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__); - result = 1; - } - else if (feof(fp)) - { - printf("%d: fseek() didn't reset EOF flag\n", __LINE__); - result = 1; - } - - /* Go back to the beginning of the file: absolute. */ - if (fseek(fp, 0, SEEK_SET) != 0) - { - printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - int pos = lseek(fd, 0, SEEK_CUR); - printf("%d: lseek() returned different position, pos %d\n", __LINE__, - pos); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } - - /* Now with fseeko. */ - if (fseeko(fp, 0, SEEK_SET) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } - - /* Go back to the beginning of the file: relative. */ - if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0) - { - printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } - - /* Now with fseeko. */ - if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } - - /* Go back to the beginning of the file: from the end. */ - if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0) - { - printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } - - /* Now with fseeko. */ - if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } - - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error 2\n", __LINE__); - result = 1; - goto out; - } - - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error 3\n", __LINE__); - result = 1; - goto out; - } - - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error 4\n", __LINE__); - result = 1; - goto out; - } - - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error 5\n", __LINE__); - result = 1; - goto out; - } - - if (fputc('1', fp) == EOF || fputc('2', fp) == EOF) - { - printf("%d: cannot add characters at the end\n", __LINE__); - result = 1; - goto out; - } - - /* Check the access time. */ - if (fstat(fd, &st1) < 0) - { - printf("%d: fstat64() before fseeko() failed\n\n", __LINE__); - result = 1; - } - else - { - sleep(1); - - if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_CUR) != 0) - { - printf("%d: fseek() after write characters failed\n", __LINE__); - result = 1; - goto out; - } - else - { - - time_t t; - /* Make sure the timestamp actually can be different. */ - sleep(1); - t = time(NULL); - - if (fstat(fd, &st2) < 0) - { - printf("%d: fstat64() after fseeko() failed\n\n", __LINE__); - result = 1; - } - if (st1.st_ctime >= t) - { - printf("%d: st_ctime not updated\n", __LINE__); - result = 1; - } - if (st1.st_mtime >= t) - { - printf("%d: st_mtime not updated\n", __LINE__); - result = 1; - } - if (st1.st_ctime >= st2.st_ctime) - { - printf("%d: st_ctime not changed\n", __LINE__); - result = 1; - } - if (st1.st_mtime >= st2.st_mtime) - { - printf("%d: st_mtime not changed\n", __LINE__); - result = 1; - } - } - } - - if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2 - * (sizeof(outstr) - 1)) - { - printf("%d: reading 2 records plus bits failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp( - &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2 - * (sizeof(outstr) - 1)] != '1' || buf[2 * (sizeof(outstr) - 1) + 1] - != '2') - { - printf("%d: reading records failed\n", __LINE__); - result = 1; - } - else if (ungetc('9', fp) == EOF) - { - printf("%d: ungetc() failed\n", __LINE__); - result = 1; - } - else if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_END) != 0) - { - printf("%d: fseek after ungetc failed\n", __LINE__); - result = 1; - } - else if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2 - * (sizeof(outstr) - 1)) - { - printf("%d: reading 2 records plus bits failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp( - &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2 - * (sizeof(outstr) - 1)] != '1') - { - printf("%d: reading records for the second time failed\n", __LINE__); - result = 1; - } - else if (buf[2 * (sizeof(outstr) - 1) + 1] == '9') - { - printf("%d: unget character not ignored\n", __LINE__); - result = 1; - } - else if (buf[2 * (sizeof(outstr) - 1) + 1] != '2') - { - printf("%d: unget somehow changed character\n", __LINE__); - result = 1; - } - - fclose(fp); - - fp = fopen(fname, "r"); - if (fp == NULL) - { - printf("%d: fopen() failed\n\n", __LINE__); - result = 1; - } - else if (fstat(fileno(fp), &st1) < 0) - { - printf("%d: fstat64() before fseeko() failed\n\n", __LINE__); - result = 1; - } - else if (fseeko(fp, 0, SEEK_END) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__); - result = 1; - } - else if (ftello(fp) != st1.st_size) - { - printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__, - (size_t) st1.st_size, (size_t) ftello(fp)); - result = 1; - } - else - printf("%d: SEEK_END works\n", __LINE__); - if (fp != NULL) - fclose(fp); - - fp = fopen(fname, "r"); - if (fp == NULL) - { - printf("%d: fopen() failed\n\n", __LINE__); - result = 1; - } - else if (fstat(fileno(fp), &st1) < 0) - { - printf("%d: fstat64() before fgetc() failed\n\n", __LINE__); - result = 1; - } - else if (fgetc(fp) == EOF) - { - printf("%d: fgetc() before fseeko() failed\n\n", __LINE__); - result = 1; - } - else if (fseeko(fp, 0, SEEK_END) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__); - result = 1; - } - else if (ftello(fp) != st1.st_size) - { - printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__, - (size_t) st1.st_size, (size_t) ftello(fp)); - result = 1; - } - else - printf("%d: SEEK_END works\n", __LINE__); - if (fp != NULL) - fclose(fp); - - out: unlink(fname); - - return result; -} -FINSH_FUNCTION_EXPORT(libc_fseek, lseek test for libc); +/* + * fstat.c + * + * Created on: 2010-11-17 + * Author: bernard + */ +#include +#include +#include +#include +#include +#include + +const char* text = "this is a test string\n"; +void libc_fstat() +{ + int fd; + struct stat s; + + fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0); + if (fd < 0) + { + printf("open failed\n"); + return; + } + + write(fd, text, strlen(text) + 1); + printf("begin: %d\n", lseek(fd, 0, SEEK_SET)); + printf("end: %d\n", lseek(fd, 0, SEEK_END)); + + printf("fstat result: %d\n", fstat(fd, &s)); + close(fd); +} +FINSH_FUNCTION_EXPORT(libc_fstat, fstat test for libc); + +void libc_lseek() +{ + int fd; + + fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0); + if (fd < 0) + { + printf("open failed\n"); + return; + } + + write(fd, text, strlen(text) + 1); + printf("begin: %d\n", lseek(fd, 0, SEEK_SET)); + printf("end: %d\n", lseek(fd, 0, SEEK_END)); + close(fd); +} +FINSH_FUNCTION_EXPORT(libc_lseek, lseek test for libc); + +void sleep(int tick) +{ + rt_thread_sleep(tick); +} + +int libc_fseek(void) +{ + const char *tmpdir; + char *fname; + int fd; + FILE *fp; + const char outstr[] = "hello world!\n"; + char strbuf[sizeof outstr]; + char buf[200]; + struct stat st1; + struct stat st2; + int result = 0; + + tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL || tmpdir[0] == '\0') + tmpdir = "/tmp"; + + asprintf(&fname, "%s/tst-fseek.XXXXXX", tmpdir); + if (fname == NULL) + { + fprintf(stderr, "cannot generate name for temporary file: %s\n", + strerror(errno)); + return 1; + } + + /* Create a temporary file. */ + fd = mkstemp(fname); + if (fd == -1) + { + fprintf(stderr, "cannot open temporary file: %s\n", strerror(errno)); + return 1; + } + + fp = fdopen(fd, "w+"); + if (fp == NULL) + { + fprintf(stderr, "cannot get FILE for temporary file: %s\n", strerror( + errno)); + return 1; + } + setbuffer(fp, strbuf, sizeof(outstr) - 1); + + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error\n", __LINE__); + result = 1; + goto out; + } + + /* The EOF flag must be reset. */ + if (fgetc(fp) != EOF) + { + printf("%d: managed to read at end of file\n", __LINE__); + result = 1; + } + else if (!feof(fp)) + { + printf("%d: EOF flag not set\n", __LINE__); + result = 1; + } + if (fseek(fp, 0, SEEK_CUR) != 0) + { + printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__); + result = 1; + } + else if (feof(fp)) + { + printf("%d: fseek() didn't reset EOF flag\n", __LINE__); + result = 1; + } + + /* Do the same for fseeko(). */ + if (fgetc(fp) != EOF) + { + printf("%d: managed to read at end of file\n", __LINE__); + result = 1; + } + else if (!feof(fp)) + { + printf("%d: EOF flag not set\n", __LINE__); + result = 1; + } + if (fseeko(fp, 0, SEEK_CUR) != 0) + { + printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__); + result = 1; + } + else if (feof(fp)) + { + printf("%d: fseek() didn't reset EOF flag\n", __LINE__); + result = 1; + } + + /* Go back to the beginning of the file: absolute. */ + if (fseek(fp, 0, SEEK_SET) != 0) + { + printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + int pos = lseek(fd, 0, SEEK_CUR); + printf("%d: lseek() returned different position, pos %d\n", __LINE__, + pos); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } + + /* Now with fseeko. */ + if (fseeko(fp, 0, SEEK_SET) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } + + /* Go back to the beginning of the file: relative. */ + if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0) + { + printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } + + /* Now with fseeko. */ + if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } + + /* Go back to the beginning of the file: from the end. */ + if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0) + { + printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } + + /* Now with fseeko. */ + if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } + + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error 2\n", __LINE__); + result = 1; + goto out; + } + + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error 3\n", __LINE__); + result = 1; + goto out; + } + + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error 4\n", __LINE__); + result = 1; + goto out; + } + + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error 5\n", __LINE__); + result = 1; + goto out; + } + + if (fputc('1', fp) == EOF || fputc('2', fp) == EOF) + { + printf("%d: cannot add characters at the end\n", __LINE__); + result = 1; + goto out; + } + + /* Check the access time. */ + if (fstat(fd, &st1) < 0) + { + printf("%d: fstat64() before fseeko() failed\n\n", __LINE__); + result = 1; + } + else + { + sleep(1); + + if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_CUR) != 0) + { + printf("%d: fseek() after write characters failed\n", __LINE__); + result = 1; + goto out; + } + else + { + + time_t t; + /* Make sure the timestamp actually can be different. */ + sleep(1); + t = time(NULL); + + if (fstat(fd, &st2) < 0) + { + printf("%d: fstat64() after fseeko() failed\n\n", __LINE__); + result = 1; + } + if (st1.st_ctime >= t) + { + printf("%d: st_ctime not updated\n", __LINE__); + result = 1; + } + if (st1.st_mtime >= t) + { + printf("%d: st_mtime not updated\n", __LINE__); + result = 1; + } + if (st1.st_ctime >= st2.st_ctime) + { + printf("%d: st_ctime not changed\n", __LINE__); + result = 1; + } + if (st1.st_mtime >= st2.st_mtime) + { + printf("%d: st_mtime not changed\n", __LINE__); + result = 1; + } + } + } + + if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2 + * (sizeof(outstr) - 1)) + { + printf("%d: reading 2 records plus bits failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp( + &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2 + * (sizeof(outstr) - 1)] != '1' || buf[2 * (sizeof(outstr) - 1) + 1] + != '2') + { + printf("%d: reading records failed\n", __LINE__); + result = 1; + } + else if (ungetc('9', fp) == EOF) + { + printf("%d: ungetc() failed\n", __LINE__); + result = 1; + } + else if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_END) != 0) + { + printf("%d: fseek after ungetc failed\n", __LINE__); + result = 1; + } + else if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2 + * (sizeof(outstr) - 1)) + { + printf("%d: reading 2 records plus bits failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp( + &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2 + * (sizeof(outstr) - 1)] != '1') + { + printf("%d: reading records for the second time failed\n", __LINE__); + result = 1; + } + else if (buf[2 * (sizeof(outstr) - 1) + 1] == '9') + { + printf("%d: unget character not ignored\n", __LINE__); + result = 1; + } + else if (buf[2 * (sizeof(outstr) - 1) + 1] != '2') + { + printf("%d: unget somehow changed character\n", __LINE__); + result = 1; + } + + fclose(fp); + + fp = fopen(fname, "r"); + if (fp == NULL) + { + printf("%d: fopen() failed\n\n", __LINE__); + result = 1; + } + else if (fstat(fileno(fp), &st1) < 0) + { + printf("%d: fstat64() before fseeko() failed\n\n", __LINE__); + result = 1; + } + else if (fseeko(fp, 0, SEEK_END) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__); + result = 1; + } + else if (ftello(fp) != st1.st_size) + { + printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__, + (size_t) st1.st_size, (size_t) ftello(fp)); + result = 1; + } + else + printf("%d: SEEK_END works\n", __LINE__); + if (fp != NULL) + fclose(fp); + + fp = fopen(fname, "r"); + if (fp == NULL) + { + printf("%d: fopen() failed\n\n", __LINE__); + result = 1; + } + else if (fstat(fileno(fp), &st1) < 0) + { + printf("%d: fstat64() before fgetc() failed\n\n", __LINE__); + result = 1; + } + else if (fgetc(fp) == EOF) + { + printf("%d: fgetc() before fseeko() failed\n\n", __LINE__); + result = 1; + } + else if (fseeko(fp, 0, SEEK_END) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__); + result = 1; + } + else if (ftello(fp) != st1.st_size) + { + printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__, + (size_t) st1.st_size, (size_t) ftello(fp)); + result = 1; + } + else + printf("%d: SEEK_END works\n", __LINE__); + if (fp != NULL) + fclose(fp); + + out: unlink(fname); + + return result; +} +FINSH_FUNCTION_EXPORT(libc_fseek, lseek test for libc); diff --git a/examples/libc/memory.c b/examples/libc/memory.c index 81b566f646..ee524fa43d 100644 --- a/examples/libc/memory.c +++ b/examples/libc/memory.c @@ -1,56 +1,56 @@ -/* - * memory.c - * - * Created on: 2010-11-17 - * Author: bernard - */ -#include -#include -#include -#include - -static int errors = 0; -static void merror(const char *msg) -{ - ++errors; - printf("Error: %s\n", msg); -} - -int libc_mem(void) -{ - void *p; - int save; - - errno = 0; - - p = malloc(-1); - save = errno; - - if (p != NULL) - merror("malloc (-1) succeeded."); - - if (p == NULL && save != ENOMEM) - merror("errno is not set correctly"); - - p = malloc(10); - if (p == NULL) - merror("malloc (10) failed."); - - /* realloc (p, 0) == free (p). */ - p = realloc(p, 0); - if (p != NULL) - merror("realloc (p, 0) failed."); - - p = malloc(0); - if (p == NULL) - { - printf("malloc(0) returns NULL\n"); - } - - p = realloc(p, 0); - if (p != NULL) - merror("realloc (p, 0) failed."); - - return errors != 0; -} -FINSH_FUNCTION_EXPORT(libc_mem, memory test for libc); +/* + * memory.c + * + * Created on: 2010-11-17 + * Author: bernard + */ +#include +#include +#include +#include + +static int errors = 0; +static void merror(const char *msg) +{ + ++errors; + printf("Error: %s\n", msg); +} + +int libc_mem(void) +{ + void *p; + int save; + + errno = 0; + + p = malloc(-1); + save = errno; + + if (p != NULL) + merror("malloc (-1) succeeded."); + + if (p == NULL && save != ENOMEM) + merror("errno is not set correctly"); + + p = malloc(10); + if (p == NULL) + merror("malloc (10) failed."); + + /* realloc (p, 0) == free (p). */ + p = realloc(p, 0); + if (p != NULL) + merror("realloc (p, 0) failed."); + + p = malloc(0); + if (p == NULL) + { + printf("malloc(0) returns NULL\n"); + } + + p = realloc(p, 0); + if (p != NULL) + merror("realloc (p, 0) failed."); + + return errors != 0; +} +FINSH_FUNCTION_EXPORT(libc_mem, memory test for libc); diff --git a/examples/libc/mq.c b/examples/libc/mq.c index 6f9b1c6e59..3163e27975 100644 --- a/examples/libc/mq.c +++ b/examples/libc/mq.c @@ -1,119 +1,119 @@ -#include -#include -#include -#include -#include -#include - -#define MQ_NAME_1 "testmsg1" -#define MQ_NAME_2 "testmsg2" -#define MSG_SIZE 128 -#define MAX_MSG 3 - -const char *s_msg_ptr[] = {"msg test 1", "msg test 2", "msg test 3"}; -char r_msg_ptr_1[MAX_MSG][MSG_SIZE]; -char r_msg_ptr_2[MAX_MSG][MSG_SIZE]; -pthread_t send1, send2, rev1, rev2; - -int * send_1(void * mq) -{ - int i; - mqd_t mq1 = *(mqd_t *)mq; - - printf("Enter into send_1 \n"); - for (i = 0; i < MAX_MSG; i++ ) { - if ( -1 == mq_send(mq1, s_msg_ptr[i], MSG_SIZE, i)) { - perror("mq_send doesn't return success \n"); - pthread_exit((void *)1); - } - printf("[%d] send '%s' in thread send_1. \n", i+1, s_msg_ptr[i]); - } - pthread_exit((void *)0); - -} - -int * send_2(void * mq) -{ - int i; - mqd_t mq2 = *(mqd_t *)mq; - - printf("Enter into send_2 \n"); - for (i = 0; i < MAX_MSG; i++ ) { - if ( -1 == mq_send(mq2, s_msg_ptr[i], MSG_SIZE, i)) { - perror("mq_send doesn't return success \n"); - pthread_exit((void *)1); - } - printf("[%d] send '%s' in thread send_2. \n", i+1, s_msg_ptr[i]); - } - pthread_exit((void *)0); -} - -int * receive_1(void * mq) -{ - int i; - mqd_t mq1 = *(mqd_t *)mq; - - printf("Enter into receive_1 \n"); - for (i = 0; i< MAX_MSG; i++) { - if ( -1 == mq_receive(mq1, r_msg_ptr_1[i], MSG_SIZE, NULL) ) { - perror("mq_receive doesn't return success \n"); - pthread_exit((void *)1); - } - printf("[%d] receive '%s' in thread receive_1. \n", i+1, r_msg_ptr_1[i]); - } - pthread_exit((void *)0); -} -int * receive_2(void * mq) -{ - int i; - mqd_t mq2 = *(mqd_t *)mq; - - printf("Enter into receive_2 \n"); - for (i = 0; i< MAX_MSG; i++) { - if ( -1 == mq_receive(mq2, r_msg_ptr_2[i], MSG_SIZE, NULL) ) { - perror("mq_receive doesn't return success \n"); - pthread_exit((void *)1); - } - printf("[%d] receive '%s' in thread receive_2. \n", i+1, r_msg_ptr_2[i]); - } - pthread_exit((void *)0); -} - -int libc_mq() -{ - mqd_t mq1 = 0, mq2 = 0; - struct mq_attr mqstat; - int oflag = O_CREAT|O_RDWR; - - memset(&mqstat, 0, sizeof(mqstat)); - mqstat.mq_maxmsg = MAX_MSG; - mqstat.mq_msgsize = MSG_SIZE; - mqstat.mq_flags = 0; - - if( ((mqd_t) -1) == (mq1 = mq_open(MQ_NAME_1,oflag,0777, &mqstat)) ) { - printf("mq_open doesn't return success \n"); - return -1; - } - if( ((mqd_t) -1) == (mq2 = mq_open(MQ_NAME_2,oflag,0777, &mqstat)) ) { - printf("mq_open doesn't return success \n"); - return -1; - } - pthread_create(&send1, NULL, (void *)send_1, (void *)&mq1); - pthread_create(&send2, NULL, (void *)send_2, (void *)&mq2); - pthread_create(&rev1, NULL, (void *)receive_1, (void *)&mq1); - pthread_create(&rev2, NULL, (void *)receive_2, (void *)&mq2); - pthread_join(send1, NULL); - pthread_join(send2, NULL); - pthread_join(rev1, NULL); - pthread_join(rev2, NULL); - - mq_close(mq1); - mq_close(mq2); - mq_unlink(MQ_NAME_1); - mq_unlink(MQ_NAME_2); - - printf("PASSED\n"); - return 0; -} -#include -FINSH_FUNCTION_EXPORT(libc_mq, posix mqueue test); +#include +#include +#include +#include +#include +#include + +#define MQ_NAME_1 "testmsg1" +#define MQ_NAME_2 "testmsg2" +#define MSG_SIZE 128 +#define MAX_MSG 3 + +const char *s_msg_ptr[] = {"msg test 1", "msg test 2", "msg test 3"}; +char r_msg_ptr_1[MAX_MSG][MSG_SIZE]; +char r_msg_ptr_2[MAX_MSG][MSG_SIZE]; +pthread_t send1, send2, rev1, rev2; + +int * send_1(void * mq) +{ + int i; + mqd_t mq1 = *(mqd_t *)mq; + + printf("Enter into send_1 \n"); + for (i = 0; i < MAX_MSG; i++ ) { + if ( -1 == mq_send(mq1, s_msg_ptr[i], MSG_SIZE, i)) { + perror("mq_send doesn't return success \n"); + pthread_exit((void *)1); + } + printf("[%d] send '%s' in thread send_1. \n", i+1, s_msg_ptr[i]); + } + pthread_exit((void *)0); + +} + +int * send_2(void * mq) +{ + int i; + mqd_t mq2 = *(mqd_t *)mq; + + printf("Enter into send_2 \n"); + for (i = 0; i < MAX_MSG; i++ ) { + if ( -1 == mq_send(mq2, s_msg_ptr[i], MSG_SIZE, i)) { + perror("mq_send doesn't return success \n"); + pthread_exit((void *)1); + } + printf("[%d] send '%s' in thread send_2. \n", i+1, s_msg_ptr[i]); + } + pthread_exit((void *)0); +} + +int * receive_1(void * mq) +{ + int i; + mqd_t mq1 = *(mqd_t *)mq; + + printf("Enter into receive_1 \n"); + for (i = 0; i< MAX_MSG; i++) { + if ( -1 == mq_receive(mq1, r_msg_ptr_1[i], MSG_SIZE, NULL) ) { + perror("mq_receive doesn't return success \n"); + pthread_exit((void *)1); + } + printf("[%d] receive '%s' in thread receive_1. \n", i+1, r_msg_ptr_1[i]); + } + pthread_exit((void *)0); +} +int * receive_2(void * mq) +{ + int i; + mqd_t mq2 = *(mqd_t *)mq; + + printf("Enter into receive_2 \n"); + for (i = 0; i< MAX_MSG; i++) { + if ( -1 == mq_receive(mq2, r_msg_ptr_2[i], MSG_SIZE, NULL) ) { + perror("mq_receive doesn't return success \n"); + pthread_exit((void *)1); + } + printf("[%d] receive '%s' in thread receive_2. \n", i+1, r_msg_ptr_2[i]); + } + pthread_exit((void *)0); +} + +int libc_mq() +{ + mqd_t mq1 = 0, mq2 = 0; + struct mq_attr mqstat; + int oflag = O_CREAT|O_RDWR; + + memset(&mqstat, 0, sizeof(mqstat)); + mqstat.mq_maxmsg = MAX_MSG; + mqstat.mq_msgsize = MSG_SIZE; + mqstat.mq_flags = 0; + + if( ((mqd_t) -1) == (mq1 = mq_open(MQ_NAME_1,oflag,0777, &mqstat)) ) { + printf("mq_open doesn't return success \n"); + return -1; + } + if( ((mqd_t) -1) == (mq2 = mq_open(MQ_NAME_2,oflag,0777, &mqstat)) ) { + printf("mq_open doesn't return success \n"); + return -1; + } + pthread_create(&send1, NULL, (void *)send_1, (void *)&mq1); + pthread_create(&send2, NULL, (void *)send_2, (void *)&mq2); + pthread_create(&rev1, NULL, (void *)receive_1, (void *)&mq1); + pthread_create(&rev2, NULL, (void *)receive_2, (void *)&mq2); + pthread_join(send1, NULL); + pthread_join(send2, NULL); + pthread_join(rev1, NULL); + pthread_join(rev2, NULL); + + mq_close(mq1); + mq_close(mq2); + mq_unlink(MQ_NAME_1); + mq_unlink(MQ_NAME_2); + + printf("PASSED\n"); + return 0; +} +#include +FINSH_FUNCTION_EXPORT(libc_mq, posix mqueue test); diff --git a/examples/libc/printf.c b/examples/libc/printf.c index 12435731b7..2d2d8a7763 100644 --- a/examples/libc/printf.c +++ b/examples/libc/printf.c @@ -1,200 +1,200 @@ -#include -#include -#include - -#include - -char * format[] = { - "%", - "%0.", - "%.0", - "%+0.", - "%+.0", - "%.5", - "%+.5", - "%2.5", - "%22.5", - "%022.5", - "%#022.5", - "%-#022.5", - "%+#022.5", - "%-22.5", - "%+22.5", - "%--22.5", - "%++22.5", - "%+-22.5", - "%-+22.5", - "%-#022.5", - "%-#22.5", - "%-2.22", - "%+2.22", - "%-#02.22", - "%-#2.22", - "%-1.5", - "%1.5", - "%-#01.5", - "%-#1.5", - "%-#.5", - "%-#1.", - "%-#.", - NULL -}; - - -static void -intchk (const char *fmt) -{ - (void) printf("%15s :, \"", fmt); - (void) printf(fmt, 0); - (void) printf("\", \""); - (void) printf(fmt, 123); - (void) printf("\", \""); - (void) printf(fmt, -18); - (void) printf("\"\n"); -} - -static void -fltchk (const char *fmt) -{ - (void) printf("%15s :, \"", fmt); - (void) printf(fmt, 0.0); - (void) printf("\", \""); - (void) printf(fmt, 123.0001); - (void) printf("\", \""); - (void) printf(fmt, -18.0002301); - (void) printf("\"\n"); -} - - -int printf_test() -{ - char buf[256]; - int i; - - printf("%s\n\n", "# vim:syntax=off:"); - - /* integers */ - for(i=0;format[i];i++) { - strcpy(buf, format[i]); - strcat(buf, "d"); - intchk(buf); - } - - /* floats */ - for(i=0;format[i];i++) { - strcpy(buf, format[i]); - strcat(buf, "f"); - fltchk(buf); - } - /* hexa */ - for(i=0;format[i];i++) { - strcpy(buf, format[i]); - strcat(buf, "x"); - intchk(buf); - } - - printf("#%.4x %4x#\n", 4, 88); - printf("#%4x#\n",4); - printf("#%#22.8x#\n",1234567); - - printf("#%+2i#\n",18); - printf("#%i#\n",18); - printf("#%llu#\n",4294967297ULL); - printf("#%#x#\n",44444); - printf("#%-8i#\n",33); - printf("#%i#\n",18); - printf("#%d#\n",18); - printf("#%u#\n",18); - printf("#%lu#\n",18); - printf("#%li#\n",18); - printf("#%-+#06d#\n", -123); - printf("#%-+#6d#\n", -123); - printf("#%+#06d#\n", -123); - printf("#%06d#\n", -123); - printf("#%+15s#\n","ABCDEF"); - /* from ncurses make_keys */ - printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1"); - printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1"); - printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1"); - printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1"); - printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1"); - printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1"); - printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1"); - printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1"); - printf("{ %4d, %*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1"); - printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1"); - printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1"); - printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1"); - printf("%*.*f\n", 0, 16, 0.0); - printf("%*.*f\n", 16, 16, 0.0); - printf("%*.*f\n", 2, 2, -0.0); - printf("%*.*f\n", 20, 0, -123.123); - printf("%*.*f\n", 10, 0, +123.123); - - - i = printf("\"%s\"\n","A"); - printf("%i\n", i); - /* from glibc's tst-printf.c */ - - { - char buf[20]; - char buf2[512]; - int i; - - printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n", - snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf), - buf); - memset(buf2,0,sizeof(buf)); - i=snprintf(buf2, 256, "%.9999u", 10); - printf("%i %i\n",i,strlen(buf2)); - - printf ("snprintf (\"%%.999999u\", 10) == %d\n", - snprintf(buf2, sizeof(buf2), "%.999999u", 10)); - } - return 0; -} - -void libc_printf() -{ - printf("stdout test!!\n"); - fprintf(stdout, "fprintf test!!\n"); - fprintf(stderr, "fprintf test!!\n"); - puts("puts test!!\n"); - - putc('1', stderr); - putc('2', stderr); - putc('\n', stderr); - - printf_test(); -} -FINSH_FUNCTION_EXPORT(libc_printf, printf test in libc); - - -void libc_dprintf() -{ - int fd; - - fd = open("/dev/console", O_WRONLY, 0); - if (fd >0) - { - dprintf(fd, "fd:%d printf test!!\n", fd); - close(fd); - } -} -FINSH_FUNCTION_EXPORT(libc_dprintf, dprintf test); - - -void libc_fdopen() -{ - int fd; - FILE* fp; - - fd = open("/dev/console", O_WRONLY, 0); - if (fd >0) - { - fp = fdopen(fd, "w"); - fprintf(fp, "fdopen test, fd %d!!\n", fileno(fp)); - fclose(fp); - } -} -FINSH_FUNCTION_EXPORT(libc_fdopen, fdopen test); +#include +#include +#include + +#include + +char * format[] = { + "%", + "%0.", + "%.0", + "%+0.", + "%+.0", + "%.5", + "%+.5", + "%2.5", + "%22.5", + "%022.5", + "%#022.5", + "%-#022.5", + "%+#022.5", + "%-22.5", + "%+22.5", + "%--22.5", + "%++22.5", + "%+-22.5", + "%-+22.5", + "%-#022.5", + "%-#22.5", + "%-2.22", + "%+2.22", + "%-#02.22", + "%-#2.22", + "%-1.5", + "%1.5", + "%-#01.5", + "%-#1.5", + "%-#.5", + "%-#1.", + "%-#.", + NULL +}; + + +static void +intchk (const char *fmt) +{ + (void) printf("%15s :, \"", fmt); + (void) printf(fmt, 0); + (void) printf("\", \""); + (void) printf(fmt, 123); + (void) printf("\", \""); + (void) printf(fmt, -18); + (void) printf("\"\n"); +} + +static void +fltchk (const char *fmt) +{ + (void) printf("%15s :, \"", fmt); + (void) printf(fmt, 0.0); + (void) printf("\", \""); + (void) printf(fmt, 123.0001); + (void) printf("\", \""); + (void) printf(fmt, -18.0002301); + (void) printf("\"\n"); +} + + +int printf_test() +{ + char buf[256]; + int i; + + printf("%s\n\n", "# vim:syntax=off:"); + + /* integers */ + for(i=0;format[i];i++) { + strcpy(buf, format[i]); + strcat(buf, "d"); + intchk(buf); + } + + /* floats */ + for(i=0;format[i];i++) { + strcpy(buf, format[i]); + strcat(buf, "f"); + fltchk(buf); + } + /* hexa */ + for(i=0;format[i];i++) { + strcpy(buf, format[i]); + strcat(buf, "x"); + intchk(buf); + } + + printf("#%.4x %4x#\n", 4, 88); + printf("#%4x#\n",4); + printf("#%#22.8x#\n",1234567); + + printf("#%+2i#\n",18); + printf("#%i#\n",18); + printf("#%llu#\n",4294967297ULL); + printf("#%#x#\n",44444); + printf("#%-8i#\n",33); + printf("#%i#\n",18); + printf("#%d#\n",18); + printf("#%u#\n",18); + printf("#%lu#\n",18); + printf("#%li#\n",18); + printf("#%-+#06d#\n", -123); + printf("#%-+#6d#\n", -123); + printf("#%+#06d#\n", -123); + printf("#%06d#\n", -123); + printf("#%+15s#\n","ABCDEF"); + /* from ncurses make_keys */ + printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1"); + printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1"); + printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1"); + printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1"); + printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1"); + printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1"); + printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1"); + printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1"); + printf("{ %4d, %*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1"); + printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1"); + printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1"); + printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1"); + printf("%*.*f\n", 0, 16, 0.0); + printf("%*.*f\n", 16, 16, 0.0); + printf("%*.*f\n", 2, 2, -0.0); + printf("%*.*f\n", 20, 0, -123.123); + printf("%*.*f\n", 10, 0, +123.123); + + + i = printf("\"%s\"\n","A"); + printf("%i\n", i); + /* from glibc's tst-printf.c */ + + { + char buf[20]; + char buf2[512]; + int i; + + printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n", + snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf), + buf); + memset(buf2,0,sizeof(buf)); + i=snprintf(buf2, 256, "%.9999u", 10); + printf("%i %i\n",i,strlen(buf2)); + + printf ("snprintf (\"%%.999999u\", 10) == %d\n", + snprintf(buf2, sizeof(buf2), "%.999999u", 10)); + } + return 0; +} + +void libc_printf() +{ + printf("stdout test!!\n"); + fprintf(stdout, "fprintf test!!\n"); + fprintf(stderr, "fprintf test!!\n"); + puts("puts test!!\n"); + + putc('1', stderr); + putc('2', stderr); + putc('\n', stderr); + + printf_test(); +} +FINSH_FUNCTION_EXPORT(libc_printf, printf test in libc); + + +void libc_dprintf() +{ + int fd; + + fd = open("/dev/console", O_WRONLY, 0); + if (fd >0) + { + dprintf(fd, "fd:%d printf test!!\n", fd); + close(fd); + } +} +FINSH_FUNCTION_EXPORT(libc_dprintf, dprintf test); + + +void libc_fdopen() +{ + int fd; + FILE* fp; + + fd = open("/dev/console", O_WRONLY, 0); + if (fd >0) + { + fp = fdopen(fd, "w"); + fprintf(fp, "fdopen test, fd %d!!\n", fileno(fp)); + fclose(fp); + } +} +FINSH_FUNCTION_EXPORT(libc_fdopen, fdopen test); diff --git a/examples/libc/rand.c b/examples/libc/rand.c index ca74353adc..8f52ad28bb 100644 --- a/examples/libc/rand.c +++ b/examples/libc/rand.c @@ -1,43 +1,43 @@ -/* - * rand.c - * - * Created on: 2010-11-17 - * Author: bernard - */ -#include -#include -#include - -int libc_rand(void) -{ - int i1, i2; - int j1, j2; - - /* The C standard says that "If rand is called before any calls to - srand have been made, the same sequence shall be generated as - when srand is first called with a seed value of 1." */ - i1 = rand(); - i2 = rand(); - srand(1); - j1 = rand(); - j2 = rand(); - if (i1 < 0 || i2 < 0 || j1 < 0 || j2 < 0) - { - puts("Test FAILED!"); - } - if (j1 == i1 && j2 == i2) - { - puts("Test succeeded."); - return 0; - } - else - { - if (j1 != i1) - printf("%d != %d\n", j1, i1); - if (j2 != i2) - printf("%d != %d\n", j2, i2); - puts("Test FAILED!"); - return 1; - } -} -FINSH_FUNCTION_EXPORT(libc_rand, rand test for libc); +/* + * rand.c + * + * Created on: 2010-11-17 + * Author: bernard + */ +#include +#include +#include + +int libc_rand(void) +{ + int i1, i2; + int j1, j2; + + /* The C standard says that "If rand is called before any calls to + srand have been made, the same sequence shall be generated as + when srand is first called with a seed value of 1." */ + i1 = rand(); + i2 = rand(); + srand(1); + j1 = rand(); + j2 = rand(); + if (i1 < 0 || i2 < 0 || j1 < 0 || j2 < 0) + { + puts("Test FAILED!"); + } + if (j1 == i1 && j2 == i2) + { + puts("Test succeeded."); + return 0; + } + else + { + if (j1 != i1) + printf("%d != %d\n", j1, i1); + if (j2 != i2) + printf("%d != %d\n", j2, i2); + puts("Test FAILED!"); + return 1; + } +} +FINSH_FUNCTION_EXPORT(libc_rand, rand test for libc); diff --git a/examples/libc/sem.c b/examples/libc/sem.c index 9686119059..d081d246e9 100644 --- a/examples/libc/sem.c +++ b/examples/libc/sem.c @@ -1,65 +1,65 @@ -#include -#include -#include - -static sem_t sema; -static void* other_thread() -{ - printf("other_thread here!\n"); - - sleep(1); - - while (1) - { - printf("other_thread: sem_post...\n"); - if(sem_post(&sema) == -1) - printf("sem_post failed\n"); - sleep(1); - } - - printf("other_thread dies!\n"); - pthread_exit(0); -} - -static void test_thread(void* parameter) -{ - pthread_t tid; - - printf("main thread here!\n"); - printf("sleep 5 seconds..."); - sleep(5); - printf("done\n"); - - sem_init(&sema, 0, 0); - - /* create the "other" thread */ - if(pthread_create(&tid, 0, &other_thread, 0)!=0) - /* error */ - printf("pthread_create OtherThread failed.\n"); - else - printf("created OtherThread=%x\n", tid); - - /* let the other thread run */ - while (1) - { - printf("Main: sem_wait...\n"); - if(sem_wait(&sema) == -1) - printf("sem_wait failed\n"); - printf("Main back.\n\n"); - } - - pthread_exit(0); -} -#include -void libc_sem() -{ - rt_thread_t tid; - - tid = rt_thread_create("semtest", test_thread, RT_NULL, - 2048, 20, 5); - if (tid != RT_NULL) - { - rt_thread_startup(tid); - } -} -FINSH_FUNCTION_EXPORT(libc_sem, posix semaphore test); +#include +#include +#include + +static sem_t sema; +static void* other_thread() +{ + printf("other_thread here!\n"); + + sleep(1); + + while (1) + { + printf("other_thread: sem_post...\n"); + if(sem_post(&sema) == -1) + printf("sem_post failed\n"); + sleep(1); + } + + printf("other_thread dies!\n"); + pthread_exit(0); +} + +static void test_thread(void* parameter) +{ + pthread_t tid; + + printf("main thread here!\n"); + printf("sleep 5 seconds..."); + sleep(5); + printf("done\n"); + + sem_init(&sema, 0, 0); + + /* create the "other" thread */ + if(pthread_create(&tid, 0, &other_thread, 0)!=0) + /* error */ + printf("pthread_create OtherThread failed.\n"); + else + printf("created OtherThread=%x\n", tid); + + /* let the other thread run */ + while (1) + { + printf("Main: sem_wait...\n"); + if(sem_wait(&sema) == -1) + printf("sem_wait failed\n"); + printf("Main back.\n\n"); + } + + pthread_exit(0); +} +#include +void libc_sem() +{ + rt_thread_t tid; + + tid = rt_thread_create("semtest", test_thread, RT_NULL, + 2048, 20, 5); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } +} +FINSH_FUNCTION_EXPORT(libc_sem, posix semaphore test); diff --git a/examples/libc/time.c b/examples/libc/time.c index cbe5773ec0..fa6dee74c8 100644 --- a/examples/libc/time.c +++ b/examples/libc/time.c @@ -1,24 +1,24 @@ -/* - * time.c - * - * Created on: 2010-11-17 - * Author: bernard - */ - -#include -#include -#include - -int speed() -{ - int i; - time_t t; - - printf("%d\n", time(0)); - for (i = 0; i < 10000000; ++i) - t = time(0); - - printf("%d\n", time(0)); - return 0; -} -FINSH_FUNCTION_EXPORT(speed, speed test); +/* + * time.c + * + * Created on: 2010-11-17 + * Author: bernard + */ + +#include +#include +#include + +int speed() +{ + int i; + time_t t; + + printf("%d\n", time(0)); + for (i = 0; i < 10000000; ++i) + t = time(0); + + printf("%d\n", time(0)); + return 0; +} +FINSH_FUNCTION_EXPORT(speed, speed test); diff --git a/examples/module/README b/examples/module/README index d5990192ce..b862667bf2 100644 --- a/examples/module/README +++ b/examples/module/README @@ -1,4 +1,4 @@ -example: -1.edit rtconfig.py to config toolchain and bsp -2.scons --app=basicapp -3.copy basicapp/build/$bsp/basicapp.so to filesystem +example: +1.edit rtconfig.py to config toolchain and bsp +2.scons --app=basicapp +3.copy basicapp/build/$bsp/basicapp.so to filesystem diff --git a/examples/module/SConstruct b/examples/module/SConstruct index 47bff46f1c..d11d1b6128 100644 --- a/examples/module/SConstruct +++ b/examples/module/SConstruct @@ -1,73 +1,73 @@ -import os -import sys -import SCons.cpp -import rtconfig - -if os.getenv('RTT_ROOT'): - RTT_ROOT = os.getenv('RTT_ROOT') -else: - RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') - -sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] -from building import * - -Export('RTT_ROOT') - -# add target option -AddOption('--app', - dest='app', - nargs=1, type='string', - action='store', - metavar='DIR', - help='installation prefix') - -# add target option -AddOption('--type', - dest='type', - nargs=1, type='string', - action='store', - metavar='DIR', - help='installation prefix') - -app = GetOption('app') - -if GetOption('type') == 'ext': - linkflags = rtconfig.LFLAGS + ' -e 0' -else: - linkflags = rtconfig.LFLAGS + ' -e main' - -env = Environment(tools = ['mingw'], - AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, - CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, - CXX = rtconfig.CXX, - AR = rtconfig.AR, ARFLAGS = '-rc', - LINK = rtconfig.LINK, LINKFLAGS = linkflags, - CPPPATH = [ - RTT_ROOT + '/include', - RTT_ROOT + '/bsp/' + rtconfig.BSP, - RTT_ROOT + '/components/finsh', - RTT_ROOT + '/components/rtgui/include', - RTT_ROOT + '/components/rgtui/common', - RTT_ROOT + '/components/rtgui/server', - RTT_ROOT + '/components/rtgui/widgets', - RTT_ROOT + '/components/libdl', - RTT_ROOT + '/components/external/ftk/ftk/src/os/rt-thread', - RTT_ROOT + '/components/external/ftk/ftk/src/demos', - RTT_ROOT + '/components/external/ftk/ftk/apps/common', - RTT_ROOT + '/components/external/ftk/ftk/src', - RTT_ROOT + '/components/dfs', - RTT_ROOT + '/components/dfs/include', - RTT_ROOT + '/components/libc/newlib', - RTT_ROOT + '/components/external/cairo/cairo-1.10.2/src', - RTT_ROOT + '/components/external/cairo/' - ]) -env.PrependENVPath('PATH', rtconfig.EXEC_PATH) - -PrepareModuleBuilding(env, RTT_ROOT) - -dir = app + '/build/' + rtconfig.BSP -objs = SConscript(app + '/Sconscript', variant_dir=dir, duplicate=0) -TARGET = dir + '/' + app + '.' + rtconfig.TARGET_EXT - -# build program -env.Program(TARGET, objs) +import os +import sys +import SCons.cpp +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +Export('RTT_ROOT') + +# add target option +AddOption('--app', + dest='app', + nargs=1, type='string', + action='store', + metavar='DIR', + help='installation prefix') + +# add target option +AddOption('--type', + dest='type', + nargs=1, type='string', + action='store', + metavar='DIR', + help='installation prefix') + +app = GetOption('app') + +if GetOption('type') == 'ext': + linkflags = rtconfig.LFLAGS + ' -e 0' +else: + linkflags = rtconfig.LFLAGS + ' -e main' + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = linkflags, + CPPPATH = [ + RTT_ROOT + '/include', + RTT_ROOT + '/bsp/' + rtconfig.BSP, + RTT_ROOT + '/components/finsh', + RTT_ROOT + '/components/rtgui/include', + RTT_ROOT + '/components/rgtui/common', + RTT_ROOT + '/components/rtgui/server', + RTT_ROOT + '/components/rtgui/widgets', + RTT_ROOT + '/components/libdl', + RTT_ROOT + '/components/external/ftk/ftk/src/os/rt-thread', + RTT_ROOT + '/components/external/ftk/ftk/src/demos', + RTT_ROOT + '/components/external/ftk/ftk/apps/common', + RTT_ROOT + '/components/external/ftk/ftk/src', + RTT_ROOT + '/components/dfs', + RTT_ROOT + '/components/dfs/include', + RTT_ROOT + '/components/libc/newlib', + RTT_ROOT + '/components/external/cairo/cairo-1.10.2/src', + RTT_ROOT + '/components/external/cairo/' + ]) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +PrepareModuleBuilding(env, RTT_ROOT) + +dir = app + '/build/' + rtconfig.BSP +objs = SConscript(app + '/Sconscript', variant_dir=dir, duplicate=0) +TARGET = dir + '/' + app + '.' + rtconfig.TARGET_EXT + +# build program +env.Program(TARGET, objs) diff --git a/examples/module/basicapp/Sconscript b/examples/module/basicapp/Sconscript index 690ae8c7dd..d8dd99964e 100644 --- a/examples/module/basicapp/Sconscript +++ b/examples/module/basicapp/Sconscript @@ -1,7 +1,7 @@ -import rtconfig -Import('RTT_ROOT') -from building import * - -src = Glob('*.c') -group = DefineGroup('', src, depend = ['']) +import rtconfig +Import('RTT_ROOT') +from building import * + +src = Glob('*.c') +group = DefineGroup('', src, depend = ['']) Return('group') \ No newline at end of file diff --git a/examples/module/extapp/Sconscript b/examples/module/extapp/Sconscript index 690ae8c7dd..d8dd99964e 100644 --- a/examples/module/extapp/Sconscript +++ b/examples/module/extapp/Sconscript @@ -1,7 +1,7 @@ -import rtconfig -Import('RTT_ROOT') -from building import * - -src = Glob('*.c') -group = DefineGroup('', src, depend = ['']) +import rtconfig +Import('RTT_ROOT') +from building import * + +src = Glob('*.c') +group = DefineGroup('', src, depend = ['']) Return('group') \ No newline at end of file diff --git a/examples/module/rtconfig.py b/examples/module/rtconfig.py index 00163c4e85..70ecf91e1f 100644 --- a/examples/module/rtconfig.py +++ b/examples/module/rtconfig.py @@ -1,23 +1,23 @@ -# bsp name -BSP = 'mini2440' - -# toolchains -EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin' -PREFIX = 'arm-none-eabi-' -CC = PREFIX + 'gcc' -CXX = PREFIX + 'g++' -AS = PREFIX + 'gcc' -AR = PREFIX + 'ar' -LINK = PREFIX + 'gcc' -TARGET_EXT = 'so' -SIZE = PREFIX + 'size' -OBJDUMP = PREFIX + 'objdump' -OBJCPY = PREFIX + 'objcopy' - -DEVICE = ' -mcpu=arm920t' -CFLAGS = DEVICE + ' -O0 -fPIC -DFTK_AS_PLUGIN -DRT_THREAD ' -AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' -LFLAGS = DEVICE + ' -Wl,-z,max-page-size=0x4 -shared -fPIC -nostdlib -s' - -CPATH = '' -LPATH = '' +# bsp name +BSP = 'mini2440' + +# toolchains +EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin' +PREFIX = 'arm-none-eabi-' +CC = PREFIX + 'gcc' +CXX = PREFIX + 'g++' +AS = PREFIX + 'gcc' +AR = PREFIX + 'ar' +LINK = PREFIX + 'gcc' +TARGET_EXT = 'so' +SIZE = PREFIX + 'size' +OBJDUMP = PREFIX + 'objdump' +OBJCPY = PREFIX + 'objcopy' + +DEVICE = ' -mcpu=arm920t' +CFLAGS = DEVICE + ' -O0 -fPIC -DFTK_AS_PLUGIN -DRT_THREAD ' +AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' +LFLAGS = DEVICE + ' -Wl,-z,max-page-size=0x4 -shared -fPIC -nostdlib -s' + +CPATH = '' +LPATH = '' diff --git a/examples/module/rtconfig_lm3s.py b/examples/module/rtconfig_lm3s.py index 0f81c67a48..a0d350c5b1 100644 --- a/examples/module/rtconfig_lm3s.py +++ b/examples/module/rtconfig_lm3s.py @@ -1,23 +1,23 @@ -# bsp name -BSP = 'lm3s8962' - -# toolchains -EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin' -PREFIX = 'arm-none-eabi-' -CC = PREFIX + 'gcc' -CXX = PREFIX + 'g++' -AS = PREFIX + 'gcc' -AR = PREFIX + 'ar' -LINK = PREFIX + 'gcc' -TARGET_EXT = 'so' -SIZE = PREFIX + 'size' -OBJDUMP = PREFIX + 'objdump' -OBJCPY = PREFIX + 'objcopy' - -DEVICE = ' -mcpu=cortex-m3' -CFLAGS = DEVICE + ' -mthumb -mlong-calls -Dsourcerygxx -O0 -fPIC' -AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' -LFLAGS = DEVICE + ' -mthumb -Wl,-z,max-page-size=0x4 -shared -fPIC -e main -nostdlib' - -CPATH = '' -LPATH = '' +# bsp name +BSP = 'lm3s8962' + +# toolchains +EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin' +PREFIX = 'arm-none-eabi-' +CC = PREFIX + 'gcc' +CXX = PREFIX + 'g++' +AS = PREFIX + 'gcc' +AR = PREFIX + 'ar' +LINK = PREFIX + 'gcc' +TARGET_EXT = 'so' +SIZE = PREFIX + 'size' +OBJDUMP = PREFIX + 'objdump' +OBJCPY = PREFIX + 'objcopy' + +DEVICE = ' -mcpu=cortex-m3' +CFLAGS = DEVICE + ' -mthumb -mlong-calls -Dsourcerygxx -O0 -fPIC' +AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' +LFLAGS = DEVICE + ' -mthumb -Wl,-z,max-page-size=0x4 -shared -fPIC -e main -nostdlib' + +CPATH = '' +LPATH = '' diff --git a/examples/module/tetris/Sconscript b/examples/module/tetris/Sconscript index 690ae8c7dd..d8dd99964e 100644 --- a/examples/module/tetris/Sconscript +++ b/examples/module/tetris/Sconscript @@ -1,7 +1,7 @@ -import rtconfig -Import('RTT_ROOT') -from building import * - -src = Glob('*.c') -group = DefineGroup('', src, depend = ['']) +import rtconfig +Import('RTT_ROOT') +from building import * + +src = Glob('*.c') +group = DefineGroup('', src, depend = ['']) Return('group') \ No newline at end of file diff --git a/examples/module/tetris/tetris.h b/examples/module/tetris/tetris.h index b5ef13785f..5be429cf72 100644 --- a/examples/module/tetris/tetris.h +++ b/examples/module/tetris/tetris.h @@ -1,61 +1,61 @@ -/* - * File : tetris_modal.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-08-14 Yi.Qiu first version - */ - - #include - - struct rt_tetris; - typedef struct rt_tetris rt_tetris_t; - - struct rt_tetris_view; - typedef struct rt_tetris_view rt_tetris_view_t; - - typedef rt_err_t (*on_update)(rt_tetris_view_t* thiz, rt_tetris_t* tetris); - - struct rt_tetris_view - { - rt_uint32_t width; - rt_uint32_t height; - - on_update update; - on_update update_next_brick; - on_update update_level; - on_update update_score_and_lines; - void *private; - }; - - rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height); - rt_err_t rt_tetris_destory(rt_tetris_t* thiz); - rt_err_t rt_tetris_start(rt_tetris_t* thiz); - rt_err_t rt_tetris_pause(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_width(rt_tetris_t* thiz); - rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_level(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_score(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_height(rt_tetris_t* thiz); - rt_bool_t rt_tetris_status(rt_tetris_t* thiz); - rt_err_t rt_tetris_down(rt_tetris_t* thiz); - rt_err_t rt_tetris_left(rt_tetris_t* thiz); - rt_err_t rt_tetris_right(rt_tetris_t* thiz); - rt_err_t rt_tetris_drop(rt_tetris_t* thiz); - rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction); - rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view); - rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view); - rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block); - - rt_tetris_view_t* rt_tetris_view_create(void* private); - rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz); - -void tetris_ui_entry(void* parameter); - +/* + * File : tetris_modal.c + * This file is part of RTGUI in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-08-14 Yi.Qiu first version + */ + + #include + + struct rt_tetris; + typedef struct rt_tetris rt_tetris_t; + + struct rt_tetris_view; + typedef struct rt_tetris_view rt_tetris_view_t; + + typedef rt_err_t (*on_update)(rt_tetris_view_t* thiz, rt_tetris_t* tetris); + + struct rt_tetris_view + { + rt_uint32_t width; + rt_uint32_t height; + + on_update update; + on_update update_next_brick; + on_update update_level; + on_update update_score_and_lines; + void *private; + }; + + rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height); + rt_err_t rt_tetris_destory(rt_tetris_t* thiz); + rt_err_t rt_tetris_start(rt_tetris_t* thiz); + rt_err_t rt_tetris_pause(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_width(rt_tetris_t* thiz); + rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_level(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_score(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_height(rt_tetris_t* thiz); + rt_bool_t rt_tetris_status(rt_tetris_t* thiz); + rt_err_t rt_tetris_down(rt_tetris_t* thiz); + rt_err_t rt_tetris_left(rt_tetris_t* thiz); + rt_err_t rt_tetris_right(rt_tetris_t* thiz); + rt_err_t rt_tetris_drop(rt_tetris_t* thiz); + rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction); + rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view); + rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view); + rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block); + + rt_tetris_view_t* rt_tetris_view_create(void* private); + rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz); + +void tetris_ui_entry(void* parameter); + diff --git a/examples/module/tetris/tetris_modal.c b/examples/module/tetris/tetris_modal.c index 01b5850e96..d4532ed78d 100644 --- a/examples/module/tetris/tetris_modal.c +++ b/examples/module/tetris/tetris_modal.c @@ -1,730 +1,730 @@ -/* - * File : tetris_modal.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-08-14 Yi.Qiu first version - */ - -#include -#include -#include "tetris.h" - -struct rt_tetris -{ - rt_uint32_t width; /* the width of the tetris */ - rt_uint32_t height; /* the height of the tetris */ - rt_uint16_t* panel; /* the panel of the tetris */ - rt_uint32_t* brick; /* the current brick of the tetris */ - rt_uint32_t* next_brick; /* the next brick of the tetris */ - rt_tetris_view_t* view; /* the view on which the tetris show */ - rt_uint32_t level; /* game level */ - rt_uint32_t lines; /* released lines count */ - rt_uint32_t score; /* total scores statistic */ - rt_bool_t status; /* game status, pause or runing */ -}; - -static const rt_uint32_t g_brick[][4] = -{ - {23,7,8,22}, - {23,7,8,24}, - {24,7,8,25}, - {8,7,9,23}, - {8,7,9,24}, - {8,7,9,25}, - {7,6,8,9}, -}; - -static rt_err_t rt_tetris_append_brick(rt_tetris_t* thiz, rt_uint32_t brick[]); -static rt_err_t rt_tetris_delete_brick(rt_tetris_t* thiz, rt_uint32_t brick[]); -static rt_err_t rt_tetris_release_lines(rt_tetris_t* thiz, rt_uint32_t brick[]); -static rt_err_t rt_tetris_is_reach_top(rt_tetris_t* thiz, rt_uint32_t brick[]); -static rt_err_t rt_tetris_update_brick(rt_tetris_t* thiz); - -/** - * this function create a tetris instance - * - * @param width the width of tetris. - * @param height the height of tetris. - * - * @return the tetris instance - */ -rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height) -{ - int index; - - rt_tetris_t* thiz = (rt_tetris_t*)rt_malloc(sizeof(rt_tetris_t)); - RT_ASSERT(thiz != RT_NULL); - - thiz->height = height; - thiz->width = width; - thiz->panel = rt_malloc(thiz->height * sizeof(rt_uint32_t)); - rt_memset(thiz->panel, 0, thiz->height * sizeof(rt_uint32_t)); - - thiz->brick = (rt_uint32_t*)rt_malloc(4 * sizeof(rt_uint32_t)); - index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); - rt_memcpy(thiz->brick, g_brick[index], 4 * sizeof(rt_uint32_t)); - - thiz->next_brick= (rt_uint32_t*)rt_malloc(4 * sizeof(rt_uint32_t)); - index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); - rt_memcpy(thiz->next_brick, g_brick[index], 4 * sizeof(rt_uint32_t)); - - thiz->view = RT_NULL; - thiz->level = 0; - thiz->lines = 0; - thiz->score = 0; - thiz->status = RT_FALSE; - - return thiz; -} - -/** - * this function destory a tetris instance - * - * @param thiz the tetris instance. - * - * @return RT_EOK - */ -rt_err_t rt_tetris_destory(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz->panel && thiz->brick && thiz->next_brick); - - rt_free(thiz->panel); - rt_free(thiz->brick); - rt_free(thiz->next_brick); - rt_free(thiz); - - return RT_EOK; -} - -/** - * this function start tetris game - * - * @param thiz the tetris instance. - * - * @return RT_EOK - */ -rt_err_t rt_tetris_start(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - /* update next brick on view */ - thiz->view->update_next_brick(thiz->view, thiz); - - /* update level */ - thiz->view->update_level(thiz->view, thiz); - - /* update lines and score */ - thiz->view->update_score_and_lines(thiz->view, thiz); - - thiz->status = RT_TRUE; - - return RT_EOK; -} - -/** - * this function pause tetris game - * - * @param thiz the tetris instance. - * - * @return RT_EOK - */ -rt_err_t rt_tetris_pause(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - thiz->status = RT_FALSE; - - return RT_EOK; -} - -/** - * this function get width of a tetris instance - * - * @param thiz the tetris instance. - * - * @return the width of the tetris instance - */ -rt_uint32_t rt_tetris_width(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->width; -} - -/** - * this function get next brick of a tetris instance - * - * @param thiz the tetris instance. - * - * @return the next brick of the tetris instance - */ -rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->next_brick; -} - -/** - * this function get level of the tetris instance - * - * @param thiz the tetris instance. - * - * @return the level of the tetris instance - */ -rt_uint32_t rt_tetris_level(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->level; -} - -/** - * this function get released lines of the tetris instance - * - * @param thiz the tetris instance. - * - * @return the released lines of the tetris instance - */ -rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->lines; -} - -/** - * this function get score of the tetris instance - * - * @param thiz the tetris instance. - * - * @return the score of the tetris instance - */ -rt_uint32_t rt_tetris_score(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->score; -} - -/** - * this function get height of a tetris instance - * - * @param thiz the tetris instance. - * - * @return the height of the tetris instance - */ -rt_uint32_t rt_tetris_height(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->height; -} - -/** - * this function get status of a tetris instance - * - * @param thiz the tetris instance. - * - * @return the status of the tetris instance - */ -rt_bool_t rt_tetris_status(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->status; -} - -/** - * this function makes current brick move down - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_down(rt_tetris_t* thiz) -{ - int i; - - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ERROR; - - /* delete the brick from tetris panel */ - rt_tetris_delete_brick(thiz, thiz->brick); - - for(i=0; i<4; i++) - { - /* check collision and bottom*/ - if((thiz->brick[i] >= thiz->width * (thiz->height - 1)) - || rt_tetris_check_collision(thiz, thiz->brick[i] + thiz->width) == RT_EOK) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - - if(rt_tetris_is_reach_top(thiz, thiz->brick) == RT_EOK) - { - rt_memset(thiz->panel, 0xff, thiz->height * sizeof(rt_uint32_t)); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - /* game over */ - return -RT_ETIMEOUT; - } - - if(rt_tetris_release_lines(thiz, thiz->brick) == RT_EOK) - { - /* update view */ - thiz->view->update(thiz->view, thiz); - } - - rt_tetris_update_brick(thiz); - return -RT_ERROR; - } - } - - for(i=0; i<4; i++) - { - /* increase one line */ - thiz->brick[i] += thiz->width; - } - - /* append the brick to tetris panel */ - rt_tetris_append_brick(thiz, thiz->brick); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - return RT_EOK; -} - -/** - * this function makes current brick move left - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_left(rt_tetris_t* thiz) -{ - int i; - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ERROR; - - /* delete the brick from tetris panel */ - rt_tetris_delete_brick(thiz, thiz->brick); - - for(i=0; i<4; i++) - { - /* check left board */ - if((thiz->brick[i] % thiz->width) == 0) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - - if(rt_tetris_check_collision(thiz, thiz->brick[i] - 1) == RT_EOK) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - } - - for(i=0; i<4; i++) - { - /* move one step to left */ - thiz->brick[i] --;; - } - - /* append the brick to tetris panel */ - rt_tetris_append_brick(thiz, thiz->brick); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - return RT_EOK; -} - -/** - * this function makes current brick move right - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_right(rt_tetris_t* thiz) -{ - int i; - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ERROR; - - /* delete the brick from tetris panel */ - rt_tetris_delete_brick(thiz, thiz->brick); - - for(i=0; i<4; i++) - { - /* check left board */ - if(((thiz->brick[i] + 1) % thiz->width) == 0) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - - /* check collision */ - if(rt_tetris_check_collision(thiz, thiz->brick[i] + 1) == RT_EOK) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - } - - for(i=0; i<4; i++) - { - /* move one step to right */ - thiz->brick[i] ++;; - } - - /* append the brick to tetris panel */ - rt_tetris_append_brick(thiz, thiz->brick); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - return RT_EOK; -} - -/** - * this function makes current brick drop quickly - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_drop(rt_tetris_t* thiz) -{ - rt_err_t ret; - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ETIMEOUT; - - /* move down until blocked */ - while((ret = rt_tetris_down(thiz)) == RT_EOK); - - return ret; -} - -/** - * this function makes current brick do rotation - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction) -{ - int i; - rt_uint32_t tmp[4]; - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ERROR; - - rt_tetris_delete_brick(thiz, thiz->brick); - - tmp[0] = thiz->brick[0]; - for(i=1; i<4; i++) - { - int diff = thiz->brick[0] - thiz->brick[i]; - if(diff == 1) - { - tmp[i] = thiz->brick[0] - thiz->width; - } - else if(diff == -1) - { - tmp[i] = thiz->brick[0] + thiz->width; - } - else if(diff == 2) - { - tmp[i] = thiz->brick[0] - 2 * thiz->width; - } - else if(diff == -2) - { - tmp[i] = thiz->brick[0] + 2 * thiz->width; - } - else if(diff == thiz->width - 1) - { - tmp[i] = thiz->brick[0] + thiz->width + 1; - } - else if(diff == 1 - thiz->width) - { - tmp[i] = thiz->brick[0] - thiz->width - 1; - } - else if(diff == thiz->width) - { - if((thiz->brick[0] + 1) % thiz->width == 0) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - else tmp[i] = thiz->brick[0] + 1; - } - else if(diff == -1 * (thiz->width)) - { - if(thiz->brick[0] % thiz->width == 0) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - else tmp[i] = thiz->brick[0] - 1; - } - else if(diff == thiz->width + 1) - { - tmp[i] = thiz->brick[0] - thiz->width + 1; - } - else if(diff == -1 - thiz->width) - { - tmp[i] = thiz->brick[0] + thiz->width - 1; - } - else if(diff == 2 * thiz->width) - { - if((thiz->brick[0] % thiz->width) >= (thiz->width - 2)) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - else tmp[i] = thiz->brick[0] + 2; - } - else if(diff == -2 * thiz->width) - { - if((thiz->brick[0] % thiz->width) < 2) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - else tmp[i] = thiz->brick[0] - 2; - } - - if(tmp[i] > (thiz->height) * thiz->width) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - - if(rt_tetris_check_collision(thiz, tmp[i]) == RT_EOK) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - } - - /* do roration */ - for(i=0; i<4; i++) - { - thiz->brick[i] = tmp[i]; - } - - /* append the brick to tetris panel */ - rt_tetris_append_brick(thiz, thiz->brick); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - return RT_EOK; -} - -/** - * this function add a view to the tetris - * - * @param thiz the tetris instance. - * @param view the view instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view) -{ - RT_ASSERT(thiz != RT_NULL); - - /* Only suppurt single view now */ - thiz->view = view; - - return RT_EOK; -} - -/** - * this function delete a view from the tetris - * - * @param thiz the tetris instance. - * @param view the view instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ - -rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view) -{ - RT_ASSERT(thiz != RT_NULL); - - thiz->view = RT_NULL; - - return RT_EOK; -} - -/** - * this function used to check collision - * - * @param thiz the tetris instance. - * @param block the block to be checked. - * - * @return RT_EOK on collision, -RT_ERROR on not collision - */ -rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block) -{ - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(block < thiz->height * thiz->width); - - if((thiz->panel[block/thiz->width] & (1 << (block % thiz->width))) - == (1 << (block % thiz->width))) - { - return RT_EOK; - } - else - { - return -RT_ERROR; - } -} - -static rt_err_t rt_tetris_update_brick(rt_tetris_t* thiz) -{ - int index; - - RT_ASSERT(thiz != RT_NULL); - - index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); - - rt_memcpy(thiz->brick, thiz->next_brick, 4 * sizeof(rt_uint32_t)); - rt_memcpy(thiz->next_brick, g_brick[index], 4 * sizeof(rt_uint32_t)); - - /* update next brick on view */ - thiz->view->update_next_brick(thiz->view, thiz); - - return RT_EOK; -} - -static rt_err_t rt_tetris_append_brick(rt_tetris_t* thiz, rt_uint32_t brick[]) -{ - int i; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(brick != RT_NULL); - - for(i=0; i<4; i++) - { - int y = brick[i]/thiz->width; - int x = brick[i]%thiz->width; - - thiz->panel[y] |= (1<width; - int x = brick[i]%thiz->width; - - thiz->panel[y] &= ~(1<width == 0) - return RT_EOK; - } - - return -RT_ERROR; -} - -static rt_err_t rt_tetris_release_lines(rt_tetris_t* thiz, rt_uint32_t brick[]) -{ - int i, j, check_line = 0; - rt_bool_t line_released = -RT_ERROR; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(brick != RT_NULL); - - for(i=0; i<4; i++) - { - /* choose a line */ - check_line = brick[i]/thiz->width; - if((thiz->panel[check_line]) == ((1 << thiz->width) - 1)) - { - for(j=check_line; j>0; j--) - { - thiz->panel[j] = thiz->panel[j-1]; - } - - /* clear the first line */ - thiz->panel[0] = 0; - - for(j=i+1; j<4; j++) - { - if(brick[j] < brick[i]) - { - brick[j] += thiz->width; - } - } - - thiz->lines++; - thiz->score += 100; - line_released = RT_EOK; - } - } - - if(line_released == RT_EOK) - { - /* update view */ - thiz->view->update_score_and_lines(thiz->view, thiz); - return RT_EOK; - } - else - { - return -RT_ERROR; - } -} - +/* + * File : tetris_modal.c + * This file is part of RTGUI in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-08-14 Yi.Qiu first version + */ + +#include +#include +#include "tetris.h" + +struct rt_tetris +{ + rt_uint32_t width; /* the width of the tetris */ + rt_uint32_t height; /* the height of the tetris */ + rt_uint16_t* panel; /* the panel of the tetris */ + rt_uint32_t* brick; /* the current brick of the tetris */ + rt_uint32_t* next_brick; /* the next brick of the tetris */ + rt_tetris_view_t* view; /* the view on which the tetris show */ + rt_uint32_t level; /* game level */ + rt_uint32_t lines; /* released lines count */ + rt_uint32_t score; /* total scores statistic */ + rt_bool_t status; /* game status, pause or runing */ +}; + +static const rt_uint32_t g_brick[][4] = +{ + {23,7,8,22}, + {23,7,8,24}, + {24,7,8,25}, + {8,7,9,23}, + {8,7,9,24}, + {8,7,9,25}, + {7,6,8,9}, +}; + +static rt_err_t rt_tetris_append_brick(rt_tetris_t* thiz, rt_uint32_t brick[]); +static rt_err_t rt_tetris_delete_brick(rt_tetris_t* thiz, rt_uint32_t brick[]); +static rt_err_t rt_tetris_release_lines(rt_tetris_t* thiz, rt_uint32_t brick[]); +static rt_err_t rt_tetris_is_reach_top(rt_tetris_t* thiz, rt_uint32_t brick[]); +static rt_err_t rt_tetris_update_brick(rt_tetris_t* thiz); + +/** + * this function create a tetris instance + * + * @param width the width of tetris. + * @param height the height of tetris. + * + * @return the tetris instance + */ +rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height) +{ + int index; + + rt_tetris_t* thiz = (rt_tetris_t*)rt_malloc(sizeof(rt_tetris_t)); + RT_ASSERT(thiz != RT_NULL); + + thiz->height = height; + thiz->width = width; + thiz->panel = rt_malloc(thiz->height * sizeof(rt_uint32_t)); + rt_memset(thiz->panel, 0, thiz->height * sizeof(rt_uint32_t)); + + thiz->brick = (rt_uint32_t*)rt_malloc(4 * sizeof(rt_uint32_t)); + index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); + rt_memcpy(thiz->brick, g_brick[index], 4 * sizeof(rt_uint32_t)); + + thiz->next_brick= (rt_uint32_t*)rt_malloc(4 * sizeof(rt_uint32_t)); + index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); + rt_memcpy(thiz->next_brick, g_brick[index], 4 * sizeof(rt_uint32_t)); + + thiz->view = RT_NULL; + thiz->level = 0; + thiz->lines = 0; + thiz->score = 0; + thiz->status = RT_FALSE; + + return thiz; +} + +/** + * this function destory a tetris instance + * + * @param thiz the tetris instance. + * + * @return RT_EOK + */ +rt_err_t rt_tetris_destory(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz->panel && thiz->brick && thiz->next_brick); + + rt_free(thiz->panel); + rt_free(thiz->brick); + rt_free(thiz->next_brick); + rt_free(thiz); + + return RT_EOK; +} + +/** + * this function start tetris game + * + * @param thiz the tetris instance. + * + * @return RT_EOK + */ +rt_err_t rt_tetris_start(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + /* update next brick on view */ + thiz->view->update_next_brick(thiz->view, thiz); + + /* update level */ + thiz->view->update_level(thiz->view, thiz); + + /* update lines and score */ + thiz->view->update_score_and_lines(thiz->view, thiz); + + thiz->status = RT_TRUE; + + return RT_EOK; +} + +/** + * this function pause tetris game + * + * @param thiz the tetris instance. + * + * @return RT_EOK + */ +rt_err_t rt_tetris_pause(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + thiz->status = RT_FALSE; + + return RT_EOK; +} + +/** + * this function get width of a tetris instance + * + * @param thiz the tetris instance. + * + * @return the width of the tetris instance + */ +rt_uint32_t rt_tetris_width(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->width; +} + +/** + * this function get next brick of a tetris instance + * + * @param thiz the tetris instance. + * + * @return the next brick of the tetris instance + */ +rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->next_brick; +} + +/** + * this function get level of the tetris instance + * + * @param thiz the tetris instance. + * + * @return the level of the tetris instance + */ +rt_uint32_t rt_tetris_level(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->level; +} + +/** + * this function get released lines of the tetris instance + * + * @param thiz the tetris instance. + * + * @return the released lines of the tetris instance + */ +rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->lines; +} + +/** + * this function get score of the tetris instance + * + * @param thiz the tetris instance. + * + * @return the score of the tetris instance + */ +rt_uint32_t rt_tetris_score(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->score; +} + +/** + * this function get height of a tetris instance + * + * @param thiz the tetris instance. + * + * @return the height of the tetris instance + */ +rt_uint32_t rt_tetris_height(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->height; +} + +/** + * this function get status of a tetris instance + * + * @param thiz the tetris instance. + * + * @return the status of the tetris instance + */ +rt_bool_t rt_tetris_status(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->status; +} + +/** + * this function makes current brick move down + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_down(rt_tetris_t* thiz) +{ + int i; + + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ERROR; + + /* delete the brick from tetris panel */ + rt_tetris_delete_brick(thiz, thiz->brick); + + for(i=0; i<4; i++) + { + /* check collision and bottom*/ + if((thiz->brick[i] >= thiz->width * (thiz->height - 1)) + || rt_tetris_check_collision(thiz, thiz->brick[i] + thiz->width) == RT_EOK) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + + if(rt_tetris_is_reach_top(thiz, thiz->brick) == RT_EOK) + { + rt_memset(thiz->panel, 0xff, thiz->height * sizeof(rt_uint32_t)); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + /* game over */ + return -RT_ETIMEOUT; + } + + if(rt_tetris_release_lines(thiz, thiz->brick) == RT_EOK) + { + /* update view */ + thiz->view->update(thiz->view, thiz); + } + + rt_tetris_update_brick(thiz); + return -RT_ERROR; + } + } + + for(i=0; i<4; i++) + { + /* increase one line */ + thiz->brick[i] += thiz->width; + } + + /* append the brick to tetris panel */ + rt_tetris_append_brick(thiz, thiz->brick); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + return RT_EOK; +} + +/** + * this function makes current brick move left + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_left(rt_tetris_t* thiz) +{ + int i; + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ERROR; + + /* delete the brick from tetris panel */ + rt_tetris_delete_brick(thiz, thiz->brick); + + for(i=0; i<4; i++) + { + /* check left board */ + if((thiz->brick[i] % thiz->width) == 0) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + + if(rt_tetris_check_collision(thiz, thiz->brick[i] - 1) == RT_EOK) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + } + + for(i=0; i<4; i++) + { + /* move one step to left */ + thiz->brick[i] --;; + } + + /* append the brick to tetris panel */ + rt_tetris_append_brick(thiz, thiz->brick); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + return RT_EOK; +} + +/** + * this function makes current brick move right + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_right(rt_tetris_t* thiz) +{ + int i; + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ERROR; + + /* delete the brick from tetris panel */ + rt_tetris_delete_brick(thiz, thiz->brick); + + for(i=0; i<4; i++) + { + /* check left board */ + if(((thiz->brick[i] + 1) % thiz->width) == 0) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + + /* check collision */ + if(rt_tetris_check_collision(thiz, thiz->brick[i] + 1) == RT_EOK) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + } + + for(i=0; i<4; i++) + { + /* move one step to right */ + thiz->brick[i] ++;; + } + + /* append the brick to tetris panel */ + rt_tetris_append_brick(thiz, thiz->brick); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + return RT_EOK; +} + +/** + * this function makes current brick drop quickly + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_drop(rt_tetris_t* thiz) +{ + rt_err_t ret; + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ETIMEOUT; + + /* move down until blocked */ + while((ret = rt_tetris_down(thiz)) == RT_EOK); + + return ret; +} + +/** + * this function makes current brick do rotation + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction) +{ + int i; + rt_uint32_t tmp[4]; + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ERROR; + + rt_tetris_delete_brick(thiz, thiz->brick); + + tmp[0] = thiz->brick[0]; + for(i=1; i<4; i++) + { + int diff = thiz->brick[0] - thiz->brick[i]; + if(diff == 1) + { + tmp[i] = thiz->brick[0] - thiz->width; + } + else if(diff == -1) + { + tmp[i] = thiz->brick[0] + thiz->width; + } + else if(diff == 2) + { + tmp[i] = thiz->brick[0] - 2 * thiz->width; + } + else if(diff == -2) + { + tmp[i] = thiz->brick[0] + 2 * thiz->width; + } + else if(diff == thiz->width - 1) + { + tmp[i] = thiz->brick[0] + thiz->width + 1; + } + else if(diff == 1 - thiz->width) + { + tmp[i] = thiz->brick[0] - thiz->width - 1; + } + else if(diff == thiz->width) + { + if((thiz->brick[0] + 1) % thiz->width == 0) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + else tmp[i] = thiz->brick[0] + 1; + } + else if(diff == -1 * (thiz->width)) + { + if(thiz->brick[0] % thiz->width == 0) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + else tmp[i] = thiz->brick[0] - 1; + } + else if(diff == thiz->width + 1) + { + tmp[i] = thiz->brick[0] - thiz->width + 1; + } + else if(diff == -1 - thiz->width) + { + tmp[i] = thiz->brick[0] + thiz->width - 1; + } + else if(diff == 2 * thiz->width) + { + if((thiz->brick[0] % thiz->width) >= (thiz->width - 2)) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + else tmp[i] = thiz->brick[0] + 2; + } + else if(diff == -2 * thiz->width) + { + if((thiz->brick[0] % thiz->width) < 2) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + else tmp[i] = thiz->brick[0] - 2; + } + + if(tmp[i] > (thiz->height) * thiz->width) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + + if(rt_tetris_check_collision(thiz, tmp[i]) == RT_EOK) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + } + + /* do roration */ + for(i=0; i<4; i++) + { + thiz->brick[i] = tmp[i]; + } + + /* append the brick to tetris panel */ + rt_tetris_append_brick(thiz, thiz->brick); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + return RT_EOK; +} + +/** + * this function add a view to the tetris + * + * @param thiz the tetris instance. + * @param view the view instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view) +{ + RT_ASSERT(thiz != RT_NULL); + + /* Only suppurt single view now */ + thiz->view = view; + + return RT_EOK; +} + +/** + * this function delete a view from the tetris + * + * @param thiz the tetris instance. + * @param view the view instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ + +rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view) +{ + RT_ASSERT(thiz != RT_NULL); + + thiz->view = RT_NULL; + + return RT_EOK; +} + +/** + * this function used to check collision + * + * @param thiz the tetris instance. + * @param block the block to be checked. + * + * @return RT_EOK on collision, -RT_ERROR on not collision + */ +rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block) +{ + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(block < thiz->height * thiz->width); + + if((thiz->panel[block/thiz->width] & (1 << (block % thiz->width))) + == (1 << (block % thiz->width))) + { + return RT_EOK; + } + else + { + return -RT_ERROR; + } +} + +static rt_err_t rt_tetris_update_brick(rt_tetris_t* thiz) +{ + int index; + + RT_ASSERT(thiz != RT_NULL); + + index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); + + rt_memcpy(thiz->brick, thiz->next_brick, 4 * sizeof(rt_uint32_t)); + rt_memcpy(thiz->next_brick, g_brick[index], 4 * sizeof(rt_uint32_t)); + + /* update next brick on view */ + thiz->view->update_next_brick(thiz->view, thiz); + + return RT_EOK; +} + +static rt_err_t rt_tetris_append_brick(rt_tetris_t* thiz, rt_uint32_t brick[]) +{ + int i; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(brick != RT_NULL); + + for(i=0; i<4; i++) + { + int y = brick[i]/thiz->width; + int x = brick[i]%thiz->width; + + thiz->panel[y] |= (1<width; + int x = brick[i]%thiz->width; + + thiz->panel[y] &= ~(1<width == 0) + return RT_EOK; + } + + return -RT_ERROR; +} + +static rt_err_t rt_tetris_release_lines(rt_tetris_t* thiz, rt_uint32_t brick[]) +{ + int i, j, check_line = 0; + rt_bool_t line_released = -RT_ERROR; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(brick != RT_NULL); + + for(i=0; i<4; i++) + { + /* choose a line */ + check_line = brick[i]/thiz->width; + if((thiz->panel[check_line]) == ((1 << thiz->width) - 1)) + { + for(j=check_line; j>0; j--) + { + thiz->panel[j] = thiz->panel[j-1]; + } + + /* clear the first line */ + thiz->panel[0] = 0; + + for(j=i+1; j<4; j++) + { + if(brick[j] < brick[i]) + { + brick[j] += thiz->width; + } + } + + thiz->lines++; + thiz->score += 100; + line_released = RT_EOK; + } + } + + if(line_released == RT_EOK) + { + /* update view */ + thiz->view->update_score_and_lines(thiz->view, thiz); + return RT_EOK; + } + else + { + return -RT_ERROR; + } +} + diff --git a/examples/module/tetris/tetris_ui.c b/examples/module/tetris/tetris_ui.c index 86bb7f3b3a..f5b64ab9fa 100644 --- a/examples/module/tetris/tetris_ui.c +++ b/examples/module/tetris/tetris_ui.c @@ -1,239 +1,239 @@ -/* - * File : tetris_ui.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-08-14 Yi.Qiu first version - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tetris.h" - -struct app_info -{ - rtgui_workbench_t* workbench; - rtgui_view_t* game_view; - rtgui_list_view_t* function_view; - - rt_tetris_t * tetris; - rt_tetris_view_t* tetris_view; - rtgui_timer_t* _timer; -}; -typedef struct app_info app_info; -static app_info g_app_info; - -static void _game_over(void) -{ - rtgui_timer_destory(g_app_info._timer); - rt_tetris_destory(g_app_info.tetris); - rt_tetris_view_destroy(g_app_info.tetris_view); - rt_kprintf("GAME OVER\n"); - - rtgui_view_show(g_app_info.function_view, RT_FALSE); -} - -static rt_bool_t game_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) -{ - if (event->type == RTGUI_EVENT_PAINT) - { - struct rtgui_dc* dc; - rtgui_rect_t rect; - - /* draw child */ - rtgui_view_event_handler(widget, event); - - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - rect.x1 = 96; - rect.y1 = 0; - rect.x2 = 128; - rect.y2 = 16; - rtgui_dc_draw_text(dc, "next", &rect); - rect.y1 += 30; - rect.y2 = rect.y1 + 16; - rtgui_dc_draw_text(dc, "level", &rect); - rect.y1 += 22; - rect.y2 = rect.y1 + 16; - rtgui_dc_draw_text(dc, "lines", &rect); - rect.y1 += 22; - rect.y2 = rect.y1 + 16; - rtgui_dc_draw_text(dc, "score", &rect); - rtgui_dc_end_drawing(dc); - - /* start tetris game, removed later */ - rt_tetris_start(g_app_info.tetris); - return RT_FALSE; - } - else if ((event->type == RTGUI_EVENT_KBD)) - { - struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; - - if (ekbd->type == RTGUI_KEYDOWN) - { - if (ekbd->key == RTGUIK_RIGHT) - { - rt_tetris_right(g_app_info.tetris); - } - else if (ekbd->key == RTGUIK_LEFT) - { - rt_tetris_left(g_app_info.tetris); - } - else if (ekbd->key == RTGUIK_UP) - { - rt_tetris_rotate(g_app_info.tetris, RT_EOK); - } - else if (ekbd->key == RTGUIK_DOWN) - { - if( rt_tetris_drop(g_app_info.tetris) == -RT_ETIMEOUT - && rt_tetris_status(g_app_info.tetris) != RT_FALSE) - { - _game_over(); - } - } - } - } - - return rtgui_view_event_handler(widget, event); -} - -static void _timer_timeout(rtgui_timer_t* timer, void* parameter) -{ - if( rt_tetris_down(g_app_info.tetris) == -RT_ETIMEOUT) - { - _game_over(); - } -} - -static rt_bool_t workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event) -{ - if (event->type == RTGUI_EVENT_KBD) - { - struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; - if (((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME) - && !RTGUI_WORKBENCH_IS_MODAL_MODE(g_app_info.workbench)) - { - /* active home view */ - if (g_app_info.workbench->current_view != g_app_info.game_view) - { - rtgui_view_show(g_app_info.game_view, RT_FALSE); - return RT_TRUE; - } - } - } - - return rtgui_workbench_event_handler(widget, event); -} - -static void listitem_action_return(void) -{ - rtgui_view_destroy(g_app_info.game_view); - rtgui_list_view_destroy(g_app_info.function_view); - rtgui_workbench_close(g_app_info.workbench); -} - -static void listitem_action_start(void) -{ - /* create tetris modal instance */ - g_app_info.tetris = rt_tetris_create(16, 17); - - /* create tetris view instance */ - g_app_info.tetris_view = rt_tetris_view_create(RTGUI_WIDGET(g_app_info.game_view)); - - /* register tetris view to tetris modal */ - rt_tetris_add_view(g_app_info.tetris, g_app_info.tetris_view); - - /* create timer */ - g_app_info._timer = rtgui_timer_create(40, RT_TIMER_FLAG_PERIODIC, _timer_timeout, RT_NULL); - - /* this view can be focused */ - RTGUI_WIDGET(g_app_info.game_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; - - /* set widget focus */ - rtgui_widget_focus(RTGUI_WIDGET(g_app_info.game_view)); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(g_app_info.game_view)) = RTGUI_RGB(0xff, 0xff, 0xff); - - rtgui_view_show(g_app_info.game_view, RT_FALSE); - rtgui_timer_start(g_app_info._timer); -} - -static void listitem_action_continue(void) -{ - -} - -static void listitem_action_adjust(void) -{ - -} - -static void listitem_action_description(void) -{ - -} - -static const struct rtgui_list_item function_list[] = -{ - {"ÐÂÓÎϷ", RT_NULL, listitem_action_start, RT_NULL}, - {"¼ÌÐø", RT_NULL, listitem_action_continue, RT_NULL}, - {"µȼ¶", RT_NULL, listitem_action_adjust, RT_NULL}, - {"ÓÎϷ˵Ã÷", RT_NULL, listitem_action_description, RT_NULL}, - {"Í˳öÓÎϷ", RT_NULL, listitem_action_return, RT_NULL}, -}; - -void main(void) -{ - rt_mq_t mq; - rtgui_rect_t rect; - - mq = rt_mq_create("tetris_ui", 256, 4, RT_IPC_FLAG_FIFO); - rtgui_thread_register(rt_thread_self(), mq); - - g_app_info.workbench = rtgui_workbench_create("main", "tetris"); - if (g_app_info.workbench == RT_NULL) - { - rt_kprintf("can't find panel 'main'\n"); - rt_mq_delete(mq); - - return; - } - rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.workbench), workbench_event_handler); - - /* add function view */ - rtgui_widget_get_rect(RTGUI_WIDGET(g_app_info.workbench), &rect); - - g_app_info.function_view = rtgui_list_view_create(function_list, - sizeof(function_list) / sizeof(struct rtgui_list_item), - &rect, - RTGUI_LIST_VIEW_LIST); - - rtgui_workbench_add_view(g_app_info.workbench, RTGUI_VIEW(g_app_info.function_view)); - - /* add home view */ - g_app_info.game_view = rtgui_view_create("game"); - - rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.game_view), game_view_event_handler); - rtgui_workbench_add_view(g_app_info.workbench, g_app_info.game_view); - - rtgui_view_show(RTGUI_VIEW(g_app_info.function_view), RT_FALSE); - - rtgui_workbench_event_loop(g_app_info.workbench); - rtgui_workbench_destroy(g_app_info.workbench); - - rtgui_thread_deregister(rt_thread_self()); - rt_mq_delete(mq); -} - +/* + * File : tetris_ui.c + * This file is part of RTGUI in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-08-14 Yi.Qiu first version + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tetris.h" + +struct app_info +{ + rtgui_workbench_t* workbench; + rtgui_view_t* game_view; + rtgui_list_view_t* function_view; + + rt_tetris_t * tetris; + rt_tetris_view_t* tetris_view; + rtgui_timer_t* _timer; +}; +typedef struct app_info app_info; +static app_info g_app_info; + +static void _game_over(void) +{ + rtgui_timer_destory(g_app_info._timer); + rt_tetris_destory(g_app_info.tetris); + rt_tetris_view_destroy(g_app_info.tetris_view); + rt_kprintf("GAME OVER\n"); + + rtgui_view_show(g_app_info.function_view, RT_FALSE); +} + +static rt_bool_t game_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +{ + if (event->type == RTGUI_EVENT_PAINT) + { + struct rtgui_dc* dc; + rtgui_rect_t rect; + + /* draw child */ + rtgui_view_event_handler(widget, event); + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + rect.x1 = 96; + rect.y1 = 0; + rect.x2 = 128; + rect.y2 = 16; + rtgui_dc_draw_text(dc, "next", &rect); + rect.y1 += 30; + rect.y2 = rect.y1 + 16; + rtgui_dc_draw_text(dc, "level", &rect); + rect.y1 += 22; + rect.y2 = rect.y1 + 16; + rtgui_dc_draw_text(dc, "lines", &rect); + rect.y1 += 22; + rect.y2 = rect.y1 + 16; + rtgui_dc_draw_text(dc, "score", &rect); + rtgui_dc_end_drawing(dc); + + /* start tetris game, removed later */ + rt_tetris_start(g_app_info.tetris); + return RT_FALSE; + } + else if ((event->type == RTGUI_EVENT_KBD)) + { + struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; + + if (ekbd->type == RTGUI_KEYDOWN) + { + if (ekbd->key == RTGUIK_RIGHT) + { + rt_tetris_right(g_app_info.tetris); + } + else if (ekbd->key == RTGUIK_LEFT) + { + rt_tetris_left(g_app_info.tetris); + } + else if (ekbd->key == RTGUIK_UP) + { + rt_tetris_rotate(g_app_info.tetris, RT_EOK); + } + else if (ekbd->key == RTGUIK_DOWN) + { + if( rt_tetris_drop(g_app_info.tetris) == -RT_ETIMEOUT + && rt_tetris_status(g_app_info.tetris) != RT_FALSE) + { + _game_over(); + } + } + } + } + + return rtgui_view_event_handler(widget, event); +} + +static void _timer_timeout(rtgui_timer_t* timer, void* parameter) +{ + if( rt_tetris_down(g_app_info.tetris) == -RT_ETIMEOUT) + { + _game_over(); + } +} + +static rt_bool_t workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event) +{ + if (event->type == RTGUI_EVENT_KBD) + { + struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; + if (((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME) + && !RTGUI_WORKBENCH_IS_MODAL_MODE(g_app_info.workbench)) + { + /* active home view */ + if (g_app_info.workbench->current_view != g_app_info.game_view) + { + rtgui_view_show(g_app_info.game_view, RT_FALSE); + return RT_TRUE; + } + } + } + + return rtgui_workbench_event_handler(widget, event); +} + +static void listitem_action_return(void) +{ + rtgui_view_destroy(g_app_info.game_view); + rtgui_list_view_destroy(g_app_info.function_view); + rtgui_workbench_close(g_app_info.workbench); +} + +static void listitem_action_start(void) +{ + /* create tetris modal instance */ + g_app_info.tetris = rt_tetris_create(16, 17); + + /* create tetris view instance */ + g_app_info.tetris_view = rt_tetris_view_create(RTGUI_WIDGET(g_app_info.game_view)); + + /* register tetris view to tetris modal */ + rt_tetris_add_view(g_app_info.tetris, g_app_info.tetris_view); + + /* create timer */ + g_app_info._timer = rtgui_timer_create(40, RT_TIMER_FLAG_PERIODIC, _timer_timeout, RT_NULL); + + /* this view can be focused */ + RTGUI_WIDGET(g_app_info.game_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; + + /* set widget focus */ + rtgui_widget_focus(RTGUI_WIDGET(g_app_info.game_view)); + RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(g_app_info.game_view)) = RTGUI_RGB(0xff, 0xff, 0xff); + + rtgui_view_show(g_app_info.game_view, RT_FALSE); + rtgui_timer_start(g_app_info._timer); +} + +static void listitem_action_continue(void) +{ + +} + +static void listitem_action_adjust(void) +{ + +} + +static void listitem_action_description(void) +{ + +} + +static const struct rtgui_list_item function_list[] = +{ + {"ÐÂÓÎϷ", RT_NULL, listitem_action_start, RT_NULL}, + {"¼ÌÐø", RT_NULL, listitem_action_continue, RT_NULL}, + {"µȼ¶", RT_NULL, listitem_action_adjust, RT_NULL}, + {"ÓÎϷ˵Ã÷", RT_NULL, listitem_action_description, RT_NULL}, + {"Í˳öÓÎϷ", RT_NULL, listitem_action_return, RT_NULL}, +}; + +void main(void) +{ + rt_mq_t mq; + rtgui_rect_t rect; + + mq = rt_mq_create("tetris_ui", 256, 4, RT_IPC_FLAG_FIFO); + rtgui_thread_register(rt_thread_self(), mq); + + g_app_info.workbench = rtgui_workbench_create("main", "tetris"); + if (g_app_info.workbench == RT_NULL) + { + rt_kprintf("can't find panel 'main'\n"); + rt_mq_delete(mq); + + return; + } + rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.workbench), workbench_event_handler); + + /* add function view */ + rtgui_widget_get_rect(RTGUI_WIDGET(g_app_info.workbench), &rect); + + g_app_info.function_view = rtgui_list_view_create(function_list, + sizeof(function_list) / sizeof(struct rtgui_list_item), + &rect, + RTGUI_LIST_VIEW_LIST); + + rtgui_workbench_add_view(g_app_info.workbench, RTGUI_VIEW(g_app_info.function_view)); + + /* add home view */ + g_app_info.game_view = rtgui_view_create("game"); + + rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.game_view), game_view_event_handler); + rtgui_workbench_add_view(g_app_info.workbench, g_app_info.game_view); + + rtgui_view_show(RTGUI_VIEW(g_app_info.function_view), RT_FALSE); + + rtgui_workbench_event_loop(g_app_info.workbench); + rtgui_workbench_destroy(g_app_info.workbench); + + rtgui_thread_deregister(rt_thread_self()); + rt_mq_delete(mq); +} + diff --git a/examples/module/tetris/tetris_view.c b/examples/module/tetris/tetris_view.c index dcb0cb312a..722a4d315c 100644 --- a/examples/module/tetris/tetris_view.c +++ b/examples/module/tetris/tetris_view.c @@ -1,218 +1,218 @@ -/* - * File : tetris_view.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-08-14 Yi.Qiu first version - */ - -#include -#include -#include -#include -#include -#include "tetris.h" - -static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris); -static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris); -static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris); -static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris); - -rt_tetris_view_t* rt_tetris_view_create(void* private) -{ - rt_tetris_view_t* thiz; - - RT_ASSERT(private != RT_NULL) - - thiz = (rt_tetris_view_t*)rt_malloc(sizeof(rt_tetris_view_t)); - thiz->width = 96; - thiz->height = 96; - - thiz->update = _rt_tetris_view_update; - thiz->update_next_brick = _rt_tetris_view_update_next_brick; - thiz->update_level = _rt_tetris_view_update_level; - thiz->update_score_and_lines = _rt_tetris_view_update_score_and_lines; - thiz->private = private; - - return thiz; -} - -rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - rt_free(thiz); - - return RT_EOK; -} - -static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect; - rt_uint32_t width; - rt_uint32_t ppb, i; - rtgui_widget_t* widget; - rt_uint32_t* next_brick; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(tetris != RT_NULL); - - next_brick = rt_tetris_next_brick(tetris); - widget = (rtgui_widget_t*)thiz->private; - width = rt_tetris_width(tetris); - /* pixel per block */ - ppb = thiz->width / width; - - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - - rect.x1 = 100; - rect.x2 = rect.x1 + 4 * ppb; - rect.y1 = 16; - rect.y2 = rect.y1 + 2 * ppb; - - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_dc_fill_rect(dc, &rect); - - for(i=0; i<4; i++) - { - rt_uint32_t y = next_brick[i] / width; - rt_uint32_t x = next_brick[i] % width; - - rect.x1 = 100 + ppb * (x - 6); - rect.x2 = rect.x1 + ppb - 1; - rect.y1 = 16 + ppb * y ; - rect.y2 = rect.y1 + ppb - 1; - - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); - rtgui_dc_fill_rect(dc, &rect); - } - - rtgui_dc_end_drawing(dc); - - return RT_EOK; -} - -static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect; - rtgui_widget_t* widget; - char text[4]; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(tetris != RT_NULL); - - widget = (rtgui_widget_t*)thiz->private; - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - - rect.x1 = 96; - rect.y1 = 42; - rect.x2 = 128; - rect.y2 = rect.y1 + 10; - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_dc_fill_rect(dc, &rect); - rt_sprintf(text, "%d", rt_tetris_level(tetris)); - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); - rtgui_dc_draw_text(dc, text, &rect); - - /* Redraw panel */ - rtgui_dc_end_drawing(dc); - - return RT_EOK; -} - -static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect; - rtgui_widget_t* widget; - char text[4]; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(tetris != RT_NULL); - - widget = (rtgui_widget_t*)thiz->private; - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - - rect.x1 = 96; - rect.y1 = 64; - rect.x2 = 128; - rect.y2 = rect.y1 + 10; - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_dc_fill_rect(dc, &rect); - rt_sprintf(text, "%d", rt_tetris_lines(tetris)); - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); - rtgui_dc_draw_text(dc, text, &rect); - - rect.y1 += 22; - rect.y2 = rect.y1 + 10; - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_dc_fill_rect(dc, &rect); - rt_sprintf(text, "%d", rt_tetris_score(tetris)); - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); - rtgui_dc_draw_text(dc, text, &rect); - - /* Redraw panel */ - rtgui_dc_end_drawing(dc); - - return RT_EOK; -} - -static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect; - rt_uint32_t width, height; - rt_uint32_t j,k, ppb; - rtgui_widget_t* widget; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(tetris != RT_NULL); - - widget = (rtgui_widget_t*)thiz->private; - width = rt_tetris_width(tetris); - height = rt_tetris_height(tetris); - ppb = thiz->width / width; - - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - - /* Redraw panel */ - for(j=0; j +#include +#include +#include +#include +#include "tetris.h" + +static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris); +static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris); +static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris); +static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris); + +rt_tetris_view_t* rt_tetris_view_create(void* private) +{ + rt_tetris_view_t* thiz; + + RT_ASSERT(private != RT_NULL) + + thiz = (rt_tetris_view_t*)rt_malloc(sizeof(rt_tetris_view_t)); + thiz->width = 96; + thiz->height = 96; + + thiz->update = _rt_tetris_view_update; + thiz->update_next_brick = _rt_tetris_view_update_next_brick; + thiz->update_level = _rt_tetris_view_update_level; + thiz->update_score_and_lines = _rt_tetris_view_update_score_and_lines; + thiz->private = private; + + return thiz; +} + +rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + rt_free(thiz); + + return RT_EOK; +} + +static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect; + rt_uint32_t width; + rt_uint32_t ppb, i; + rtgui_widget_t* widget; + rt_uint32_t* next_brick; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(tetris != RT_NULL); + + next_brick = rt_tetris_next_brick(tetris); + widget = (rtgui_widget_t*)thiz->private; + width = rt_tetris_width(tetris); + /* pixel per block */ + ppb = thiz->width / width; + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + + rect.x1 = 100; + rect.x2 = rect.x1 + 4 * ppb; + rect.y1 = 16; + rect.y2 = rect.y1 + 2 * ppb; + + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_dc_fill_rect(dc, &rect); + + for(i=0; i<4; i++) + { + rt_uint32_t y = next_brick[i] / width; + rt_uint32_t x = next_brick[i] % width; + + rect.x1 = 100 + ppb * (x - 6); + rect.x2 = rect.x1 + ppb - 1; + rect.y1 = 16 + ppb * y ; + rect.y2 = rect.y1 + ppb - 1; + + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); + rtgui_dc_fill_rect(dc, &rect); + } + + rtgui_dc_end_drawing(dc); + + return RT_EOK; +} + +static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect; + rtgui_widget_t* widget; + char text[4]; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(tetris != RT_NULL); + + widget = (rtgui_widget_t*)thiz->private; + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + + rect.x1 = 96; + rect.y1 = 42; + rect.x2 = 128; + rect.y2 = rect.y1 + 10; + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_dc_fill_rect(dc, &rect); + rt_sprintf(text, "%d", rt_tetris_level(tetris)); + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); + rtgui_dc_draw_text(dc, text, &rect); + + /* Redraw panel */ + rtgui_dc_end_drawing(dc); + + return RT_EOK; +} + +static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect; + rtgui_widget_t* widget; + char text[4]; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(tetris != RT_NULL); + + widget = (rtgui_widget_t*)thiz->private; + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + + rect.x1 = 96; + rect.y1 = 64; + rect.x2 = 128; + rect.y2 = rect.y1 + 10; + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_dc_fill_rect(dc, &rect); + rt_sprintf(text, "%d", rt_tetris_lines(tetris)); + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); + rtgui_dc_draw_text(dc, text, &rect); + + rect.y1 += 22; + rect.y2 = rect.y1 + 10; + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_dc_fill_rect(dc, &rect); + rt_sprintf(text, "%d", rt_tetris_score(tetris)); + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); + rtgui_dc_draw_text(dc, text, &rect); + + /* Redraw panel */ + rtgui_dc_end_drawing(dc); + + return RT_EOK; +} + +static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect; + rt_uint32_t width, height; + rt_uint32_t j,k, ppb; + rtgui_widget_t* widget; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(tetris != RT_NULL); + + widget = (rtgui_widget_t*)thiz->private; + width = rt_tetris_width(tetris); + height = rt_tetris_height(tetris); + ppb = thiz->width / width; + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + + /* Redraw panel */ + for(j=0; j -#include /* 为了解析主机名,需要包含netdb.h头文件 */ -#include /* 使用BSD socket,需要包含sockets.h头文件 */ - -#define BUFSZ 1024 - -static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */ -void tcpclient(const char* url, int port) -{ - char *recv_data; - struct hostent *host; - int sock, bytes_received; - struct sockaddr_in server_addr; - - /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ - host = gethostbyname(url); - - /* 分配用于存放接收数据的缓冲 */ - recv_data = rt_malloc(BUFSZ); - if (recv_data == RT_NULL) - { - rt_kprintf("No memory\n"); - return; - } - - /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */ - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) - { - /* 创建socket失败 */ - rt_kprintf("Socket error\n"); - - /* 释放接收缓冲 */ - rt_free(recv_data); - return; - } - - /* 初始化预连接的服务端地址 */ - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(port); - server_addr.sin_addr = *((struct in_addr *)host->h_addr); - rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); - - /* 连接到服务端 */ - if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) - { - /* 连接失败 */ - rt_kprintf("Connect fail!\n"); - lwip_close(sock); - - /*释放接收缓冲 */ - rt_free(recv_data); - return; - } - - while(1) - { - /* 从sock连接中接收最大BUFSZ - 1字节数据 */ - bytes_received = recv(sock, recv_data, BUFSZ - 1, 0); - if (bytes_received <= 0) - { - /* 接收失败,关闭这个连接 */ - lwip_close(sock); - - /* 释放接收缓冲 */ - rt_free(recv_data); - break; - } - - /* 有接收到数据,把末端清零 */ - recv_data[bytes_received] = '\0'; - - if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0) - { - /* 如果是首字母是q或Q,关闭这个连接 */ - lwip_close(sock); - - /* 释放接收缓冲 */ - rt_free(recv_data); - break; - } - else - { - /* 在控制终端显示收到的数据 */ - rt_kprintf("\nRecieved data = %s " , recv_data); - } - - /* 发送数据到sock连接 */ - send(sock,send_data,strlen(send_data), 0); - } - - return; -} - -#ifdef RT_USING_FINSH -#include -/* 输出tcpclient函数到finsh shell中 */ -FINSH_FUNCTION_EXPORT(tcpclient, startup tcp client); -#endif +#include +#include /* 为了解析主机名,需要包含netdb.h头文件 */ +#include /* 使用BSD socket,需要包含sockets.h头文件 */ + +#define BUFSZ 1024 + +static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */ +void tcpclient(const char* url, int port) +{ + char *recv_data; + struct hostent *host; + int sock, bytes_received; + struct sockaddr_in server_addr; + + /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ + host = gethostbyname(url); + + /* 分配用于存放接收数据的缓冲 */ + recv_data = rt_malloc(BUFSZ); + if (recv_data == RT_NULL) + { + rt_kprintf("No memory\n"); + return; + } + + /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */ + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + /* 创建socket失败 */ + rt_kprintf("Socket error\n"); + + /* 释放接收缓冲 */ + rt_free(recv_data); + return; + } + + /* 初始化预连接的服务端地址 */ + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr = *((struct in_addr *)host->h_addr); + rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + /* 连接到服务端 */ + if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) + { + /* 连接失败 */ + rt_kprintf("Connect fail!\n"); + lwip_close(sock); + + /*释放接收缓冲 */ + rt_free(recv_data); + return; + } + + while(1) + { + /* 从sock连接中接收最大BUFSZ - 1字节数据 */ + bytes_received = recv(sock, recv_data, BUFSZ - 1, 0); + if (bytes_received <= 0) + { + /* 接收失败,关闭这个连接 */ + lwip_close(sock); + + /* 释放接收缓冲 */ + rt_free(recv_data); + break; + } + + /* 有接收到数据,把末端清零 */ + recv_data[bytes_received] = '\0'; + + if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0) + { + /* 如果是首字母是q或Q,关闭这个连接 */ + lwip_close(sock); + + /* 释放接收缓冲 */ + rt_free(recv_data); + break; + } + else + { + /* 在控制终端显示收到的数据 */ + rt_kprintf("\nRecieved data = %s " , recv_data); + } + + /* 发送数据到sock连接 */ + send(sock,send_data,strlen(send_data), 0); + } + + return; +} + +#ifdef RT_USING_FINSH +#include +/* 输出tcpclient函数到finsh shell中 */ +FINSH_FUNCTION_EXPORT(tcpclient, startup tcp client); +#endif diff --git a/examples/network/tcpsendpacket.c b/examples/network/tcpsendpacket.c index 328b9df7c9..50841e0149 100644 --- a/examples/network/tcpsendpacket.c +++ b/examples/network/tcpsendpacket.c @@ -1,63 +1,63 @@ -#include -#include /* ΪÁ˽âÎöÖ÷»úÃû£¬ÐèҪ°üº¬netdb.hͷÎļþ */ -#include /* ʹÓÃBSD socket£¬ÐèҪ°üº¬sockets.hͷÎļþ */ - -void tcp_senddata(const char* url, int port, int length) -{ - struct hostent *host; - int sock, err, result, timeout, index; - struct sockaddr_in server_addr; - rt_uint8_t *buffer_ptr; - - /* ͨ¹ýº¯ÊýÈë¿ڲÎÊýurl»ñµÃhostµØַ£¨Èç¹ûÊÇÓòÃû£¬»á×öÓòÃû½âÎö£© */ - host = gethostbyname(url); - /* ´´½¨һ¸ösocket£¬ÀàÐÍÊÇSOCKET_STREAM£¬TCPÀàÐÍ */ - if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) - { - /* ´´½¨socketʧ°Ü */ - rt_kprintf("Socket error\n"); - return; - } - - /* ÉñÆæÄڴæ */ - buffer_ptr = rt_malloc(length); - /* ¹¹Ô췢ÉúÊý¾Ý */ - for (index = 0; index < length; index ++) - buffer_ptr[index] = index & 0xff; - - timeout = 100; - /* ÉèÖ÷¢Ëͳ¬ʱʱ¼ä100ms */ - lwip_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); - /* ³õʼ»¯ԤÁ¬½ӵķþÎñ¶˵Øַ */ - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(port); - server_addr.sin_addr = *((struct in_addr *)host->h_addr); - rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); - - /* Á¬½ӵ½·þÎñ¶Ë */ - err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); - rt_kprintf("TCP thread connect error code: %d\n", err); - - while(1) - { - /* ·¢ËÍÊý¾ݵ½sockÁ¬½Ó */ - result = send(sock, buffer_ptr, length, MSG_DONTWAIT); - if(result == -1) //Êý¾ݷ¢ËʹíÎó´¦Àí - { - rt_kprintf("TCP thread send error: %d\n", result); - lwip_close(sock); //¹رÕÁ¬½ӣ¬ÖØÐ´´½¨Á¬½Ó - rt_thread_delay(10); - if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) - rt_kprintf("TCP Socket error:%d\n",sock); - err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); - rt_kprintf("TCP thread connect error code: %d\n", err); - } - } -} - -#ifdef RT_USING_FINSH -#include -/* Êä³ötcpclientº¯Êýµ½finsh shellÖÐ */ -FINSH_FUNCTION_EXPORT(tcp_senddata, send a packet through tcp connection); -#endif - +#include +#include /* ΪÁ˽âÎöÖ÷»úÃû£¬ÐèҪ°üº¬netdb.hͷÎļþ */ +#include /* ʹÓÃBSD socket£¬ÐèҪ°üº¬sockets.hͷÎļþ */ + +void tcp_senddata(const char* url, int port, int length) +{ + struct hostent *host; + int sock, err, result, timeout, index; + struct sockaddr_in server_addr; + rt_uint8_t *buffer_ptr; + + /* ͨ¹ýº¯ÊýÈë¿ڲÎÊýurl»ñµÃhostµØַ£¨Èç¹ûÊÇÓòÃû£¬»á×öÓòÃû½âÎö£© */ + host = gethostbyname(url); + /* ´´½¨һ¸ösocket£¬ÀàÐÍÊÇSOCKET_STREAM£¬TCPÀàÐÍ */ + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) + { + /* ´´½¨socketʧ°Ü */ + rt_kprintf("Socket error\n"); + return; + } + + /* ÉñÆæÄڴæ */ + buffer_ptr = rt_malloc(length); + /* ¹¹Ô췢ÉúÊý¾Ý */ + for (index = 0; index < length; index ++) + buffer_ptr[index] = index & 0xff; + + timeout = 100; + /* ÉèÖ÷¢Ëͳ¬ʱʱ¼ä100ms */ + lwip_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); + /* ³õʼ»¯ԤÁ¬½ӵķþÎñ¶˵Øַ */ + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr = *((struct in_addr *)host->h_addr); + rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + /* Á¬½ӵ½·þÎñ¶Ë */ + err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); + rt_kprintf("TCP thread connect error code: %d\n", err); + + while(1) + { + /* ·¢ËÍÊý¾ݵ½sockÁ¬½Ó */ + result = send(sock, buffer_ptr, length, MSG_DONTWAIT); + if(result == -1) //Êý¾ݷ¢ËʹíÎó´¦Àí + { + rt_kprintf("TCP thread send error: %d\n", result); + lwip_close(sock); //¹رÕÁ¬½ӣ¬ÖØÐ´´½¨Á¬½Ó + rt_thread_delay(10); + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) + rt_kprintf("TCP Socket error:%d\n",sock); + err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); + rt_kprintf("TCP thread connect error code: %d\n", err); + } + } +} + +#ifdef RT_USING_FINSH +#include +/* Êä³ötcpclientº¯Êýµ½finsh shellÖÐ */ +FINSH_FUNCTION_EXPORT(tcp_senddata, send a packet through tcp connection); +#endif + diff --git a/examples/network/tcpserver.c b/examples/network/tcpserver.c index 6d83acc1b2..54b8c9301d 100644 --- a/examples/network/tcpserver.c +++ b/examples/network/tcpserver.c @@ -1,122 +1,122 @@ -#include -#include /* 使用BSD Socket接口必须包含sockets.h这个头文件 */ - -static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */ -void tcpserv(void* parameter) -{ - char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */ - rt_uint32_t sin_size; - int sock, connected, bytes_received; - struct sockaddr_in server_addr, client_addr; - rt_bool_t stop = RT_FALSE; /* 停止标志 */ - - recv_data = rt_malloc(1024); /* 分配接收用的数据缓冲 */ - if (recv_data == RT_NULL) - { - rt_kprintf("No memory\n"); - return; - } - - /* 一个socket在使用前,需要预先创建出来,指定SOCK_STREAM为TCP的socket */ - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) - { - /* 创建失败的错误处理 */ - rt_kprintf("Socket error\n"); - - /* 释放已分配的接收缓冲 */ - rt_free(recv_data); - return; - } - - /* 初始化服务端地址 */ - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(5000); /* 服务端工作的端口 */ - server_addr.sin_addr.s_addr = INADDR_ANY; - rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero)); - - /* 绑定socket到服务端地址 */ - if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) - { - /* 绑定失败 */ - rt_kprintf("Unable to bind\n"); - - /* 释放已分配的接收缓冲 */ - rt_free(recv_data); - return; - } - - /* 在socket上进行监听 */ - if (listen(sock, 5) == -1) - { - rt_kprintf("Listen error\n"); - - /* release recv buffer */ - rt_free(recv_data); - return; - } - - rt_kprintf("\nTCPServer Waiting for client on port 5000...\n"); - while(stop != RT_TRUE) - { - sin_size = sizeof(struct sockaddr_in); - - /* 接受一个客户端连接socket的请求,这个函数调用是阻塞式的 */ - connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); - /* 返回的是连接成功的socket */ - - /* 接受返回的client_addr指向了客户端的地址信息 */ - rt_kprintf("I got a connection from (%s , %d)\n", - inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); - - /* 客户端连接的处理 */ - while (1) - { - /* 发送数据到connected socket */ - send(connected, send_data, strlen(send_data), 0); - - /* 从connected socket中接收数据,接收buffer是1024大小,但并不一定能够收到1024大小的数据 */ - bytes_received = recv(connected,recv_data, 1024, 0); - if (bytes_received <= 0) - { - /* 接收失败,关闭这个connected socket */ - lwip_close(connected); - break; - } - - /* 有接收到数据,把末端清零 */ - recv_data[bytes_received] = '\0'; - if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0) - { - /* 如果是首字母是q或Q,关闭这个连接 */ - lwip_close(connected); - break; - } - else if (strcmp(recv_data, "exit") == 0) - { - /* 如果接收的是exit,则关闭整个服务端 */ - lwip_close(connected); - stop = RT_TRUE; - break; - } - else - { - /* 在控制终端显示收到的数据 */ - rt_kprintf("RECIEVED DATA = %s \n" , recv_data); - } - } - } - - /* 退出服务 */ - lwip_close(sock); - - /* 释放接收缓冲 */ - rt_free(recv_data); - - return ; -} - -#ifdef RT_USING_FINSH -#include -/* 输出tcpserv函数到finsh shell中 */ -FINSH_FUNCTION_EXPORT(tcpserv, startup tcp server); -#endif +#include +#include /* 使用BSD Socket接口必须包含sockets.h这个头文件 */ + +static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */ +void tcpserv(void* parameter) +{ + char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */ + rt_uint32_t sin_size; + int sock, connected, bytes_received; + struct sockaddr_in server_addr, client_addr; + rt_bool_t stop = RT_FALSE; /* 停止标志 */ + + recv_data = rt_malloc(1024); /* 分配接收用的数据缓冲 */ + if (recv_data == RT_NULL) + { + rt_kprintf("No memory\n"); + return; + } + + /* 一个socket在使用前,需要预先创建出来,指定SOCK_STREAM为TCP的socket */ + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + /* 创建失败的错误处理 */ + rt_kprintf("Socket error\n"); + + /* 释放已分配的接收缓冲 */ + rt_free(recv_data); + return; + } + + /* 初始化服务端地址 */ + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(5000); /* 服务端工作的端口 */ + server_addr.sin_addr.s_addr = INADDR_ANY; + rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero)); + + /* 绑定socket到服务端地址 */ + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) + { + /* 绑定失败 */ + rt_kprintf("Unable to bind\n"); + + /* 释放已分配的接收缓冲 */ + rt_free(recv_data); + return; + } + + /* 在socket上进行监听 */ + if (listen(sock, 5) == -1) + { + rt_kprintf("Listen error\n"); + + /* release recv buffer */ + rt_free(recv_data); + return; + } + + rt_kprintf("\nTCPServer Waiting for client on port 5000...\n"); + while(stop != RT_TRUE) + { + sin_size = sizeof(struct sockaddr_in); + + /* 接受一个客户端连接socket的请求,这个函数调用是阻塞式的 */ + connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); + /* 返回的是连接成功的socket */ + + /* 接受返回的client_addr指向了客户端的地址信息 */ + rt_kprintf("I got a connection from (%s , %d)\n", + inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); + + /* 客户端连接的处理 */ + while (1) + { + /* 发送数据到connected socket */ + send(connected, send_data, strlen(send_data), 0); + + /* 从connected socket中接收数据,接收buffer是1024大小,但并不一定能够收到1024大小的数据 */ + bytes_received = recv(connected,recv_data, 1024, 0); + if (bytes_received <= 0) + { + /* 接收失败,关闭这个connected socket */ + lwip_close(connected); + break; + } + + /* 有接收到数据,把末端清零 */ + recv_data[bytes_received] = '\0'; + if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0) + { + /* 如果是首字母是q或Q,关闭这个连接 */ + lwip_close(connected); + break; + } + else if (strcmp(recv_data, "exit") == 0) + { + /* 如果接收的是exit,则关闭整个服务端 */ + lwip_close(connected); + stop = RT_TRUE; + break; + } + else + { + /* 在控制终端显示收到的数据 */ + rt_kprintf("RECIEVED DATA = %s \n" , recv_data); + } + } + } + + /* 退出服务 */ + lwip_close(sock); + + /* 释放接收缓冲 */ + rt_free(recv_data); + + return ; +} + +#ifdef RT_USING_FINSH +#include +/* 输出tcpserv函数到finsh shell中 */ +FINSH_FUNCTION_EXPORT(tcpserv, startup tcp server); +#endif diff --git a/examples/network/udpclient.c b/examples/network/udpclient.c index 041adb32c5..50e0d39784 100644 --- a/examples/network/udpclient.c +++ b/examples/network/udpclient.c @@ -1,50 +1,50 @@ -#include -#include /* 为了解析主机名,需要包含netdb.h头文件 */ -#include /* 使用BSD socket,需要包含sockets.h头文件 */ - -const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* 发送用到的数据 */ -void udpclient(const char* url, int port, int count) -{ - int sock; - struct hostent *host; - struct sockaddr_in server_addr; - - /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ - host= (struct hostent *) gethostbyname(url); - - /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */ - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) - { - rt_kprintf("Socket error\n"); - return; - } - - /* 初始化预连接的服务端地址 */ - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(port); - server_addr.sin_addr = *((struct in_addr *)host->h_addr); - rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); - - /* 总计发送count次数据 */ - while (count) - { - /* 发送数据到服务远端 */ - sendto(sock, send_data, strlen(send_data), 0, - (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); - - /* 线程休眠一段时间 */ - rt_thread_delay(50); - - /* 计数值减一 */ - count --; - } - - /* 关闭这个socket */ - lwip_close(sock); -} - -#ifdef RT_USING_FINSH -#include -/* 输出udpclient函数到finsh shell中 */ -FINSH_FUNCTION_EXPORT(udpclient, startup udp client); -#endif +#include +#include /* 为了解析主机名,需要包含netdb.h头文件 */ +#include /* 使用BSD socket,需要包含sockets.h头文件 */ + +const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* 发送用到的数据 */ +void udpclient(const char* url, int port, int count) +{ + int sock; + struct hostent *host; + struct sockaddr_in server_addr; + + /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ + host= (struct hostent *) gethostbyname(url); + + /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + { + rt_kprintf("Socket error\n"); + return; + } + + /* 初始化预连接的服务端地址 */ + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr = *((struct in_addr *)host->h_addr); + rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + /* 总计发送count次数据 */ + while (count) + { + /* 发送数据到服务远端 */ + sendto(sock, send_data, strlen(send_data), 0, + (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); + + /* 线程休眠一段时间 */ + rt_thread_delay(50); + + /* 计数值减一 */ + count --; + } + + /* 关闭这个socket */ + lwip_close(sock); +} + +#ifdef RT_USING_FINSH +#include +/* 输出udpclient函数到finsh shell中 */ +FINSH_FUNCTION_EXPORT(udpclient, startup udp client); +#endif diff --git a/examples/network/udpserver.c b/examples/network/udpserver.c index ee84e9d061..cacd93b839 100644 --- a/examples/network/udpserver.c +++ b/examples/network/udpserver.c @@ -1,86 +1,86 @@ -#include -#include /* 使用BSD socket,需要包含sockets.h头文件 */ - -#define BUFSZ 1024 - -void udpserv(void* paramemter) -{ - int sock; - int bytes_read; - char *recv_data; - rt_uint32_t addr_len; - struct sockaddr_in server_addr, client_addr; - - /* 分配接收用的数据缓冲 */ - recv_data = rt_malloc(BUFSZ); - if (recv_data == RT_NULL) - { - /* 分配内存失败,返回 */ - rt_kprintf("No memory\n"); - return; - } - - /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */ - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) - { - rt_kprintf("Socket error\n"); - - /* 释放接收用的数据缓冲 */ - rt_free(recv_data); - return; - } - - /* 初始化服务端地址 */ - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(5000); - server_addr.sin_addr.s_addr = INADDR_ANY; - rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero)); - - /* 绑定socket到服务端地址 */ - if (bind(sock,(struct sockaddr *)&server_addr, - sizeof(struct sockaddr)) == -1) - { - /* 绑定地址失败 */ - rt_kprintf("Bind error\n"); - - /* 释放接收用的数据缓冲 */ - rt_free(recv_data); - return; - } - - addr_len = sizeof(struct sockaddr); - rt_kprintf("UDPServer Waiting for client on port 5000...\n"); - - while (1) - { - /* 从sock中收取最大BUFSZ - 1字节数据 */ - bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0, - (struct sockaddr *)&client_addr, &addr_len); - /* UDP不同于TCP,它基本不会出现收取的数据失败的情况,除非设置了超时等待 */ - - recv_data[bytes_read] = '\0'; /* 把末端清零 */ - - /* 输出接收的数据 */ - rt_kprintf("\n(%s , %d) said : ",inet_ntoa(client_addr.sin_addr), - ntohs(client_addr.sin_port)); - rt_kprintf("%s", recv_data); - - /* 如果接收数据是exit,退出 */ - if (strcmp(recv_data, "exit") == 0) - { - lwip_close(sock); - - /* 释放接收用的数据缓冲 */ - rt_free(recv_data); - break; - } - } - - return; -} - -#ifdef RT_USING_FINSH -#include -/* 输出udpserv函数到finsh shell中 */ -FINSH_FUNCTION_EXPORT(udpserv, startup udp server); -#endif +#include +#include /* 使用BSD socket,需要包含sockets.h头文件 */ + +#define BUFSZ 1024 + +void udpserv(void* paramemter) +{ + int sock; + int bytes_read; + char *recv_data; + rt_uint32_t addr_len; + struct sockaddr_in server_addr, client_addr; + + /* 分配接收用的数据缓冲 */ + recv_data = rt_malloc(BUFSZ); + if (recv_data == RT_NULL) + { + /* 分配内存失败,返回 */ + rt_kprintf("No memory\n"); + return; + } + + /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + { + rt_kprintf("Socket error\n"); + + /* 释放接收用的数据缓冲 */ + rt_free(recv_data); + return; + } + + /* 初始化服务端地址 */ + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(5000); + server_addr.sin_addr.s_addr = INADDR_ANY; + rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero)); + + /* 绑定socket到服务端地址 */ + if (bind(sock,(struct sockaddr *)&server_addr, + sizeof(struct sockaddr)) == -1) + { + /* 绑定地址失败 */ + rt_kprintf("Bind error\n"); + + /* 释放接收用的数据缓冲 */ + rt_free(recv_data); + return; + } + + addr_len = sizeof(struct sockaddr); + rt_kprintf("UDPServer Waiting for client on port 5000...\n"); + + while (1) + { + /* 从sock中收取最大BUFSZ - 1字节数据 */ + bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0, + (struct sockaddr *)&client_addr, &addr_len); + /* UDP不同于TCP,它基本不会出现收取的数据失败的情况,除非设置了超时等待 */ + + recv_data[bytes_read] = '\0'; /* 把末端清零 */ + + /* 输出接收的数据 */ + rt_kprintf("\n(%s , %d) said : ",inet_ntoa(client_addr.sin_addr), + ntohs(client_addr.sin_port)); + rt_kprintf("%s", recv_data); + + /* 如果接收数据是exit,退出 */ + if (strcmp(recv_data, "exit") == 0) + { + lwip_close(sock); + + /* 释放接收用的数据缓冲 */ + rt_free(recv_data); + break; + } + } + + return; +} + +#ifdef RT_USING_FINSH +#include +/* 输出udpserv函数到finsh shell中 */ +FINSH_FUNCTION_EXPORT(udpserv, startup udp server); +#endif diff --git a/examples/test/dhry.h b/examples/test/dhry.h index 02e7180e59..8f47233802 100644 --- a/examples/test/dhry.h +++ b/examples/test/dhry.h @@ -1,412 +1,412 @@ -/* - **************************************************************************** - * - * "DHRYSTONE" Benchmark Program - * ----------------------------- - * - * Version: C, Version 2.1 - * - * File: dhry.h (part 1 of 3) - * - * Date: May 25, 1988 - * - * Author: Reinhold P. Weicker - * Siemens AG, AUT E 51 - * Postfach 3220 - * 8520 Erlangen - * Germany (West) - * Phone: [+49]-9131-7-20330 - * (8-17 Central European Time) - * Usenet: ..!mcsun!unido!estevax!weicker - * - * Original Version (in Ada) published in - * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), - * pp. 1013 - 1030, together with the statistics - * on which the distribution of statements etc. is based. - * - * In this C version, the following C library functions are used: - * - strcpy, strcmp (inside the measurement loop) - * - printf, scanf (outside the measurement loop) - * In addition, Berkeley UNIX system calls "times ()" or "time ()" - * are used for execution time measurement. For measurements - * on other systems, these calls have to be changed. - * - * Collection of Results: - * Reinhold Weicker (address see above) and - * - * Rick Richardson - * PC Research. Inc. - * 94 Apple Orchard Drive - * Tinton Falls, NJ 07724 - * Phone: (201) 389-8963 (9-17 EST) - * Usenet: ...!uunet!pcrat!rick - * - * Please send results to Rick Richardson and/or Reinhold Weicker. - * Complete information should be given on hardware and software used. - * Hardware information includes: Machine type, CPU, type and size - * of caches; for microprocessors: clock frequency, memory speed - * (number of wait states). - * Software information includes: Compiler (and runtime library) - * manufacturer and version, compilation switches, OS version. - * The Operating System version may give an indication about the - * compiler; Dhrystone itself performs no OS calls in the measurement loop. - * - * The complete output generated by the program should be mailed - * such that at least some checks for correctness can be made. - * - *************************************************************************** - * - * History: This version C/2.1 has been made for two reasons: - * - * 1) There is an obvious need for a common C version of - * Dhrystone, since C is at present the most popular system - * programming language for the class of processors - * (microcomputers, minicomputers) where Dhrystone is used most. - * There should be, as far as possible, only one C version of - * Dhrystone such that results can be compared without - * restrictions. In the past, the C versions distributed - * by Rick Richardson (Version 1.1) and by Reinhold Weicker - * had small (though not significant) differences. - * - * 2) As far as it is possible without changes to the Dhrystone - * statistics, optimizing compilers should be prevented from - * removing significant statements. - * - * This C version has been developed in cooperation with - * Rick Richardson (Tinton Falls, NJ), it incorporates many - * ideas from the "Version 1.1" distributed previously by - * him over the UNIX network Usenet. - * I also thank Chaim Benedelac (National Semiconductor), - * David Ditzel (SUN), Earl Killian and John Mashey (MIPS), - * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) - * for their help with comments on earlier versions of the - * benchmark. - * - * Changes: In the initialization part, this version follows mostly - * Rick Richardson's version distributed via Usenet, not the - * version distributed earlier via floppy disk by Reinhold Weicker. - * As a concession to older compilers, names have been made - * unique within the first 8 characters. - * Inside the measurement loop, this version follows the - * version previously distributed by Reinhold Weicker. - * - * At several places in the benchmark, code has been added, - * but within the measurement loop only in branches that - * are not executed. The intention is that optimizing compilers - * should be prevented from moving code out of the measurement - * loop, or from removing code altogether. Since the statements - * that are executed within the measurement loop have NOT been - * changed, the numbers defining the "Dhrystone distribution" - * (distribution of statements, operand types and locality) - * still hold. Except for sophisticated optimizing compilers, - * execution times for this version should be the same as - * for previous versions. - * - * Since it has proven difficult to subtract the time for the - * measurement loop overhead in a correct way, the loop check - * has been made a part of the benchmark. This does have - * an impact - though a very minor one - on the distribution - * statistics which have been updated for this version. - * - * All changes within the measurement loop are described - * and discussed in the companion paper "Rationale for - * Dhrystone version 2". - * - * Because of the self-imposed limitation that the order and - * distribution of the executed statements should not be - * changed, there are still cases where optimizing compilers - * may not generate code for some statements. To a certain - * degree, this is unavoidable for small synthetic benchmarks. - * Users of the benchmark are advised to check code listings - * whether code is generated for all statements of Dhrystone. - * - * Version 2.1 is identical to version 2.0 distributed via - * the UNIX network Usenet in March 1988 except that it corrects - * some minor deficiencies that were found by users of version 2.0. - * The only change within the measurement loop is that a - * non-executed "else" part was added to the "if" statement in - * Func_3, and a non-executed "else" part removed from Proc_3. - * - *************************************************************************** - * - * Defines: The following "Defines" are possible: - * -DREG=register (default: Not defined) - * As an approximation to what an average C programmer - * might do, the "register" storage class is applied - * (if enabled by -DREG=register) - * - for local variables, if they are used (dynamically) - * five or more times - * - for parameters if they are used (dynamically) - * six or more times - * Note that an optimal "register" strategy is - * compiler-dependent, and that "register" declarations - * do not necessarily lead to faster execution. - * -DNOSTRUCTASSIGN (default: Not defined) - * Define if the C compiler does not support - * assignment of structures. - * -DNOENUMS (default: Not defined) - * Define if the C compiler does not support - * enumeration types. - * -DTIMES (default) - * -DTIME - * The "times" function of UNIX (returning process times) - * or the "time" function (returning wallclock time) - * is used for measurement. - * For single user machines, "time ()" is adequate. For - * multi-user machines where you cannot get single-user - * access, use the "times ()" function. If you have - * neither, use a stopwatch in the dead of night. - * "printf"s are provided marking the points "Start Timer" - * and "Stop Timer". DO NOT use the UNIX "time(1)" - * command, as this will measure the total time to - * run this program, which will (erroneously) include - * the time to allocate storage (malloc) and to perform - * the initialization. - * -DHZ=nnn - * In Berkeley UNIX, the function "times" returns process - * time in 1/HZ seconds, with HZ = 60 for most systems. - * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY - * A VALUE. - * - *************************************************************************** - * - * Compilation model and measurement (IMPORTANT): - * - * This C version of Dhrystone consists of three files: - * - dhry.h (this file, containing global definitions and comments) - * - dhry_1.c (containing the code corresponding to Ada package Pack_1) - * - dhry_2.c (containing the code corresponding to Ada package Pack_2) - * - * The following "ground rules" apply for measurements: - * - Separate compilation - * - No procedure merging - * - Otherwise, compiler optimizations are allowed but should be indicated - * - Default results are those without register declarations - * See the companion paper "Rationale for Dhrystone Version 2" for a more - * detailed discussion of these ground rules. - * - * For 16-Bit processors (e.g. 80186, 80286), times for all compilation - * models ("small", "medium", "large" etc.) should be given if possible, - * together with a definition of these models for the compiler system used. - * - ************************************************************************** - * - * Dhrystone (C version) statistics: - * - * [Comment from the first distribution, updated for version 2. - * Note that because of language differences, the numbers are slightly - * different from the Ada version.] - * - * The following program contains statements of a high level programming - * language (here: C) in a distribution considered representative: - * - * assignments 52 (51.0 %) - * control statements 33 (32.4 %) - * procedure, function calls 17 (16.7 %) - * - * 103 statements are dynamically executed. The program is balanced with - * respect to the three aspects: - * - * - statement type - * - operand type - * - operand locality - * operand global, local, parameter, or constant. - * - * The combination of these three aspects is balanced only approximately. - * - * 1. Statement Type: - * ----------------- number - * - * V1 = V2 9 - * (incl. V1 = F(..) - * V = Constant 12 - * Assignment, 7 - * with array element - * Assignment, 6 - * with record component - * -- - * 34 34 - * - * X = Y +|-|"&&"|"|" Z 5 - * X = Y +|-|"==" Constant 6 - * X = X +|- 1 3 - * X = Y *|/ Z 2 - * X = Expression, 1 - * two operators - * X = Expression, 1 - * three operators - * -- - * 18 18 - * - * if .... 14 - * with "else" 7 - * without "else" 7 - * executed 3 - * not executed 4 - * for ... 7 | counted every time - * while ... 4 | the loop condition - * do ... while 1 | is evaluated - * switch ... 1 - * break 1 - * declaration with 1 - * initialization - * -- - * 34 34 - * - * P (...) procedure call 11 - * user procedure 10 - * library procedure 1 - * X = F (...) - * function call 6 - * user function 5 - * library function 1 - * -- - * 17 17 - * --- - * 103 - * - * The average number of parameters in procedure or function calls - * is 1.82 (not counting the function values as implicit parameters). - * - * - * 2. Operators - * ------------ - * number approximate - * percentage - * - * Arithmetic 32 50.8 - * - * + 21 33.3 - * - 7 11.1 - * * 3 4.8 - * / (int div) 1 1.6 - * - * Comparison 27 42.8 - * - * == 9 14.3 - * /= 4 6.3 - * > 1 1.6 - * < 3 4.8 - * >= 1 1.6 - * <= 9 14.3 - * - * Logic 4 6.3 - * - * && (AND-THEN) 1 1.6 - * | (OR) 1 1.6 - * ! (NOT) 2 3.2 - * - * -- ----- - * 63 100.1 - * - * - * 3. Operand Type (counted once per operand reference): - * --------------- - * number approximate - * percentage - * - * Integer 175 72.3 % - * Character 45 18.6 % - * Pointer 12 5.0 % - * String30 6 2.5 % - * Array 2 0.8 % - * Record 2 0.8 % - * --- ------- - * 242 100.0 % - * - * When there is an access path leading to the final operand (e.g. a record - * component), only the final data type on the access path is counted. - * - * - * 4. Operand Locality: - * ------------------- - * number approximate - * percentage - * - * local variable 114 47.1 % - * global variable 22 9.1 % - * parameter 45 18.6 % - * value 23 9.5 % - * reference 22 9.1 % - * function result 6 2.5 % - * constant 55 22.7 % - * --- ------- - * 242 100.0 % - * - * - * The program does not compute anything meaningful, but it is syntactically - * and semantically correct. All variables have a value assigned to them - * before they are used as a source operand. - * - * There has been no explicit effort to account for the effects of a - * cache, or to balance the use of long or short displacements for code or - * data. - * - *************************************************************************** - */ - -/* Compiler and system dependent definitions: */ - -#define Mic_secs_Per_Second 1000000.0 - /* Berkeley UNIX C returns process times in seconds/HZ */ - -#ifdef NOSTRUCTASSIGN -#define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) -#else -#define structassign(d, s) d = s -#endif - -#ifdef NOENUM -#define Ident_1 0 -#define Ident_2 1 -#define Ident_3 2 -#define Ident_4 3 -#define Ident_5 4 - typedef int Enumeration; -#else - typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} - Enumeration; -#endif - /* for boolean and enumeration types in Ada, Pascal */ - -/* General definitions: */ - -// #include - /* for strcpy, strcmp */ -#include - -#define Null 0 - /* Value of a Null pointer */ -#define true 1 -#define false 0 - -typedef int One_Thirty; -typedef int One_Fifty; -typedef char Capital_Letter; -typedef int Boolean; -typedef char Str_30 [31]; -typedef int Arr_1_Dim [50]; -typedef int Arr_2_Dim [50] [50]; - -typedef struct record - { - struct record *Ptr_Comp; - Enumeration Discr; - union { - struct { - Enumeration Enum_Comp; - int Int_Comp; - char Str_Comp [31]; - } var_1; - struct { - Enumeration E_Comp_2; - char Str_2_Comp [31]; - } var_2; - struct { - char Ch_1_Comp; - char Ch_2_Comp; - } var_3; - } variant; - } Rec_Type, *Rec_Pointer; - - +/* + **************************************************************************** + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry.h (part 1 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * Siemens AG, AUT E 51 + * Postfach 3220 + * 8520 Erlangen + * Germany (West) + * Phone: [+49]-9131-7-20330 + * (8-17 Central European Time) + * Usenet: ..!mcsun!unido!estevax!weicker + * + * Original Version (in Ada) published in + * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), + * pp. 1013 - 1030, together with the statistics + * on which the distribution of statements etc. is based. + * + * In this C version, the following C library functions are used: + * - strcpy, strcmp (inside the measurement loop) + * - printf, scanf (outside the measurement loop) + * In addition, Berkeley UNIX system calls "times ()" or "time ()" + * are used for execution time measurement. For measurements + * on other systems, these calls have to be changed. + * + * Collection of Results: + * Reinhold Weicker (address see above) and + * + * Rick Richardson + * PC Research. Inc. + * 94 Apple Orchard Drive + * Tinton Falls, NJ 07724 + * Phone: (201) 389-8963 (9-17 EST) + * Usenet: ...!uunet!pcrat!rick + * + * Please send results to Rick Richardson and/or Reinhold Weicker. + * Complete information should be given on hardware and software used. + * Hardware information includes: Machine type, CPU, type and size + * of caches; for microprocessors: clock frequency, memory speed + * (number of wait states). + * Software information includes: Compiler (and runtime library) + * manufacturer and version, compilation switches, OS version. + * The Operating System version may give an indication about the + * compiler; Dhrystone itself performs no OS calls in the measurement loop. + * + * The complete output generated by the program should be mailed + * such that at least some checks for correctness can be made. + * + *************************************************************************** + * + * History: This version C/2.1 has been made for two reasons: + * + * 1) There is an obvious need for a common C version of + * Dhrystone, since C is at present the most popular system + * programming language for the class of processors + * (microcomputers, minicomputers) where Dhrystone is used most. + * There should be, as far as possible, only one C version of + * Dhrystone such that results can be compared without + * restrictions. In the past, the C versions distributed + * by Rick Richardson (Version 1.1) and by Reinhold Weicker + * had small (though not significant) differences. + * + * 2) As far as it is possible without changes to the Dhrystone + * statistics, optimizing compilers should be prevented from + * removing significant statements. + * + * This C version has been developed in cooperation with + * Rick Richardson (Tinton Falls, NJ), it incorporates many + * ideas from the "Version 1.1" distributed previously by + * him over the UNIX network Usenet. + * I also thank Chaim Benedelac (National Semiconductor), + * David Ditzel (SUN), Earl Killian and John Mashey (MIPS), + * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) + * for their help with comments on earlier versions of the + * benchmark. + * + * Changes: In the initialization part, this version follows mostly + * Rick Richardson's version distributed via Usenet, not the + * version distributed earlier via floppy disk by Reinhold Weicker. + * As a concession to older compilers, names have been made + * unique within the first 8 characters. + * Inside the measurement loop, this version follows the + * version previously distributed by Reinhold Weicker. + * + * At several places in the benchmark, code has been added, + * but within the measurement loop only in branches that + * are not executed. The intention is that optimizing compilers + * should be prevented from moving code out of the measurement + * loop, or from removing code altogether. Since the statements + * that are executed within the measurement loop have NOT been + * changed, the numbers defining the "Dhrystone distribution" + * (distribution of statements, operand types and locality) + * still hold. Except for sophisticated optimizing compilers, + * execution times for this version should be the same as + * for previous versions. + * + * Since it has proven difficult to subtract the time for the + * measurement loop overhead in a correct way, the loop check + * has been made a part of the benchmark. This does have + * an impact - though a very minor one - on the distribution + * statistics which have been updated for this version. + * + * All changes within the measurement loop are described + * and discussed in the companion paper "Rationale for + * Dhrystone version 2". + * + * Because of the self-imposed limitation that the order and + * distribution of the executed statements should not be + * changed, there are still cases where optimizing compilers + * may not generate code for some statements. To a certain + * degree, this is unavoidable for small synthetic benchmarks. + * Users of the benchmark are advised to check code listings + * whether code is generated for all statements of Dhrystone. + * + * Version 2.1 is identical to version 2.0 distributed via + * the UNIX network Usenet in March 1988 except that it corrects + * some minor deficiencies that were found by users of version 2.0. + * The only change within the measurement loop is that a + * non-executed "else" part was added to the "if" statement in + * Func_3, and a non-executed "else" part removed from Proc_3. + * + *************************************************************************** + * + * Defines: The following "Defines" are possible: + * -DREG=register (default: Not defined) + * As an approximation to what an average C programmer + * might do, the "register" storage class is applied + * (if enabled by -DREG=register) + * - for local variables, if they are used (dynamically) + * five or more times + * - for parameters if they are used (dynamically) + * six or more times + * Note that an optimal "register" strategy is + * compiler-dependent, and that "register" declarations + * do not necessarily lead to faster execution. + * -DNOSTRUCTASSIGN (default: Not defined) + * Define if the C compiler does not support + * assignment of structures. + * -DNOENUMS (default: Not defined) + * Define if the C compiler does not support + * enumeration types. + * -DTIMES (default) + * -DTIME + * The "times" function of UNIX (returning process times) + * or the "time" function (returning wallclock time) + * is used for measurement. + * For single user machines, "time ()" is adequate. For + * multi-user machines where you cannot get single-user + * access, use the "times ()" function. If you have + * neither, use a stopwatch in the dead of night. + * "printf"s are provided marking the points "Start Timer" + * and "Stop Timer". DO NOT use the UNIX "time(1)" + * command, as this will measure the total time to + * run this program, which will (erroneously) include + * the time to allocate storage (malloc) and to perform + * the initialization. + * -DHZ=nnn + * In Berkeley UNIX, the function "times" returns process + * time in 1/HZ seconds, with HZ = 60 for most systems. + * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY + * A VALUE. + * + *************************************************************************** + * + * Compilation model and measurement (IMPORTANT): + * + * This C version of Dhrystone consists of three files: + * - dhry.h (this file, containing global definitions and comments) + * - dhry_1.c (containing the code corresponding to Ada package Pack_1) + * - dhry_2.c (containing the code corresponding to Ada package Pack_2) + * + * The following "ground rules" apply for measurements: + * - Separate compilation + * - No procedure merging + * - Otherwise, compiler optimizations are allowed but should be indicated + * - Default results are those without register declarations + * See the companion paper "Rationale for Dhrystone Version 2" for a more + * detailed discussion of these ground rules. + * + * For 16-Bit processors (e.g. 80186, 80286), times for all compilation + * models ("small", "medium", "large" etc.) should be given if possible, + * together with a definition of these models for the compiler system used. + * + ************************************************************************** + * + * Dhrystone (C version) statistics: + * + * [Comment from the first distribution, updated for version 2. + * Note that because of language differences, the numbers are slightly + * different from the Ada version.] + * + * The following program contains statements of a high level programming + * language (here: C) in a distribution considered representative: + * + * assignments 52 (51.0 %) + * control statements 33 (32.4 %) + * procedure, function calls 17 (16.7 %) + * + * 103 statements are dynamically executed. The program is balanced with + * respect to the three aspects: + * + * - statement type + * - operand type + * - operand locality + * operand global, local, parameter, or constant. + * + * The combination of these three aspects is balanced only approximately. + * + * 1. Statement Type: + * ----------------- number + * + * V1 = V2 9 + * (incl. V1 = F(..) + * V = Constant 12 + * Assignment, 7 + * with array element + * Assignment, 6 + * with record component + * -- + * 34 34 + * + * X = Y +|-|"&&"|"|" Z 5 + * X = Y +|-|"==" Constant 6 + * X = X +|- 1 3 + * X = Y *|/ Z 2 + * X = Expression, 1 + * two operators + * X = Expression, 1 + * three operators + * -- + * 18 18 + * + * if .... 14 + * with "else" 7 + * without "else" 7 + * executed 3 + * not executed 4 + * for ... 7 | counted every time + * while ... 4 | the loop condition + * do ... while 1 | is evaluated + * switch ... 1 + * break 1 + * declaration with 1 + * initialization + * -- + * 34 34 + * + * P (...) procedure call 11 + * user procedure 10 + * library procedure 1 + * X = F (...) + * function call 6 + * user function 5 + * library function 1 + * -- + * 17 17 + * --- + * 103 + * + * The average number of parameters in procedure or function calls + * is 1.82 (not counting the function values as implicit parameters). + * + * + * 2. Operators + * ------------ + * number approximate + * percentage + * + * Arithmetic 32 50.8 + * + * + 21 33.3 + * - 7 11.1 + * * 3 4.8 + * / (int div) 1 1.6 + * + * Comparison 27 42.8 + * + * == 9 14.3 + * /= 4 6.3 + * > 1 1.6 + * < 3 4.8 + * >= 1 1.6 + * <= 9 14.3 + * + * Logic 4 6.3 + * + * && (AND-THEN) 1 1.6 + * | (OR) 1 1.6 + * ! (NOT) 2 3.2 + * + * -- ----- + * 63 100.1 + * + * + * 3. Operand Type (counted once per operand reference): + * --------------- + * number approximate + * percentage + * + * Integer 175 72.3 % + * Character 45 18.6 % + * Pointer 12 5.0 % + * String30 6 2.5 % + * Array 2 0.8 % + * Record 2 0.8 % + * --- ------- + * 242 100.0 % + * + * When there is an access path leading to the final operand (e.g. a record + * component), only the final data type on the access path is counted. + * + * + * 4. Operand Locality: + * ------------------- + * number approximate + * percentage + * + * local variable 114 47.1 % + * global variable 22 9.1 % + * parameter 45 18.6 % + * value 23 9.5 % + * reference 22 9.1 % + * function result 6 2.5 % + * constant 55 22.7 % + * --- ------- + * 242 100.0 % + * + * + * The program does not compute anything meaningful, but it is syntactically + * and semantically correct. All variables have a value assigned to them + * before they are used as a source operand. + * + * There has been no explicit effort to account for the effects of a + * cache, or to balance the use of long or short displacements for code or + * data. + * + *************************************************************************** + */ + +/* Compiler and system dependent definitions: */ + +#define Mic_secs_Per_Second 1000000.0 + /* Berkeley UNIX C returns process times in seconds/HZ */ + +#ifdef NOSTRUCTASSIGN +#define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) +#else +#define structassign(d, s) d = s +#endif + +#ifdef NOENUM +#define Ident_1 0 +#define Ident_2 1 +#define Ident_3 2 +#define Ident_4 3 +#define Ident_5 4 + typedef int Enumeration; +#else + typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} + Enumeration; +#endif + /* for boolean and enumeration types in Ada, Pascal */ + +/* General definitions: */ + +// #include + /* for strcpy, strcmp */ +#include + +#define Null 0 + /* Value of a Null pointer */ +#define true 1 +#define false 0 + +typedef int One_Thirty; +typedef int One_Fifty; +typedef char Capital_Letter; +typedef int Boolean; +typedef char Str_30 [31]; +typedef int Arr_1_Dim [50]; +typedef int Arr_2_Dim [50] [50]; + +typedef struct record + { + struct record *Ptr_Comp; + Enumeration Discr; + union { + struct { + Enumeration Enum_Comp; + int Int_Comp; + char Str_Comp [31]; + } var_1; + struct { + Enumeration E_Comp_2; + char Str_2_Comp [31]; + } var_2; + struct { + char Ch_1_Comp; + char Ch_2_Comp; + } var_3; + } variant; + } Rec_Type, *Rec_Pointer; + + diff --git a/examples/test/dhry_1.c b/examples/test/dhry_1.c index 18cdfec291..b45b9ddafa 100644 --- a/examples/test/dhry_1.c +++ b/examples/test/dhry_1.c @@ -1,349 +1,349 @@ -/* - **************************************************************************** - * - * "DHRYSTONE" Benchmark Program - * ----------------------------- - * - * Version: C, Version 2.1 - * - * File: dhry_1.c (part 2 of 3) - * - * Date: May 25, 1988 - * - * Author: Reinhold P. Weicker - * - **************************************************************************** - */ - -#define NUMBER_OF_RUNS 1000000 - -#include "dhry.h" -#define printf rt_kprintf - -/* Global Variables: */ - -Rec_Pointer Ptr_Glob, - Next_Ptr_Glob; -int Int_Glob; -Boolean Bool_Glob; -char Ch_1_Glob, - Ch_2_Glob; -int Arr_1_Glob [50]; -int Arr_2_Glob [50] [50]; - -Enumeration Func_1 (); - -/* forward declaration necessary since Enumeration may not simply be int */ - -#ifndef REG - Boolean Reg = false; -#define REG - /* REG becomes defined as empty */ - /* i.e. no register variables */ -#else - Boolean Reg = true; -#endif - -/* variables for time measurement: */ - -float Begin_Time, - End_Time, - User_Time; -float Microseconds, - Dhrystones_Per_Second; - -/* end of variables for time measurement */ - -void dhry_test(void) -/*****/ - - /* main program, corresponds to procedures */ - /* Main and Proc_0 in the Ada version */ -{ - One_Fifty Int_1_Loc; - REG One_Fifty Int_2_Loc; - One_Fifty Int_3_Loc; - REG char Ch_Index; - Enumeration Enum_Loc; - Str_30 Str_1_Loc; - Str_30 Str_2_Loc; - REG int Run_Index; - REG int Number_Of_Runs; - - /* Initializations */ - - Next_Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type)); - Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type)); - - Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; - Ptr_Glob->Discr = Ident_1; - Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; - Ptr_Glob->variant.var_1.Int_Comp = 40; - rt_strncpy (Ptr_Glob->variant.var_1.Str_Comp, - "DHRYSTONE PROGRAM, SOME STRING", sizeof(Ptr_Glob->variant.var_1.Str_Comp)); - rt_strncpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING", sizeof(Str_1_Loc)); - - Arr_2_Glob [8][7] = 10; - /* Was missing in published program. Without this statement, */ - /* Arr_2_Glob [8][7] would have an undefined value. */ - /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */ - /* overflow may occur for this array element. */ - - printf ("\n"); - printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n"); - printf ("\n"); - if (Reg) - { - printf ("Program compiled with 'register' attribute\n"); - printf ("\n"); - } - else - { - printf ("Program compiled without 'register' attribute\n"); - printf ("\n"); - } - printf ("Please give the number of runs through the benchmark: "); - - Number_Of_Runs = NUMBER_OF_RUNS; - printf ("%d\n", Number_Of_Runs); - - printf ("\n"); - - printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); - - /***************/ - /* Start timer */ - /***************/ - -// Add your timer initializing code here - - Begin_Time = rt_tick_get(); /* get start tick */ - - for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) - { - - Proc_5(); - Proc_4(); - /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */ - Int_1_Loc = 2; - Int_2_Loc = 3; - rt_strncpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING", sizeof(Str_2_Loc)); - Enum_Loc = Ident_2; - Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc); - /* Bool_Glob == 1 */ - while (Int_1_Loc < Int_2_Loc) /* loop body executed once */ - { - Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; - /* Int_3_Loc == 7 */ - Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); - /* Int_3_Loc == 7 */ - Int_1_Loc += 1; - } /* while */ - /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ - Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); - /* Int_Glob == 5 */ - Proc_1 (Ptr_Glob); - for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) - /* loop body executed twice */ - { - if (Enum_Loc == Func_1 (Ch_Index, 'C')) - /* then, not executed */ - { - Proc_6 (Ident_1, &Enum_Loc); - rt_strncpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING", sizeof(Str_2_Loc)); - Int_2_Loc = Run_Index; - Int_Glob = Run_Index; - } - } - /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ - Int_2_Loc = Int_2_Loc * Int_1_Loc; - Int_1_Loc = Int_2_Loc / Int_3_Loc; - Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; - /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */ - Proc_2 (&Int_1_Loc); - /* Int_1_Loc == 5 */ - - } /* loop "for Run_Index" */ - - /**************/ - /* Stop timer */ - /**************/ - - End_Time = rt_tick_get(); // Get end tick - - printf ("Execution ends\n"); - printf ("\n"); - printf ("Final values of the variables used in the benchmark:\n"); - printf ("\n"); - printf ("Int_Glob: %d\n", Int_Glob); - printf (" should be: %d\n", 5); - printf ("Bool_Glob: %d\n", Bool_Glob); - printf (" should be: %d\n", 1); - printf ("Ch_1_Glob: %c\n", Ch_1_Glob); - printf (" should be: %c\n", 'A'); - printf ("Ch_2_Glob: %c\n", Ch_2_Glob); - printf (" should be: %c\n", 'B'); - printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]); - printf (" should be: %d\n", 7); - printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]); - printf (" should be: Number_Of_Runs + 10\n"); - printf ("Ptr_Glob->\n"); - printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp); - printf (" should be: (implementation-dependent)\n"); - printf (" Discr: %d\n", Ptr_Glob->Discr); - printf (" should be: %d\n", 0); - printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp); - printf (" should be: %d\n", 2); - printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp); - printf (" should be: %d\n", 17); - printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp); - printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); - printf ("Next_Ptr_Glob->\n"); - printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp); - printf (" should be: (implementation-dependent), same as above\n"); - printf (" Discr: %d\n", Next_Ptr_Glob->Discr); - printf (" should be: %d\n", 0); - printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp); - printf (" should be: %d\n", 1); - printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp); - printf (" should be: %d\n", 18); - printf (" Str_Comp: %s\n", - Next_Ptr_Glob->variant.var_1.Str_Comp); - printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); - printf ("Int_1_Loc: %d\n", Int_1_Loc); - printf (" should be: %d\n", 5); - printf ("Int_2_Loc: %d\n", Int_2_Loc); - printf (" should be: %d\n", 13); - printf ("Int_3_Loc: %d\n", Int_3_Loc); - printf (" should be: %d\n", 7); - printf ("Enum_Loc: %d\n", Enum_Loc); - printf (" should be: %d\n", 1); - printf ("Str_1_Loc: %s\n", Str_1_Loc); - printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); - printf ("Str_2_Loc: %s\n", Str_2_Loc); - printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); - printf ("\n"); - - User_Time = (End_Time - Begin_Time) / RT_TICK_PER_SECOND; - - Microseconds = (float) User_Time * Mic_secs_Per_Second - / (float) Number_Of_Runs; - Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time; - - printf ("Microseconds for one run through Dhrystone: "); - printf ("%6d \n", (int)Microseconds); - printf ("Dhrystones per Second: "); - printf ("%6d \n", (int)Dhrystones_Per_Second); - printf ("Dhrystones MIPS: "); - printf ("%6d \n", (int)(Dhrystones_Per_Second / 1757.0)); - printf ("\n"); - -} - -Proc_1 (Ptr_Val_Par) -/******************/ - -REG Rec_Pointer Ptr_Val_Par; - /* executed once */ -{ - REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; - /* == Ptr_Glob_Next */ - /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */ - /* corresponds to "rename" in Ada, "with" in Pascal */ - - structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); - Ptr_Val_Par->variant.var_1.Int_Comp = 5; - Next_Record->variant.var_1.Int_Comp - = Ptr_Val_Par->variant.var_1.Int_Comp; - Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp; - Proc_3 (&Next_Record->Ptr_Comp); - /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp - == Ptr_Glob->Ptr_Comp */ - if (Next_Record->Discr == Ident_1) - /* then, executed */ - { - Next_Record->variant.var_1.Int_Comp = 6; - Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, - &Next_Record->variant.var_1.Enum_Comp); - Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp; - Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, - &Next_Record->variant.var_1.Int_Comp); - } - else /* not executed */ - structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp); -} /* Proc_1 */ - - -Proc_2 (Int_Par_Ref) -/******************/ - /* executed once */ - /* *Int_Par_Ref == 1, becomes 4 */ - -One_Fifty *Int_Par_Ref; -{ - One_Fifty Int_Loc; - Enumeration Enum_Loc; - - Int_Loc = *Int_Par_Ref + 10; - do /* executed once */ - if (Ch_1_Glob == 'A') - /* then, executed */ - { - Int_Loc -= 1; - *Int_Par_Ref = Int_Loc - Int_Glob; - Enum_Loc = Ident_1; - } /* if */ - while (Enum_Loc != Ident_1); /* true */ -} /* Proc_2 */ - - -Proc_3 (Ptr_Ref_Par) -/******************/ - /* executed once */ - /* Ptr_Ref_Par becomes Ptr_Glob */ - -Rec_Pointer *Ptr_Ref_Par; - -{ - if (Ptr_Glob != Null) - /* then, executed */ - *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp; - Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); -} /* Proc_3 */ - - -Proc_4 () /* without parameters */ -/*******/ - /* executed once */ -{ - Boolean Bool_Loc; - - Bool_Loc = Ch_1_Glob == 'A'; - Bool_Glob = Bool_Loc | Bool_Glob; - Ch_2_Glob = 'B'; -} /* Proc_4 */ - - -Proc_5 () /* without parameters */ -/*******/ - /* executed once */ -{ - Ch_1_Glob = 'A'; - Bool_Glob = false; -} /* Proc_5 */ - - - /* Procedure for the assignment of structures, */ - /* if the C compiler doesn't support this feature */ -#ifdef NOSTRUCTASSIGN -memcpy (d, s, l) -register char *d; -register char *s; -register int l; -{ - while (l--) *d++ = *s++; -} -#endif - -#include -FINSH_FUNCTION_EXPORT(dhry_test, dhry test); +/* + **************************************************************************** + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry_1.c (part 2 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * + **************************************************************************** + */ + +#define NUMBER_OF_RUNS 1000000 + +#include "dhry.h" +#define printf rt_kprintf + +/* Global Variables: */ + +Rec_Pointer Ptr_Glob, + Next_Ptr_Glob; +int Int_Glob; +Boolean Bool_Glob; +char Ch_1_Glob, + Ch_2_Glob; +int Arr_1_Glob [50]; +int Arr_2_Glob [50] [50]; + +Enumeration Func_1 (); + +/* forward declaration necessary since Enumeration may not simply be int */ + +#ifndef REG + Boolean Reg = false; +#define REG + /* REG becomes defined as empty */ + /* i.e. no register variables */ +#else + Boolean Reg = true; +#endif + +/* variables for time measurement: */ + +float Begin_Time, + End_Time, + User_Time; +float Microseconds, + Dhrystones_Per_Second; + +/* end of variables for time measurement */ + +void dhry_test(void) +/*****/ + + /* main program, corresponds to procedures */ + /* Main and Proc_0 in the Ada version */ +{ + One_Fifty Int_1_Loc; + REG One_Fifty Int_2_Loc; + One_Fifty Int_3_Loc; + REG char Ch_Index; + Enumeration Enum_Loc; + Str_30 Str_1_Loc; + Str_30 Str_2_Loc; + REG int Run_Index; + REG int Number_Of_Runs; + + /* Initializations */ + + Next_Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type)); + Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type)); + + Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; + Ptr_Glob->Discr = Ident_1; + Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; + Ptr_Glob->variant.var_1.Int_Comp = 40; + rt_strncpy (Ptr_Glob->variant.var_1.Str_Comp, + "DHRYSTONE PROGRAM, SOME STRING", sizeof(Ptr_Glob->variant.var_1.Str_Comp)); + rt_strncpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING", sizeof(Str_1_Loc)); + + Arr_2_Glob [8][7] = 10; + /* Was missing in published program. Without this statement, */ + /* Arr_2_Glob [8][7] would have an undefined value. */ + /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */ + /* overflow may occur for this array element. */ + + printf ("\n"); + printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n"); + printf ("\n"); + if (Reg) + { + printf ("Program compiled with 'register' attribute\n"); + printf ("\n"); + } + else + { + printf ("Program compiled without 'register' attribute\n"); + printf ("\n"); + } + printf ("Please give the number of runs through the benchmark: "); + + Number_Of_Runs = NUMBER_OF_RUNS; + printf ("%d\n", Number_Of_Runs); + + printf ("\n"); + + printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); + + /***************/ + /* Start timer */ + /***************/ + +// Add your timer initializing code here + + Begin_Time = rt_tick_get(); /* get start tick */ + + for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) + { + + Proc_5(); + Proc_4(); + /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */ + Int_1_Loc = 2; + Int_2_Loc = 3; + rt_strncpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING", sizeof(Str_2_Loc)); + Enum_Loc = Ident_2; + Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc); + /* Bool_Glob == 1 */ + while (Int_1_Loc < Int_2_Loc) /* loop body executed once */ + { + Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; + /* Int_3_Loc == 7 */ + Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); + /* Int_3_Loc == 7 */ + Int_1_Loc += 1; + } /* while */ + /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); + /* Int_Glob == 5 */ + Proc_1 (Ptr_Glob); + for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) + /* loop body executed twice */ + { + if (Enum_Loc == Func_1 (Ch_Index, 'C')) + /* then, not executed */ + { + Proc_6 (Ident_1, &Enum_Loc); + rt_strncpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING", sizeof(Str_2_Loc)); + Int_2_Loc = Run_Index; + Int_Glob = Run_Index; + } + } + /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + Int_2_Loc = Int_2_Loc * Int_1_Loc; + Int_1_Loc = Int_2_Loc / Int_3_Loc; + Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; + /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */ + Proc_2 (&Int_1_Loc); + /* Int_1_Loc == 5 */ + + } /* loop "for Run_Index" */ + + /**************/ + /* Stop timer */ + /**************/ + + End_Time = rt_tick_get(); // Get end tick + + printf ("Execution ends\n"); + printf ("\n"); + printf ("Final values of the variables used in the benchmark:\n"); + printf ("\n"); + printf ("Int_Glob: %d\n", Int_Glob); + printf (" should be: %d\n", 5); + printf ("Bool_Glob: %d\n", Bool_Glob); + printf (" should be: %d\n", 1); + printf ("Ch_1_Glob: %c\n", Ch_1_Glob); + printf (" should be: %c\n", 'A'); + printf ("Ch_2_Glob: %c\n", Ch_2_Glob); + printf (" should be: %c\n", 'B'); + printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]); + printf (" should be: %d\n", 7); + printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]); + printf (" should be: Number_Of_Runs + 10\n"); + printf ("Ptr_Glob->\n"); + printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp); + printf (" should be: (implementation-dependent)\n"); + printf (" Discr: %d\n", Ptr_Glob->Discr); + printf (" should be: %d\n", 0); + printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp); + printf (" should be: %d\n", 2); + printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp); + printf (" should be: %d\n", 17); + printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp); + printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); + printf ("Next_Ptr_Glob->\n"); + printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp); + printf (" should be: (implementation-dependent), same as above\n"); + printf (" Discr: %d\n", Next_Ptr_Glob->Discr); + printf (" should be: %d\n", 0); + printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp); + printf (" should be: %d\n", 1); + printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp); + printf (" should be: %d\n", 18); + printf (" Str_Comp: %s\n", + Next_Ptr_Glob->variant.var_1.Str_Comp); + printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); + printf ("Int_1_Loc: %d\n", Int_1_Loc); + printf (" should be: %d\n", 5); + printf ("Int_2_Loc: %d\n", Int_2_Loc); + printf (" should be: %d\n", 13); + printf ("Int_3_Loc: %d\n", Int_3_Loc); + printf (" should be: %d\n", 7); + printf ("Enum_Loc: %d\n", Enum_Loc); + printf (" should be: %d\n", 1); + printf ("Str_1_Loc: %s\n", Str_1_Loc); + printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); + printf ("Str_2_Loc: %s\n", Str_2_Loc); + printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); + printf ("\n"); + + User_Time = (End_Time - Begin_Time) / RT_TICK_PER_SECOND; + + Microseconds = (float) User_Time * Mic_secs_Per_Second + / (float) Number_Of_Runs; + Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time; + + printf ("Microseconds for one run through Dhrystone: "); + printf ("%6d \n", (int)Microseconds); + printf ("Dhrystones per Second: "); + printf ("%6d \n", (int)Dhrystones_Per_Second); + printf ("Dhrystones MIPS: "); + printf ("%6d \n", (int)(Dhrystones_Per_Second / 1757.0)); + printf ("\n"); + +} + +Proc_1 (Ptr_Val_Par) +/******************/ + +REG Rec_Pointer Ptr_Val_Par; + /* executed once */ +{ + REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; + /* == Ptr_Glob_Next */ + /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */ + /* corresponds to "rename" in Ada, "with" in Pascal */ + + structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); + Ptr_Val_Par->variant.var_1.Int_Comp = 5; + Next_Record->variant.var_1.Int_Comp + = Ptr_Val_Par->variant.var_1.Int_Comp; + Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp; + Proc_3 (&Next_Record->Ptr_Comp); + /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp + == Ptr_Glob->Ptr_Comp */ + if (Next_Record->Discr == Ident_1) + /* then, executed */ + { + Next_Record->variant.var_1.Int_Comp = 6; + Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, + &Next_Record->variant.var_1.Enum_Comp); + Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp; + Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, + &Next_Record->variant.var_1.Int_Comp); + } + else /* not executed */ + structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp); +} /* Proc_1 */ + + +Proc_2 (Int_Par_Ref) +/******************/ + /* executed once */ + /* *Int_Par_Ref == 1, becomes 4 */ + +One_Fifty *Int_Par_Ref; +{ + One_Fifty Int_Loc; + Enumeration Enum_Loc; + + Int_Loc = *Int_Par_Ref + 10; + do /* executed once */ + if (Ch_1_Glob == 'A') + /* then, executed */ + { + Int_Loc -= 1; + *Int_Par_Ref = Int_Loc - Int_Glob; + Enum_Loc = Ident_1; + } /* if */ + while (Enum_Loc != Ident_1); /* true */ +} /* Proc_2 */ + + +Proc_3 (Ptr_Ref_Par) +/******************/ + /* executed once */ + /* Ptr_Ref_Par becomes Ptr_Glob */ + +Rec_Pointer *Ptr_Ref_Par; + +{ + if (Ptr_Glob != Null) + /* then, executed */ + *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp; + Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); +} /* Proc_3 */ + + +Proc_4 () /* without parameters */ +/*******/ + /* executed once */ +{ + Boolean Bool_Loc; + + Bool_Loc = Ch_1_Glob == 'A'; + Bool_Glob = Bool_Loc | Bool_Glob; + Ch_2_Glob = 'B'; +} /* Proc_4 */ + + +Proc_5 () /* without parameters */ +/*******/ + /* executed once */ +{ + Ch_1_Glob = 'A'; + Bool_Glob = false; +} /* Proc_5 */ + + + /* Procedure for the assignment of structures, */ + /* if the C compiler doesn't support this feature */ +#ifdef NOSTRUCTASSIGN +memcpy (d, s, l) +register char *d; +register char *s; +register int l; +{ + while (l--) *d++ = *s++; +} +#endif + +#include +FINSH_FUNCTION_EXPORT(dhry_test, dhry test); diff --git a/examples/test/fs_test.c b/examples/test/fs_test.c index bc18a196f1..2404b82e59 100644 --- a/examples/test/fs_test.c +++ b/examples/test/fs_test.c @@ -1,297 +1,297 @@ -/* - * File : fs_test.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://openlab.rt-thread.com/license/LICENSE. - * - * Change Logs: - * Date Author Notes - * 2011-01-02 aozima the first version. - * 2011-03-17 aozima fix some bug. - * 2011-03-18 aozima to dynamic thread. - */ - -#include -#include - -static rt_uint32_t stop_flag = 0; -static rt_thread_t fsrw1_thread = RT_NULL; -static rt_thread_t fsrw2_thread = RT_NULL; - -#define fsrw1_fn "/test1.dat" -#define fsrw1_data_len 120 /* Less than 256 */ -static void fsrw1_thread_entry(void* parameter) -{ - int fd; - int index,length; - rt_uint32_t round; - rt_uint32_t tick_start,tick_end,read_speed,write_speed; - - static rt_uint8_t write_data1[fsrw1_data_len]; - static rt_uint8_t read_data1[fsrw1_data_len]; - - round = 1; - - while(1) - { - if( stop_flag ) - { - rt_kprintf("thread fsrw2 error,thread fsrw1 quit!\r\n"); - fsrw1_thread = RT_NULL; - stop_flag = 0; - return; - } - - /* creat file */ - fd = open(fsrw1_fn, O_WRONLY | O_CREAT | O_TRUNC, 0); - if (fd < 0) - { - rt_kprintf("fsrw1 open file for write failed\n"); - stop_flag = 1; - fsrw1_thread = RT_NULL; - return; - } - - /* plan write data */ - for (index = 0; index < fsrw1_data_len; index ++) - { - write_data1[index] = index; - } - - /* write 8000 times */ - tick_start = rt_tick_get(); - for(index=0; index<8000; index++) - { - length = write(fd, write_data1, fsrw1_data_len); - if (length != fsrw1_data_len) - { - rt_kprintf("fsrw1 write data failed\n"); - close(fd); - fsrw1_thread = RT_NULL; - stop_flag = 1; - return; - } - } - tick_end = rt_tick_get(); - write_speed = fsrw1_data_len*8000UL*RT_TICK_PER_SECOND/(tick_end-tick_start); - - /* close file */ - close(fd); - - /* open file read only */ - fd = open(fsrw1_fn, O_RDONLY, 0); - if (fd < 0) - { - rt_kprintf("fsrw1 open file for read failed\n"); - stop_flag = 1; - fsrw1_thread = RT_NULL; - return; - } - - /* verify data */ - tick_start = rt_tick_get(); - for(index=0; index<8000; index++) - { - rt_uint32_t i; - - length = read(fd, read_data1, fsrw1_data_len); - if (length != fsrw1_data_len) - { - rt_kprintf("fsrw1 read file failed\r\n"); - close(fd); - stop_flag = 1; - fsrw1_thread = RT_NULL; - return; - } - for(i=0; i -FINSH_FUNCTION_EXPORT(fs_test, file system R/W test. e.g: fs_test(3)); -#endif +/* + * File : fs_test.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2011, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2011-01-02 aozima the first version. + * 2011-03-17 aozima fix some bug. + * 2011-03-18 aozima to dynamic thread. + */ + +#include +#include + +static rt_uint32_t stop_flag = 0; +static rt_thread_t fsrw1_thread = RT_NULL; +static rt_thread_t fsrw2_thread = RT_NULL; + +#define fsrw1_fn "/test1.dat" +#define fsrw1_data_len 120 /* Less than 256 */ +static void fsrw1_thread_entry(void* parameter) +{ + int fd; + int index,length; + rt_uint32_t round; + rt_uint32_t tick_start,tick_end,read_speed,write_speed; + + static rt_uint8_t write_data1[fsrw1_data_len]; + static rt_uint8_t read_data1[fsrw1_data_len]; + + round = 1; + + while(1) + { + if( stop_flag ) + { + rt_kprintf("thread fsrw2 error,thread fsrw1 quit!\r\n"); + fsrw1_thread = RT_NULL; + stop_flag = 0; + return; + } + + /* creat file */ + fd = open(fsrw1_fn, O_WRONLY | O_CREAT | O_TRUNC, 0); + if (fd < 0) + { + rt_kprintf("fsrw1 open file for write failed\n"); + stop_flag = 1; + fsrw1_thread = RT_NULL; + return; + } + + /* plan write data */ + for (index = 0; index < fsrw1_data_len; index ++) + { + write_data1[index] = index; + } + + /* write 8000 times */ + tick_start = rt_tick_get(); + for(index=0; index<8000; index++) + { + length = write(fd, write_data1, fsrw1_data_len); + if (length != fsrw1_data_len) + { + rt_kprintf("fsrw1 write data failed\n"); + close(fd); + fsrw1_thread = RT_NULL; + stop_flag = 1; + return; + } + } + tick_end = rt_tick_get(); + write_speed = fsrw1_data_len*8000UL*RT_TICK_PER_SECOND/(tick_end-tick_start); + + /* close file */ + close(fd); + + /* open file read only */ + fd = open(fsrw1_fn, O_RDONLY, 0); + if (fd < 0) + { + rt_kprintf("fsrw1 open file for read failed\n"); + stop_flag = 1; + fsrw1_thread = RT_NULL; + return; + } + + /* verify data */ + tick_start = rt_tick_get(); + for(index=0; index<8000; index++) + { + rt_uint32_t i; + + length = read(fd, read_data1, fsrw1_data_len); + if (length != fsrw1_data_len) + { + rt_kprintf("fsrw1 read file failed\r\n"); + close(fd); + stop_flag = 1; + fsrw1_thread = RT_NULL; + return; + } + for(i=0; i +FINSH_FUNCTION_EXPORT(fs_test, file system R/W test. e.g: fs_test(3)); +#endif diff --git a/examples/test/mem_test.c b/examples/test/mem_test.c index 595578e126..2e94bca2d0 100644 --- a/examples/test/mem_test.c +++ b/examples/test/mem_test.c @@ -1,105 +1,105 @@ -#include - -#include -#include - -#define printf rt_kprintf - -void mem_test(uint32_t address, uint32_t size ) -{ - uint32_t i; - - printf("memtest,address: 0x%08X size: 0x%08X\r\n", address, size); - - /**< 8bit test */ - { - uint8_t * p_uint8_t = (uint8_t *)address; - for(i=0; i -FINSH_FUNCTION_EXPORT(mem_test, mem_test(0xA0000000, 0x00100000) ); -#endif +#include + +#include +#include + +#define printf rt_kprintf + +void mem_test(uint32_t address, uint32_t size ) +{ + uint32_t i; + + printf("memtest,address: 0x%08X size: 0x%08X\r\n", address, size); + + /**< 8bit test */ + { + uint8_t * p_uint8_t = (uint8_t *)address; + for(i=0; i +FINSH_FUNCTION_EXPORT(mem_test, mem_test(0xA0000000, 0x00100000) ); +#endif diff --git a/examples/test/net_test.c b/examples/test/net_test.c index 849b03bbcc..e4961622c7 100644 --- a/examples/test/net_test.c +++ b/examples/test/net_test.c @@ -1,282 +1,282 @@ -/* - * Net Test Utilities for RT-Thread - */ -#include -#include -#include -#include -/* - * UDP echo server - */ -#define UDP_ECHO_PORT 7 -rt_thread_t udpecho_tid = RT_NULL; -void udpecho_entry(void *parameter) -{ - struct netconn *conn; - struct netbuf *buf; - struct ip_addr *addr; - unsigned short port; - - conn = netconn_new(NETCONN_UDP); - netconn_bind(conn, IP_ADDR_ANY, 7); - - while(1) - { - /* received data to buffer */ - buf = netconn_recv(conn); - - addr = netbuf_fromaddr(buf); - port = netbuf_fromport(buf); - - /* send the data to buffer */ - netconn_connect(conn, addr, port); - - /* reset address, and send to client */ - buf->addr = RT_NULL; - netconn_send(conn, buf); - - /* release buffer */ - netbuf_delete(buf); - } -} -/* - * UDP socket echo server - */ -#define UDP_SOCKET_ECHO_PORT 700 -#define UDP_SOCKET_BUFFER_SIZE 4096 -rt_thread_t udpecho_socket_tid = RT_NULL; -void udpecho_socket_entry(void *parameter) -{ - int sock; - int bytes_read; - char *recv_data; - rt_uint32_t addr_len; - struct sockaddr_in server_addr, client_addr; - - /* allocate the data buffer */ - recv_data = rt_malloc(UDP_SOCKET_BUFFER_SIZE); - if (recv_data == RT_NULL) - { - /* no memory yet */ - rt_kprintf("no memory\n"); - goto _exit; - } - /* create a UDP socket */ - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) - { - rt_kprintf("create socket error\n"); - goto _exit; - } - - /* initialize server address */ - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(UDP_SOCKET_ECHO_PORT); - server_addr.sin_addr.s_addr = INADDR_ANY; - rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero)); - - /* bind socket to server address */ - if (bind(sock,(struct sockaddr *)&server_addr, - sizeof(struct sockaddr)) == -1) - { - /* bind failed */ - rt_kprintf("bind error\n"); - goto _exit; - } - - addr_len = sizeof(struct sockaddr); - while (1) - { - /* try to receive from UDP socket */ - bytes_read = recvfrom(sock, recv_data, UDP_SOCKET_BUFFER_SIZE, 0, - (struct sockaddr *)&client_addr, &addr_len); - - /* send back */ - sendto(sock, recv_data, bytes_read, 0, - (struct sockaddr *)&client_addr, addr_len); - } - -_exit: - rt_free(recv_data); - return; -} - -/* - * TCP echo server - */ -#define TCP_ECHO_PORT 7 -rt_thread_t tcpecho_tid = RT_NULL; -void tcpecho_entry(void *parameter) -{ - struct netconn *conn, *newconn; - err_t err; - - /* Create a new connection identifier. */ - conn = netconn_new(NETCONN_TCP); - - /* Bind connection to well known port number 7. */ - netconn_bind(conn, NULL, TCP_ECHO_PORT); - - /* Tell connection to go into listening mode. */ - netconn_listen(conn); - - while(1) - { - /* Grab new connection. */ - newconn = netconn_accept(conn); - /* Process the new connection. */ - if(newconn != NULL) - { - struct netbuf *buf; - void *data; - u16_t len; - - while((buf = netconn_recv(newconn)) != NULL) - { - do - { - netbuf_data(buf, &data, &len); - err = netconn_write(newconn, data, len, NETCONN_COPY); - if(err != ERR_OK){} - } - while(netbuf_next(buf) >= 0); - netbuf_delete(buf); - } - /* Close connection and discard connection identifier. */ - netconn_delete(newconn); - } - } -} - -/* - * TCP socket echo server - */ -#define TCP_SOCKET_ECHO_PORT 700 -#define TCP_SOCKET_BUFFER_SIZE 4096 -rt_thread_t tcpecho_socket_tid = RT_NULL; -void tcpecho_socket_entry(void *parameter) -{ - char *recv_data; - rt_uint32_t sin_size; - int sock = -1, connected, bytes_received; - struct sockaddr_in server_addr, client_addr; - - recv_data = rt_malloc(TCP_SOCKET_BUFFER_SIZE); - if (recv_data == RT_NULL) - { - rt_kprintf("no memory\n"); - goto _exit; - } - - /* create a TCP socket */ - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) - { - rt_kprintf("create socket error\n"); - goto _exit; - } - - /* initialize server address */ - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(TCP_SOCKET_ECHO_PORT); - server_addr.sin_addr.s_addr = INADDR_ANY; - rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero)); - - /* bind to server address */ - if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) - { - rt_kprintf("bind address failed\n"); - goto _exit; - } - - /* listen */ - if (listen(sock, 5) == -1) - { - rt_kprintf("listen error\n"); - goto _exit; - } - - sin_size = sizeof(struct sockaddr_in); - while(1) - { - /* accept client connected */ - connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); - if (connected > 0) - { - int timeout; - - /* set timeout option */ - timeout = 5000; /* 5second */ - setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - - /* handle this client */ - while (1) - { - /* receive data from this connection */ - bytes_received = recv(connected,recv_data, TCP_SOCKET_BUFFER_SIZE, 0); - if (bytes_received <= 0) - { - rt_kprintf("close client connection, errno: %d, socket error: %d\n", - rt_get_errno(), - lwip_get_error()); - /* connection closed. */ - lwip_close(connected); - break; - } - - /* send data to client */ - send(connected, recv_data, bytes_received, 0); - } - } - } - -_exit: - /* close socket */ - if (sock != -1) lwip_close(sock); - rt_free(recv_data); - - return ; -} - -/* - * NetIO TCP server - */ - -/* network test utilities entry */ -void net_test(void) -{ - /* start UDP echo server */ - if (udpecho_tid == RT_NULL) - { - udpecho_tid = rt_thread_create("uecho", - udpecho_entry, RT_NULL, - 512, RT_THREAD_PRIORITY_MAX/2, 5); - if (udpecho_tid != RT_NULL) - rt_thread_startup(udpecho_tid); - } - if (udpecho_socket_tid == RT_NULL) - { - udpecho_socket_tid = rt_thread_create("uecho_s", - udpecho_socket_entry, RT_NULL, - 512, RT_THREAD_PRIORITY_MAX/2 + 1, 5); - if (udpecho_socket_tid != RT_NULL) - rt_thread_startup(udpecho_socket_tid); - } - - if (tcpecho_tid == RT_NULL) - { - tcpecho_tid = rt_thread_create("techo", - tcpecho_entry, RT_NULL, - 512, RT_THREAD_PRIORITY_MAX/2 + 2, 5); - if (tcpecho_tid != RT_NULL) - rt_thread_startup(tcpecho_tid); - } - if (tcpecho_socket_tid == RT_NULL) - { - tcpecho_socket_tid = rt_thread_create("techo_s", - tcpecho_socket_entry, RT_NULL, - 512, RT_THREAD_PRIORITY_MAX/2 + 3, 5); - if (tcpecho_socket_tid != RT_NULL) - rt_thread_startup(tcpecho_socket_tid); - } -} -FINSH_FUNCTION_EXPORT(net_test, network test); - +/* + * Net Test Utilities for RT-Thread + */ +#include +#include +#include +#include +/* + * UDP echo server + */ +#define UDP_ECHO_PORT 7 +rt_thread_t udpecho_tid = RT_NULL; +void udpecho_entry(void *parameter) +{ + struct netconn *conn; + struct netbuf *buf; + struct ip_addr *addr; + unsigned short port; + + conn = netconn_new(NETCONN_UDP); + netconn_bind(conn, IP_ADDR_ANY, 7); + + while(1) + { + /* received data to buffer */ + buf = netconn_recv(conn); + + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + + /* send the data to buffer */ + netconn_connect(conn, addr, port); + + /* reset address, and send to client */ + buf->addr = RT_NULL; + netconn_send(conn, buf); + + /* release buffer */ + netbuf_delete(buf); + } +} +/* + * UDP socket echo server + */ +#define UDP_SOCKET_ECHO_PORT 700 +#define UDP_SOCKET_BUFFER_SIZE 4096 +rt_thread_t udpecho_socket_tid = RT_NULL; +void udpecho_socket_entry(void *parameter) +{ + int sock; + int bytes_read; + char *recv_data; + rt_uint32_t addr_len; + struct sockaddr_in server_addr, client_addr; + + /* allocate the data buffer */ + recv_data = rt_malloc(UDP_SOCKET_BUFFER_SIZE); + if (recv_data == RT_NULL) + { + /* no memory yet */ + rt_kprintf("no memory\n"); + goto _exit; + } + /* create a UDP socket */ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + { + rt_kprintf("create socket error\n"); + goto _exit; + } + + /* initialize server address */ + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(UDP_SOCKET_ECHO_PORT); + server_addr.sin_addr.s_addr = INADDR_ANY; + rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero)); + + /* bind socket to server address */ + if (bind(sock,(struct sockaddr *)&server_addr, + sizeof(struct sockaddr)) == -1) + { + /* bind failed */ + rt_kprintf("bind error\n"); + goto _exit; + } + + addr_len = sizeof(struct sockaddr); + while (1) + { + /* try to receive from UDP socket */ + bytes_read = recvfrom(sock, recv_data, UDP_SOCKET_BUFFER_SIZE, 0, + (struct sockaddr *)&client_addr, &addr_len); + + /* send back */ + sendto(sock, recv_data, bytes_read, 0, + (struct sockaddr *)&client_addr, addr_len); + } + +_exit: + rt_free(recv_data); + return; +} + +/* + * TCP echo server + */ +#define TCP_ECHO_PORT 7 +rt_thread_t tcpecho_tid = RT_NULL; +void tcpecho_entry(void *parameter) +{ + struct netconn *conn, *newconn; + err_t err; + + /* Create a new connection identifier. */ + conn = netconn_new(NETCONN_TCP); + + /* Bind connection to well known port number 7. */ + netconn_bind(conn, NULL, TCP_ECHO_PORT); + + /* Tell connection to go into listening mode. */ + netconn_listen(conn); + + while(1) + { + /* Grab new connection. */ + newconn = netconn_accept(conn); + /* Process the new connection. */ + if(newconn != NULL) + { + struct netbuf *buf; + void *data; + u16_t len; + + while((buf = netconn_recv(newconn)) != NULL) + { + do + { + netbuf_data(buf, &data, &len); + err = netconn_write(newconn, data, len, NETCONN_COPY); + if(err != ERR_OK){} + } + while(netbuf_next(buf) >= 0); + netbuf_delete(buf); + } + /* Close connection and discard connection identifier. */ + netconn_delete(newconn); + } + } +} + +/* + * TCP socket echo server + */ +#define TCP_SOCKET_ECHO_PORT 700 +#define TCP_SOCKET_BUFFER_SIZE 4096 +rt_thread_t tcpecho_socket_tid = RT_NULL; +void tcpecho_socket_entry(void *parameter) +{ + char *recv_data; + rt_uint32_t sin_size; + int sock = -1, connected, bytes_received; + struct sockaddr_in server_addr, client_addr; + + recv_data = rt_malloc(TCP_SOCKET_BUFFER_SIZE); + if (recv_data == RT_NULL) + { + rt_kprintf("no memory\n"); + goto _exit; + } + + /* create a TCP socket */ + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + rt_kprintf("create socket error\n"); + goto _exit; + } + + /* initialize server address */ + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(TCP_SOCKET_ECHO_PORT); + server_addr.sin_addr.s_addr = INADDR_ANY; + rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero)); + + /* bind to server address */ + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) + { + rt_kprintf("bind address failed\n"); + goto _exit; + } + + /* listen */ + if (listen(sock, 5) == -1) + { + rt_kprintf("listen error\n"); + goto _exit; + } + + sin_size = sizeof(struct sockaddr_in); + while(1) + { + /* accept client connected */ + connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); + if (connected > 0) + { + int timeout; + + /* set timeout option */ + timeout = 5000; /* 5second */ + setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + + /* handle this client */ + while (1) + { + /* receive data from this connection */ + bytes_received = recv(connected,recv_data, TCP_SOCKET_BUFFER_SIZE, 0); + if (bytes_received <= 0) + { + rt_kprintf("close client connection, errno: %d, socket error: %d\n", + rt_get_errno(), + lwip_get_error()); + /* connection closed. */ + lwip_close(connected); + break; + } + + /* send data to client */ + send(connected, recv_data, bytes_received, 0); + } + } + } + +_exit: + /* close socket */ + if (sock != -1) lwip_close(sock); + rt_free(recv_data); + + return ; +} + +/* + * NetIO TCP server + */ + +/* network test utilities entry */ +void net_test(void) +{ + /* start UDP echo server */ + if (udpecho_tid == RT_NULL) + { + udpecho_tid = rt_thread_create("uecho", + udpecho_entry, RT_NULL, + 512, RT_THREAD_PRIORITY_MAX/2, 5); + if (udpecho_tid != RT_NULL) + rt_thread_startup(udpecho_tid); + } + if (udpecho_socket_tid == RT_NULL) + { + udpecho_socket_tid = rt_thread_create("uecho_s", + udpecho_socket_entry, RT_NULL, + 512, RT_THREAD_PRIORITY_MAX/2 + 1, 5); + if (udpecho_socket_tid != RT_NULL) + rt_thread_startup(udpecho_socket_tid); + } + + if (tcpecho_tid == RT_NULL) + { + tcpecho_tid = rt_thread_create("techo", + tcpecho_entry, RT_NULL, + 512, RT_THREAD_PRIORITY_MAX/2 + 2, 5); + if (tcpecho_tid != RT_NULL) + rt_thread_startup(tcpecho_tid); + } + if (tcpecho_socket_tid == RT_NULL) + { + tcpecho_socket_tid = rt_thread_create("techo_s", + tcpecho_socket_entry, RT_NULL, + 512, RT_THREAD_PRIORITY_MAX/2 + 3, 5); + if (tcpecho_socket_tid != RT_NULL) + rt_thread_startup(tcpecho_socket_tid); + } +} +FINSH_FUNCTION_EXPORT(net_test, network test); + -- cgit v1.3.1