提交 4c463f27 编写于 作者: G geniusgogo

Merge branch 'master' into SQLite_on_ARMCC

...@@ -7,17 +7,9 @@ if os.getenv('RTT_ROOT'): ...@@ -7,17 +7,9 @@ if os.getenv('RTT_ROOT'):
else: else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
if os.getenv('RTT_RTGUI'):
RTT_RTGUI = os.getenv('RTT_RTGUI')
else:
# set the rtgui root directory by hand
# empty string means use the RTGUI in svn
RTT_RTGUI = os.path.normpath(r'F:\Project\git\rt-gui\components\rtgui')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import * from building import *
env = Environment(TARGET_ARCH='x86') env = Environment(TARGET_ARCH='x86')
Export('RTT_ROOT') Export('RTT_ROOT')
...@@ -84,32 +76,7 @@ else: ...@@ -84,32 +76,7 @@ else:
# prepare building environment # prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False, remove_components=['rtgui']) objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
if GetDepend('RT_USING_RTGUI'):
try:
if RTT_RTGUI:
objs += SConscript(os.path.join(RTT_RTGUI, 'SConscript'),
variant_dir='build/components/rtgui',
duplicate=0)
objs = objs + SConscript(RTT_RTGUI+'/../../demo/examples/SConscript',
variant_dir='build/examples/gui', duplicate=0)
else:
objs += SConscript(os.path.join(RTT_ROOT + '/components/rtgui', 'SConscript'),
variant_dir='build/components/rtgui',
duplicate=0)
objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript',
variant_dir='build/examples/gui', duplicate=0)
except:
print
print 'RTGUI configuration is invalid!'
print 'RT_USING_RTGUI is enabled in rtconfig.h, but scons cannot find '+\
'RTGUI source code. In order to eliminate this error, you can '+\
'add RTT_RTGUI in environment to point RTGUI source code, or '+\
'disable RT_USING_RTGUI in rtconfig.h'
exit(-1);
if GetDepend('RT_USING_TC'):
objs = objs + SConscript(RTT_ROOT + '/examples/kernel/SConscript', variant_dir = 'build/tc/kernel', duplicate=0)
def ObjRemove(objs, remove): def ObjRemove(objs, remove):
for item in objs: for item in objs:
......
...@@ -40,10 +40,6 @@ void rt_init_thread_entry(void *parameter) ...@@ -40,10 +40,6 @@ void rt_init_thread_entry(void *parameter)
rt_hw_sdl_start(); rt_hw_sdl_start();
#endif /* RT_USING_RTGUI */ #endif /* RT_USING_RTGUI */
#if defined(RT_USING_COMPONENTS_INIT) && defined(__GNUC__) && defined(RT_USING_FINSH)
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* File system Initialization */ /* File system Initialization */
#ifdef RT_USING_DFS #ifdef RT_USING_DFS
{ {
...@@ -94,17 +90,6 @@ void rt_init_thread_entry(void *parameter) ...@@ -94,17 +90,6 @@ void rt_init_thread_entry(void *parameter)
#endif #endif
} }
static void rt_test_thread_entry(void *parameter)
{
int i;
for (i = 0; i < 5; i++)
{
rt_kprintf("hello, world\n");
rt_thread_delay(RT_TICK_PER_SECOND);
}
}
int rt_application_init() int rt_application_init()
{ {
rt_thread_t tid; rt_thread_t tid;
...@@ -116,12 +101,6 @@ int rt_application_init() ...@@ -116,12 +101,6 @@ int rt_application_init()
if (tid != RT_NULL) if (tid != RT_NULL)
rt_thread_startup(tid); rt_thread_startup(tid);
tid = rt_thread_create("test",
rt_test_thread_entry, RT_NULL,
2048, RT_THREAD_PRIORITY_MAX * 3 / 4, 20);
if (tid != RT_NULL)
rt_thread_startup(tid);
return 0; return 0;
} }
......
说明: 本BSP可以如下演示 说明: 本BSP可以如下演示
依赖软件包 依赖软件包
python2.7 (python2.6使用scons --target=vs -s生成工程会出现错误) python2.7 (python2.6无法生成vs工程)
一 平台及组件支持 一 平台及组件支持
目前rtconfig.py中支持的编译器有 目前rtconfig.py中支持的编译器有
1). msvc 用于windows平台 1). msvc 用于windows平台
此平台支持的组件 此平台支持的组件
kernel kernel
...@@ -24,38 +25,21 @@ ...@@ -24,38 +25,21 @@
DFS, ELM FatFS, UFFS DFS, ELM FatFS, UFFS
RTGUI RTGUI
请根据自己的实际情况,修改rtconfig.py中CROSS_TOOL为上述某一值。
二 组件配置 二 组件配置
1) RTGUI 1) RTGUI
当前代码中已经不含RTGUI源码,因此读者需要配置一下才能在simulator中使用RTGUI RTGUI的最新源码目前托管在github上:https://github.com/RT-Thread/RTGUI
RTGUI的最新源码目前是托管在github上:https://github.com/RT-Thread/RTGUI 下载最新的RTGUI源码,将RTGUI源码包中components下的rtgui目录复制到Rt-thread的components目录下。
共有两种方法。
方法1 添加环境变量
向系统加入RTT_RTGUI环境变量,其值为刚才github上下载的rtgui源码包的路径。
例如笔者的rtgui源码包解压至 F:\Project\git\rt-gui\下, 则将此环境变量配置为 F:\Project\git\rt-gui\components\rtgui
方法2 不添加环境变量
打开SConstruct文件,
....
10 if os.getenv('RTT_RTGUI'):
11 RTT_RTGUI = os.getenv('RTT_RTGUI')
12 else:
13 # set the rtgui root directory by hand
14 # empty string means use the RTGUI in svn
15 # RTT_RTGUI = os.path.normpath(r'F:\Project\git\rt-gui\components\rtgui')
16 RTT_RTGUI =''
....
将15,16行修改为
14 # empty string means use the RTGUI in svn
15 RTT_RTGUI = os.path.normpath(r'F:\Project\git\rt-gui\components\rtgui')
16 # RTT_RTGUI =''
简单说明一下:
1)#号表示注释,类似于c语言中的//,
2)其中15行的路径为你的RTGUI路径源码,注意不是压缩包路径,而是压缩包路径下的 components\rtgui目录的绝对路径。
三 编译 三 编译
1) 使用Visual Studio(2005以上版本) 1) 使用Visual Studio(2005以上版本)
在当前目录中打开cmd,输入命令 在当前目录中打开cmd,输入命令
`scons --target=vs -s` `scons --target=vs -s`
可以生成project.vsproj,双击运行 生成vs2005的project.vsproj,使用vs2005及以上版本可以打开(VS2005需要转换工程)。
或直接生成vs2012工程
`scons --target=vs2012 -s`
2) 命令行编译 2) 命令行编译
修改rtconfig.py, 配置合适的编译器(msvc/mingw/gcc),及其路径 修改rtconfig.py, 配置合适的编译器(msvc/mingw/gcc),及其路径
...@@ -73,31 +57,23 @@ RTGUI的最新源码目前是托管在github上:https://github.com/RT-Thread/R ...@@ -73,31 +57,23 @@ RTGUI的最新源码目前是托管在github上:https://github.com/RT-Thread/R
按下回车,出现finsh,然后输入`mkfs("elm", "sd0")`格式化SD卡,如下所示 按下回车,出现finsh,然后输入`mkfs("elm", "sd0")`格式化SD卡,如下所示
finsh>>mkfs("elm", "sd0") finsh>>mkfs("elm", "sd0")
0, 0x00000000 0, 0x00000000
然后重启程序,就可以看到fatfs挂载成功了 重启程序,可以正确挂载fat文件系统。
2) 测试RTGUI 2) 测试RTGUI
启动后就会看到GUI窗口,分辨率800x480,此时在finsh中输入snake_main()并回车,即可运行贪吃蛇程序 打开RTGUI组件后编译,启动在finsh中输入snake_main()并回车,可运行贪吃蛇程序
3) 测试APP module 3) 测试APP module
rtconfig.h中需要打开RT_USING_MODULE 在rtconfig.h中打开RT_USING_MODULE
测试app module需要执行3步,如下a, b, c所示。
a. 生成rtthread.def文件 a. 生成rtthread.def文件
使用msv编译主程序时需要此文件,使用MingW编译主程序时不需要 执行`scons --def`可以自动生成rtthread.def。
msvc需要此文件才能生成正确导出符号的rtthread.dll和rtthread-win32.exe。 当修改了rtconfig.h,打开或禁用了某些组件时,需要重新生成rtthread.def文件.
此目录下默认自带了一个rtthread.def文件,当修改了rtconfig.h,禁用了某些组件时,则需要重新生成rtthread.def文件.
生成方法:
需要借助MingW工具,修改rtconfig.py中CROSS_TOOL为'mingw',然后打开CMD执行`scons --def`就会自动更新rtthread.def。
b. 生成主程序 b. 生成主程序
主程序可以使用msvc和mingw生成
如果rtconfig.h中的使能了RTGUI,则需要参考第二节第1小节配置RTGUI `scons -j4`
a.1 使用msvc
修改rtconfig.py中CROSS_TOOL为'msvc'
首先要保证当前目录下有合适的rtthread.def文件,如果没有对默认的rtconfig.h作修改,则使用默认的rtthread.def即可
CMD命令行执行`scons -j4`,即可生成rtthread.dll和 rtthread-win32.exe
a.2 使用mingw
修改rtconfig.py中CROSS_TOOL为'mingw'
CMD命令行执行`scons -j4`,这就会生成 rtthread.dll和 rtthread-win32.exe
c. 生成app module c. 生成app module
进入testdll目录,再次修改 testdll/SConstruct, 同样需要配置RTT_RTGUI路径,同 1中3) 进入testdll目录,再次修改 testdll/SConstruct, 同样需要配置RTT_RTGUI路径,同 1中3)
...@@ -107,8 +83,8 @@ c. 生成app module ...@@ -107,8 +83,8 @@ c. 生成app module
然后运行simulator目录下的 rtthread-win32.exe, 在finsh中运行 然后运行simulator目录下的 rtthread-win32.exe, 在finsh中运行
`exec("/testdll/basicapp/build/basicapp.dll")` `exec("/testdll/basicapp/build/basicapp.dll")`
如果觉得这个路径太长,就把 basicapp.dll复制到 simualtor目录下,执行 如果觉得这个路径太长,可以将basicapp.dll复制到 simualtor目录下,执行
`exec("/basicapp.dll")` `exec("/basicapp.dll")`
编译贪吃蛇程序 编译贪吃蛇程序
执行`scons --app=snake`,会在snake/build/下生成snake.dll,按照同样的方式加载即可 执行`scons --app=snake`,会在snake/build/下生成snake.dll,按照同样的方式加载即可
...@@ -209,7 +209,7 @@ ...@@ -209,7 +209,7 @@
#define RT_LWIP_TCP_WND 8192 #define RT_LWIP_TCP_WND 8192
/* SECTION: RT-Thread/GUI */ /* SECTION: RT-Thread/GUI */
#define RT_USING_RTGUI /* #define RT_USING_RTGUI */
/* name length of RTGUI object */ /* name length of RTGUI object */
#define RTGUI_NAME_MAX 12 #define RTGUI_NAME_MAX 12
......
...@@ -108,12 +108,8 @@ ...@@ -108,12 +108,8 @@
#if _MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096 #if _MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096
#error Wrong sector size. #error Wrong sector size.
#endif #endif
#if _MAX_SS != 512
#define SS(fs) ((fs)->ssize) /* Multiple sector size */
#else
#define SS(fs) 512U /* Fixed sector size */
#endif
#define SS(fs) ((fs)->ssize) /* sector size */
/* Reentrancy related */ /* Reentrancy related */
#if _FS_REENTRANT #if _FS_REENTRANT
...@@ -2058,10 +2054,11 @@ FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ ...@@ -2058,10 +2054,11 @@ FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */
stat = disk_initialize(fs->drv); /* Initialize low level disk I/O layer */ stat = disk_initialize(fs->drv); /* Initialize low level disk I/O layer */
if (stat & STA_NOINIT) /* Check if the initialization succeeded */ if (stat & STA_NOINIT) /* Check if the initialization succeeded */
return FR_NOT_READY; /* Failed to initialize due to no media or hard error */ return FR_NOT_READY; /* Failed to initialize due to no media or hard error */
#if _MAX_SS != 512 /* Get disk sector size (variable sector size cfg only) */
/* Get disk sector size (variable sector size cfg only) */
if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK) if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK)
return FR_DISK_ERR; return FR_DISK_ERR;
#endif
#if !_FS_READONLY #if !_FS_READONLY
if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */ if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */
return FR_WRITE_PROTECTED; return FR_WRITE_PROTECTED;
...@@ -3601,10 +3598,10 @@ FRESULT f_mkfs ( ...@@ -3601,10 +3598,10 @@ FRESULT f_mkfs (
stat = disk_initialize(drv); stat = disk_initialize(drv);
if (stat & STA_NOINIT) return FR_NOT_READY; if (stat & STA_NOINIT) return FR_NOT_READY;
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
#if _MAX_SS != 512 /* Get disk sector size */ /* Get disk sector size */
if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK)
return FR_DISK_ERR; return FR_DISK_ERR;
#endif
if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128)
return FR_DISK_ERR; return FR_DISK_ERR;
b_vol = (sfd) ? 0 : 63; /* Volume start sector */ b_vol = (sfd) ? 0 : 63; /* Volume start sector */
......
...@@ -84,9 +84,7 @@ typedef struct { ...@@ -84,9 +84,7 @@ typedef struct {
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
WORD id; /* File system mount ID */ WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
#if _MAX_SS != 512
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */ WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
#endif
#if _FS_REENTRANT #if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */ _SYNC_t sobj; /* Identifier of sync object */
#endif #endif
......
...@@ -37,48 +37,36 @@ ...@@ -37,48 +37,36 @@
* *
* @param ops the file system instance to be registered. * @param ops the file system instance to be registered.
* *
* @return 0 on successful, -1 on failed. * @return RT_EOK on successful, -RT_ERROR on failed.
*/ */
int dfs_register(const struct dfs_filesystem_operation *ops) int dfs_register(const struct dfs_filesystem_operation *ops)
{ {
int index, result; int ret = RT_EOK;
int free_index; const struct dfs_filesystem_operation **empty = RT_NULL;
const struct dfs_filesystem_operation **iter;
result = 0;
free_index = DFS_FILESYSTEM_TYPES_MAX;
/* lock filesystem */ /* lock filesystem */
dfs_lock(); dfs_lock();
/* check if this filesystem was already registered */ /* check if this filesystem was already registered */
for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++) for (iter = &filesystem_operation_table[0];
{ iter < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; iter ++)
if (filesystem_operation_table[index] == RT_NULL)
{ {
/* find out an empty filesystem type entry */ /* find out an empty filesystem type entry */
if (free_index == DFS_FILESYSTEM_TYPES_MAX) if (*iter == RT_NULL)
free_index = index; (empty == RT_NULL) ? (empty = iter) : 0;
} else if (strcmp((*iter)->name, ops->name) == 0)
else if (strcmp(filesystem_operation_table[index]->name, ops->name) == 0)
{ {
result = -1; ret = -1;
goto err; break;
}
} }
/* filesystem type table full */
if (free_index == DFS_FILESYSTEM_TYPES_MAX)
{
result = -1;
goto err;
} }
/* save the filesystem's operations */ /* save the filesystem's operations */
filesystem_operation_table[free_index] = ops; if ((ret == RT_EOK) && (empty != RT_NULL))
*empty = ops;
err:
dfs_unlock(); dfs_unlock();
return result; return ret;
} }
/** /**
...@@ -91,38 +79,34 @@ err: ...@@ -91,38 +79,34 @@ err:
*/ */
struct dfs_filesystem *dfs_filesystem_lookup(const char *path) struct dfs_filesystem *dfs_filesystem_lookup(const char *path)
{ {
struct dfs_filesystem *fs; struct dfs_filesystem *iter;
rt_uint32_t index, fspath, prefixlen; struct dfs_filesystem *fs = RT_NULL;
rt_uint32_t fspath, prefixlen;
fs = RT_NULL;
prefixlen = 0; prefixlen = 0;
/* lock filesystem */ /* lock filesystem */
dfs_lock(); dfs_lock();
/* lookup it in the filesystem table */ /* lookup it in the filesystem table */
for (index = 0; index < DFS_FILESYSTEMS_MAX; index++) for (iter = &filesystem_table[0];
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
{ {
if (filesystem_table[index].path == RT_NULL) if ((iter->path == RT_NULL) || (iter->ops == RT_NULL))
continue; continue;
else
{ fspath = strlen(iter->path);
fspath = strlen(filesystem_table[index].path); if ((fspath < prefixlen)
if (fspath < prefixlen) || (strncmp(iter->path, path, fspath) != 0))
continue; continue;
}
if ((filesystem_table[index].ops != RT_NULL) &&
(strncmp(filesystem_table[index].path, path, fspath) == 0))
{
/* check next path separator */ /* check next path separator */
if (fspath > 1 && (strlen(path) > fspath) && (path[fspath] != '/')) if (fspath > 1 && (strlen(path) > fspath) && (path[fspath] != '/'))
continue; continue;
fs = &filesystem_table[index]; fs = iter;
prefixlen = fspath; prefixlen = fspath;
} }
}
dfs_unlock(); dfs_unlock();
...@@ -147,64 +131,42 @@ rt_err_t dfs_filesystem_get_partition(struct dfs_partition *part, ...@@ -147,64 +131,42 @@ rt_err_t dfs_filesystem_get_partition(struct dfs_partition *part,
rt_uint8_t *dpt; rt_uint8_t *dpt;
rt_uint8_t type; rt_uint8_t type;
rt_err_t result;
RT_ASSERT(part != RT_NULL); RT_ASSERT(part != RT_NULL);
RT_ASSERT(buf != RT_NULL); RT_ASSERT(buf != RT_NULL);
result = RT_EOK;
dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE; dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
/* check if it is a valid partition table */
if ((*dpt != 0x80) && (*dpt != 0x00)) if ((*dpt != 0x80) && (*dpt != 0x00))
{ return -RT_ERROR;
/* which is not a partition table */
result = -RT_ERROR;
return result;
}
/* get partition type */ /* get partition type */
type = *(dpt+4); type = *(dpt+4);
if (type == 0)
return -RT_ERROR;
if (type != 0) /* set partition information
{ * size is the number of 512-Byte */
/* set partition type */
part->type = type; part->type = type;
/* get partition offset and size */
part->offset = *(dpt+8) | *(dpt+9)<<8 | *(dpt+10)<<16 | *(dpt+11)<<24; part->offset = *(dpt+8) | *(dpt+9)<<8 | *(dpt+10)<<16 | *(dpt+11)<<24;
part->size = *(dpt+12) | *(dpt+13)<<8 | *(dpt+14)<<16 | *(dpt+15)<<24; part->size = *(dpt+12) | *(dpt+13)<<8 | *(dpt+14)<<16 | *(dpt+15)<<24;
rt_kprintf("found part[%d], begin: %d, size: ", rt_kprintf("found part[%d], begin: %d, size: ",
pindex, part->offset*512); pindex, part->offset*512);
if ((part->size>>11) > 0) /* MB */ if ((part->size>>11) == 0)
{ rt_kprintf("%d%s",part->size>>1,"KB\n"); /* KB */
unsigned int part_size;
part_size = part->size >> 11;/* MB */
if ((part_size>>10) > 0) /* GB */
{
/* GB */
rt_kprintf("%d.%d%s",part_size>>10,part_size&0x3FF,"GB\r\n");
}
else else
{ {
/* MB */ unsigned int part_size;
rt_kprintf("%d.%d%s",part_size,(part->size>>1)&0x3FF,"MB\r\n"); part_size = part->size >> 11; /* MB */
} if ((part_size>>10) == 0)
} rt_kprintf("%d.%d%s",part_size,(part->size>>1)&0x3FF,"MB\n");
else
{
/* KB */
rt_kprintf("%d%s",part->size>>1,"KB\r\n");
}
}
else else
{ rt_kprintf("%d.%d%s",part_size>>10,part_size&0x3FF,"GB\n");
result = -RT_ERROR;
} }
return result; return RT_EOK;
} }
/** /**
...@@ -224,57 +186,54 @@ int dfs_mount(const char *device_name, ...@@ -224,57 +186,54 @@ int dfs_mount(const char *device_name,
unsigned long rwflag, unsigned long rwflag,
const void *data) const void *data)
{ {
const struct dfs_filesystem_operation *ops; const struct dfs_filesystem_operation **ops;
struct dfs_filesystem *fs; struct dfs_filesystem *iter;
char *fullpath=RT_NULL; struct dfs_filesystem *fs = RT_NULL;
char *fullpath = RT_NULL;
rt_device_t dev_id; rt_device_t dev_id;
int index, free_index;
/* open specific device */ /* open specific device */
if (device_name != RT_NULL) if (device_name == RT_NULL)
{ {
dev_id = rt_device_find(device_name); /* which is a non-device filesystem mount */
if (dev_id == RT_NULL) dev_id = NULL;
}
else if ((dev_id = rt_device_find(device_name)) == RT_NULL)
{ {
/* no this device */ /* no this device */
rt_set_errno(-DFS_STATUS_ENODEV); rt_set_errno(-DFS_STATUS_ENODEV);
return -1; return -1;
} }
}
else
{
/* which is a non-device filesystem mount */
dev_id = RT_NULL;
}
/* find out specific filesystem */ /* find out the specific filesystem */
dfs_lock(); dfs_lock();
for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++)
{
if (filesystem_operation_table[index] == RT_NULL)
continue;
if (strcmp(filesystem_operation_table[index]->name, filesystemtype) == 0) for (ops = &filesystem_operation_table[0];
ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++)
if ((ops != RT_NULL) && (strcmp((*ops)->name, filesystemtype) == 0))
break; break;
}
dfs_unlock(); dfs_unlock();
/* can't find filesystem */ if (ops == &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX])
if (index == DFS_FILESYSTEM_TYPES_MAX)
{ {
/* can't find filesystem */
rt_set_errno(-DFS_STATUS_ENODEV); rt_set_errno(-DFS_STATUS_ENODEV);
return -1;
}
/* check if there is mount implementation */
if ((*ops == NULL) || ((*ops)->mount == NULL))
{
rt_set_errno(-DFS_STATUS_ENOSYS);
return -1; return -1;
} }
ops = filesystem_operation_table[index];
/* make full path for special file */ /* make full path for special file */
fullpath = dfs_normalize_path(RT_NULL, path); fullpath = dfs_normalize_path(RT_NULL, path);
if (fullpath == RT_NULL) /* not an abstract path */ if (fullpath == RT_NULL) /* not an abstract path */
{ {
rt_set_errno(-DFS_STATUS_ENOTDIR); rt_set_errno(-DFS_STATUS_ENOTDIR);
return -1; return -1;
} }
...@@ -293,60 +252,52 @@ int dfs_mount(const char *device_name, ...@@ -293,60 +252,52 @@ int dfs_mount(const char *device_name,
dfs_file_close(&fd); dfs_file_close(&fd);
} }
free_index = DFS_FILESYSTEMS_MAX; /* check whether the file system mounted or not in the filesystem table
/* check whether the file system mounted or not */ * if it is unmounted yet, find out an empty entry */
dfs_lock(); dfs_lock();
for (index = 0; index < DFS_FILESYSTEMS_MAX; index ++)
{ for (iter = &filesystem_table[0];
if (filesystem_table[index].ops == RT_NULL) iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
{ {
/* find out an empty filesystem table entry */ /* check if it is an empty filesystem table entry? if it is, save fs */
if (free_index == DFS_FILESYSTEMS_MAX) if (iter->ops == RT_NULL)
free_index = index; (fs == RT_NULL) ? (fs = iter) : 0;
} /* check if the PATH is mounted */
else if (strcmp(filesystem_table[index].path, path) == 0) else if (strcmp(iter->path, path) == 0)
{ {
rt_set_errno(-DFS_STATUS_EINVAL); rt_set_errno(-DFS_STATUS_EINVAL);
goto err1; goto err1;
} }
} }
/* can't find en empty filesystem table entry */ if ((fs == RT_NULL) && (iter == &filesystem_table[DFS_FILESYSTEMS_MAX]))
if (free_index == DFS_FILESYSTEMS_MAX)
{ {
rt_set_errno(-DFS_STATUS_ENOSPC); rt_set_errno(-DFS_STATUS_ENOSPC);
goto err1; goto err1;
} }
/* register file system */ /* register file system */
fs = &(filesystem_table[free_index]);
fs->path = fullpath; fs->path = fullpath;
fs->ops = ops; fs->ops = *ops;
fs->dev_id = dev_id; fs->dev_id = dev_id;
/* release filesystem_table lock */ /* release filesystem_table lock */
dfs_unlock(); dfs_unlock();
/* open device, but do not check the status of device */ /* open device, but do not check the status of device */
if (dev_id != RT_NULL) if (dev_id != RT_NULL)
rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR);
/* there is no mount implementation */
if (ops->mount == RT_NULL)
{ {
if (dev_id != RT_NULL) if (rt_device_open(fs->dev_id,
rt_device_close(dev_id); RT_DEVICE_OFLAG_RDWR) != RT_EOK)
{
/* The underlaying device has error, clear the entry. */
dfs_lock(); dfs_lock();
/* clear filesystem table entry */
rt_memset(fs, 0, sizeof(struct dfs_filesystem)); rt_memset(fs, 0, sizeof(struct dfs_filesystem));
dfs_unlock(); goto err1;
rt_free(fullpath);
rt_set_errno(-DFS_STATUS_ENOSYS);
return -1;
} }
}
/* call mount of this filesystem */ /* call mount of this filesystem */
else if (ops->mount(fs, rwflag, data) < 0) if ((*ops)->mount(fs, rwflag, data) < 0)
{ {
/* close device */ /* close device */
if (dev_id != RT_NULL) if (dev_id != RT_NULL)
...@@ -356,18 +307,13 @@ int dfs_mount(const char *device_name, ...@@ -356,18 +307,13 @@ int dfs_mount(const char *device_name,
dfs_lock(); dfs_lock();
/* clear filesystem table entry */ /* clear filesystem table entry */
rt_memset(fs, 0, sizeof(struct dfs_filesystem)); rt_memset(fs, 0, sizeof(struct dfs_filesystem));
dfs_unlock(); goto err1;
rt_free(fullpath);
return -1;
} }
return 0; return 0;
err1: err1:
dfs_unlock(); dfs_unlock();
if (fullpath != RT_NULL)
rt_free(fullpath); rt_free(fullpath);
return -1; return -1;
...@@ -383,6 +329,7 @@ err1: ...@@ -383,6 +329,7 @@ err1:
int dfs_unmount(const char *specialfile) int dfs_unmount(const char *specialfile)
{ {
char *fullpath; char *fullpath;
struct dfs_filesystem *iter;
struct dfs_filesystem *fs = RT_NULL; struct dfs_filesystem *fs = RT_NULL;
fullpath = dfs_normalize_path(RT_NULL, specialfile); fullpath = dfs_normalize_path(RT_NULL, specialfile);
...@@ -396,7 +343,17 @@ int dfs_unmount(const char *specialfile) ...@@ -396,7 +343,17 @@ int dfs_unmount(const char *specialfile)
/* lock filesystem */ /* lock filesystem */
dfs_lock(); dfs_lock();
fs = dfs_filesystem_lookup(fullpath); for (iter = &filesystem_table[0];
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
{
/* check if the PATH is mounted */
if ((iter->path != NULL) && (strcmp(iter->path, fullpath) == 0))
{
fs = iter;
break;
}
}
if (fs == RT_NULL || if (fs == RT_NULL ||
fs->ops->unmount == RT_NULL || fs->ops->unmount == RT_NULL ||
fs->ops->unmount(fs) < 0) fs->ops->unmount(fs) < 0)
...@@ -437,12 +394,10 @@ err1: ...@@ -437,12 +394,10 @@ err1:
int dfs_mkfs(const char *fs_name, const char *device_name) int dfs_mkfs(const char *fs_name, const char *device_name)
{ {
int index; int index;
rt_device_t dev_id; rt_device_t dev_id = RT_NULL;
/* check device name, and it should not be NULL */ /* check device name, and it should not be NULL */
if (device_name == RT_NULL) if (device_name != RT_NULL)
dev_id = RT_NULL;
else
dev_id = rt_device_find(device_name); dev_id = rt_device_find(device_name);
if (dev_id == RT_NULL) if (dev_id == RT_NULL)
...@@ -458,18 +413,22 @@ int dfs_mkfs(const char *fs_name, const char *device_name) ...@@ -458,18 +413,22 @@ int dfs_mkfs(const char *fs_name, const char *device_name)
{ {
if (filesystem_operation_table[index] != RT_NULL && if (filesystem_operation_table[index] != RT_NULL &&
strcmp(filesystem_operation_table[index]->name, fs_name) == 0) strcmp(filesystem_operation_table[index]->name, fs_name) == 0)
break;
}
dfs_unlock();
if (index < DFS_FILESYSTEM_TYPES_MAX)
{ {
/* find file system operation */ /* find file system operation */
const struct dfs_filesystem_operation *ops = filesystem_operation_table[index]; const struct dfs_filesystem_operation *ops = filesystem_operation_table[index];
dfs_unlock(); if (ops->mkfs == RT_NULL)
{
rt_set_errno(-DFS_STATUS_ENOSYS);
return -1;
}
if (ops->mkfs != RT_NULL)
return ops->mkfs(dev_id); return ops->mkfs(dev_id);
break;
}
} }
dfs_unlock();
rt_kprintf("Can not find the file system which named as %s.\n", fs_name); rt_kprintf("Can not find the file system which named as %s.\n", fs_name);
return -1; return -1;
...@@ -538,11 +497,7 @@ int df(const char *path) ...@@ -538,11 +497,7 @@ int df(const char *path)
long long cap; long long cap;
struct statfs buffer; struct statfs buffer;
if (path == RT_NULL) result = dfs_statfs(path ? path : RT_NULL, &buffer);
result = dfs_statfs("/", &buffer);
else
result = dfs_statfs(path, &buffer);
if (result != 0) if (result != 0)
{ {
rt_kprintf("dfs_statfs failed.\n"); rt_kprintf("dfs_statfs failed.\n");
......
...@@ -9,8 +9,8 @@ static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) ...@@ -9,8 +9,8 @@ static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
{ {
while (len) while (len)
{ {
if (*ptr != value) return RT_FALSE; if (*ptr != value)
return RT_FALSE;
ptr ++; ptr ++;
len --; len --;
} }
...@@ -20,6 +20,7 @@ static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) ...@@ -20,6 +20,7 @@ static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
static void heap_malloc_init() static void heap_malloc_init()
{ {
rt_uint8_t res = TC_STAT_PASSED;
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
ptr1 = rt_malloc(1); ptr1 = rt_malloc(1);
...@@ -33,14 +34,18 @@ static void heap_malloc_init() ...@@ -33,14 +34,18 @@ static void heap_malloc_init()
memset(ptr3, 3, 31); memset(ptr3, 3, 31);
memset(ptr4, 4, 127); memset(ptr4, 4, 127);
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; if (mem_check(ptr1, 1, 1) == RT_FALSE)
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; res = TC_STAT_FAILED;
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; if (mem_check(ptr2, 2, 13) == RT_FALSE)
if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed; res = TC_STAT_FAILED;
if (mem_check(ptr3, 3, 31) == RT_FALSE)
res = TC_STAT_FAILED;
if (mem_check(ptr4, 4, 127) == RT_FALSE)
res = TC_STAT_FAILED;
rt_free(ptr4); rt_free(ptr4);
rt_free(ptr3); rt_free(ptr3);
rt_free(ptr3); rt_free(ptr2);
rt_free(ptr1); rt_free(ptr1);
if (ptr5 != RT_NULL) if (ptr5 != RT_NULL)
...@@ -48,10 +53,7 @@ static void heap_malloc_init() ...@@ -48,10 +53,7 @@ static void heap_malloc_init()
rt_free(ptr5); rt_free(ptr5);
} }
tc_done(TC_STAT_PASSED); tc_done(res);
_failed:
tc_done(TC_STAT_FAILED);
} }
#ifdef RT_USING_TC #ifdef RT_USING_TC
......
...@@ -20,6 +20,7 @@ static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) ...@@ -20,6 +20,7 @@ static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
static void heap_realloc_init() static void heap_realloc_init()
{ {
rt_uint8_t res = TC_STAT_PASSED;
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
ptr1 = rt_malloc(1); ptr1 = rt_malloc(1);
...@@ -33,36 +34,54 @@ static void heap_realloc_init() ...@@ -33,36 +34,54 @@ static void heap_realloc_init()
memset(ptr3, 3, 31); memset(ptr3, 3, 31);
memset(ptr4, 4, 127); memset(ptr4, 4, 127);
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; if (mem_check(ptr1, 1, 1) == RT_FALSE)
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; {
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; res = TC_STAT_FAILED;
if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed; goto _free;
}
if (mem_check(ptr2, 2, 13) == RT_FALSE)
{
res = TC_STAT_FAILED;
goto _free;
}
if (mem_check(ptr3, 3, 31) == RT_FALSE)
{
res = TC_STAT_FAILED;
goto _free;
}
if (mem_check(ptr4, 4, 127) == RT_FALSE)
{
res = TC_STAT_FAILED;
goto _free;
}
ptr1 = rt_realloc(ptr1, 13); ptr1 = rt_realloc(ptr1, 13);
ptr2 = rt_realloc(ptr2, 31); ptr2 = rt_realloc(ptr2, 31);
ptr3 = rt_realloc(ptr3, 127); ptr3 = rt_realloc(ptr3, 127);
ptr4 = rt_realloc(ptr4, 1); ptr4 = rt_realloc(ptr4, 1);
ptr5 = rt_realloc(ptr5, 0); ptr5 = rt_realloc(ptr5, 0);
if (ptr5)
{
rt_kprintf("realloc(ptr, 0) should return NULL\n");
res = TC_STAT_FAILED;
}
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; if (mem_check(ptr1, 1, 1) == RT_FALSE)
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; res = TC_STAT_FAILED;
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; if (mem_check(ptr2, 2, 13) == RT_FALSE)
if (mem_check(ptr4, 4, 1) != RT_FALSE) goto _failed; res = TC_STAT_FAILED;
if (mem_check(ptr3, 3, 31) == RT_FALSE)
res = TC_STAT_FAILED;
if (mem_check(ptr4, 4, 1) == RT_FALSE)
res = TC_STAT_FAILED;
_free:
rt_free(ptr4); rt_free(ptr4);
rt_free(ptr3); rt_free(ptr3);
rt_free(ptr3); rt_free(ptr2);
rt_free(ptr1); rt_free(ptr1);
if (ptr5 != RT_NULL) tc_done(res);
{
rt_free(ptr5);
}
tc_done(TC_STAT_PASSED);
_failed:
tc_done(TC_STAT_FAILED);
} }
#ifdef RT_USING_TC #ifdef RT_USING_TC
......
...@@ -25,9 +25,13 @@ static void thread_entry(void* parameter) ...@@ -25,9 +25,13 @@ static void thread_entry(void* parameter)
result = rt_sem_take(sem, 10); result = rt_sem_take(sem, 10);
if (result == -RT_ETIMEOUT) if (result == -RT_ETIMEOUT)
{ {
/* 判断是否刚好过去10个OS Tick */ rt_tick_t new_tick = rt_tick_get();
if (rt_tick_get() - tick != 10) /* 可以有两个 tick 的误差 */
if (new_tick - tick >= 12)
{ {
rt_kprintf("tick error to large: expect: 10, get %d\n",
new_tick - tick);
/* 如果失败,则测试失败 */ /* 如果失败,则测试失败 */
tc_done(TC_STAT_FAILED); tc_done(TC_STAT_FAILED);
rt_sem_delete(sem); rt_sem_delete(sem);
...@@ -90,13 +94,16 @@ static void _tc_cleanup() ...@@ -90,13 +94,16 @@ static void _tc_cleanup()
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical(); rt_enter_critical();
if (sem)
{
rt_sem_delete(sem);
sem = RT_NULL;
}
/* 删除线程 */ /* 删除线程 */
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
{ {
rt_thread_delete(tid); rt_thread_delete(tid);
/* 删除信号量 */
rt_sem_delete(sem);
} }
/* 调度器解锁 */ /* 调度器解锁 */
......
...@@ -100,6 +100,12 @@ static void _tc_cleanup() ...@@ -100,6 +100,12 @@ static void _tc_cleanup()
rt_thread_delete(t2); rt_thread_delete(t2);
rt_thread_delete(worker); rt_thread_delete(worker);
if (sem)
{
rt_sem_delete(sem);
sem = RT_NULL;
}
if (t1_count > t2_count) if (t1_count > t2_count)
tc_done(TC_STAT_FAILED); tc_done(TC_STAT_FAILED);
else else
......
...@@ -119,6 +119,10 @@ static void _tc_cleanup() ...@@ -119,6 +119,10 @@ static void _tc_cleanup()
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical(); rt_enter_critical();
rt_sem_detach(&sem_lock);
rt_sem_detach(&sem_empty);
rt_sem_detach(&sem_full);
/* 删除线程 */ /* 删除线程 */
if (producer_tid != RT_NULL && producer_tid->stat != RT_THREAD_CLOSE) if (producer_tid != RT_NULL && producer_tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(producer_tid); rt_thread_delete(producer_tid);
......
...@@ -27,9 +27,13 @@ static void thread_entry(void* parameter) ...@@ -27,9 +27,13 @@ static void thread_entry(void* parameter)
result = rt_sem_take(&sem, 10); result = rt_sem_take(&sem, 10);
if (result == -RT_ETIMEOUT) if (result == -RT_ETIMEOUT)
{ {
/* 超时后判断是否刚好是10个OS Tick */ rt_tick_t new_tick = rt_tick_get();
if (rt_tick_get() - tick != 10) /* 可以有两个 tick 的误差 */
if (new_tick - tick >= 12)
{ {
rt_kprintf("tick error to large: expect: 10, get %d\n",
new_tick - tick);
tc_done(TC_STAT_FAILED); tc_done(TC_STAT_FAILED);
rt_sem_detach(&sem); rt_sem_detach(&sem);
return; return;
......
...@@ -20,6 +20,7 @@ FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale) ...@@ -20,6 +20,7 @@ FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale)
void tc_thread_entry(void* parameter) void tc_thread_entry(void* parameter)
{ {
unsigned int fail_count = 0;
struct finsh_syscall* index; struct finsh_syscall* index;
/* create tc semaphore */ /* create tc semaphore */
...@@ -40,7 +41,10 @@ void tc_thread_entry(void* parameter) ...@@ -40,7 +41,10 @@ void tc_thread_entry(void* parameter)
tick = index->func(); tick = index->func();
if (tick > 0) if (tick > 0)
{ {
/* Make sure we are going to be blocked. */
rt_sem_control(&_tc_sem, RT_IPC_CMD_RESET, 0);
rt_sem_take(&_tc_sem, tick * _tc_scale); rt_sem_take(&_tc_sem, tick * _tc_scale);
}
if (_tc_cleanup != RT_NULL) if (_tc_cleanup != RT_NULL)
{ {
...@@ -49,27 +53,37 @@ void tc_thread_entry(void* parameter) ...@@ -49,27 +53,37 @@ void tc_thread_entry(void* parameter)
_tc_cleanup = RT_NULL; _tc_cleanup = RT_NULL;
} }
rt_sem_trytake(&_tc_sem);/* by nl1031 */ if (_tc_stat & TC_STAT_RUNNING)
{
rt_kprintf("TestCase[%s] exit with stat TC_STAT_RUNNING."
" Please fix the TC.\n",
_tc_current);
/* If the TC forgot to clear the flag, we do it. */
_tc_stat &= ~TC_STAT_RUNNING;
}
if (_tc_stat & TC_STAT_FAILED) if (_tc_stat & TC_STAT_FAILED)
{
rt_kprintf("TestCase[%s] failed\n", _tc_current); rt_kprintf("TestCase[%s] failed\n", _tc_current);
else fail_count++;
rt_kprintf("TestCase[%s] passed\n", _tc_current);
} }
else else
{ {
if (_tc_cleanup != RT_NULL) rt_kprintf("TestCase[%s] passed\n", _tc_current);
{
/* perform testcase cleanup */
_tc_cleanup();
_tc_cleanup = RT_NULL;
}
} }
} }
} }
} }
rt_kprintf("RT-Thread TestCase Running Done!\n"); rt_kprintf("RT-Thread TestCase Running Done!\n");
if (fail_count)
{
rt_kprintf("%d tests failed\n", fail_count);
}
else
{
rt_kprintf("All tests passed\n");
}
/* detach tc semaphore */ /* detach tc semaphore */
rt_sem_detach(&_tc_sem); rt_sem_detach(&_tc_sem);
} }
......
...@@ -14,7 +14,7 @@ static void thread_entry(void* parameter) ...@@ -14,7 +14,7 @@ static void thread_entry(void* parameter)
rt_kprintf("thread delay 10 tick\n"); rt_kprintf("thread delay 10 tick\n");
tick = rt_tick_get(); tick = rt_tick_get();
rt_thread_delay(10); rt_thread_delay(10);
if (rt_tick_get() - tick > 10) if (rt_tick_get() - tick > 11)
{ {
tc_done(TC_STAT_FAILED); tc_done(TC_STAT_FAILED);
return; return;
...@@ -23,7 +23,7 @@ static void thread_entry(void* parameter) ...@@ -23,7 +23,7 @@ static void thread_entry(void* parameter)
rt_kprintf("thread delay 15 tick\n"); rt_kprintf("thread delay 15 tick\n");
tick = rt_tick_get(); tick = rt_tick_get();
rt_thread_delay(15); rt_thread_delay(15);
if (rt_tick_get() - tick > 15) if (rt_tick_get() - tick > 16)
{ {
tc_done(TC_STAT_FAILED); tc_done(TC_STAT_FAILED);
return; return;
......
...@@ -41,7 +41,7 @@ static void thread2_entry(void* parameter) ...@@ -41,7 +41,7 @@ static void thread2_entry(void* parameter)
/* 线程2拥有较高的优先级,以抢占线程1而获得执行 */ /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */
/* 线程2启动后先睡眠10个OS Tick */ /* 线程2启动后先睡眠10个OS Tick */
rt_thread_delay(10); rt_thread_delay(RT_TICK_PER_SECOND);
/* /*
* 线程2唤醒后直接删除线程1,删除线程1后,线程1自动脱离就绪线程 * 线程2唤醒后直接删除线程1,删除线程1后,线程1自动脱离就绪线程
...@@ -53,7 +53,7 @@ static void thread2_entry(void* parameter) ...@@ -53,7 +53,7 @@ static void thread2_entry(void* parameter)
* 线程2继续休眠10个OS Tick然后退出,线程2休眠后应切换到idle线程 * 线程2继续休眠10个OS Tick然后退出,线程2休眠后应切换到idle线程
* idle线程将执行真正的线程1控制块和线程栈的删除 * idle线程将执行真正的线程1控制块和线程栈的删除
*/ */
rt_thread_delay(10); rt_thread_delay(RT_TICK_PER_SECOND);
} }
static void thread2_cleanup(struct rt_thread *tid) static void thread2_cleanup(struct rt_thread *tid)
...@@ -100,7 +100,7 @@ int thread_delete_init() ...@@ -100,7 +100,7 @@ int thread_delete_init()
else else
tc_stat(TC_STAT_END | TC_STAT_FAILED); tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0; return 10 * RT_TICK_PER_SECOND;
} }
#ifdef RT_USING_TC #ifdef RT_USING_TC
...@@ -112,12 +112,12 @@ static void _tc_cleanup() ...@@ -112,12 +112,12 @@ static void _tc_cleanup()
/* delete thread */ /* delete thread */
if (tid1 != RT_NULL) if (tid1 != RT_NULL)
{ {
rt_kprintf("tid1 is bad\n"); rt_kprintf("tid1 is %p, should be NULL\n", tid1);
tc_stat(TC_STAT_FAILED); tc_stat(TC_STAT_FAILED);
} }
if (tid2 != RT_NULL) if (tid2 != RT_NULL)
{ {
rt_kprintf("tid2 is bad\n"); rt_kprintf("tid2 is %p, should be NULL\n", tid2);
tc_stat(TC_STAT_FAILED); tc_stat(TC_STAT_FAILED);
} }
...@@ -129,9 +129,7 @@ int _tc_thread_delete() ...@@ -129,9 +129,7 @@ int _tc_thread_delete()
{ {
/* set tc cleanup */ /* set tc cleanup */
tc_cleanup(_tc_cleanup); tc_cleanup(_tc_cleanup);
thread_delete_init(); return thread_delete_init();
return 27;
} }
FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example); FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example);
#else #else
......
...@@ -173,6 +173,7 @@ void rt_schedule_remove_thread(struct rt_thread *thread); ...@@ -173,6 +173,7 @@ void rt_schedule_remove_thread(struct rt_thread *thread);
void rt_enter_critical(void); void rt_enter_critical(void);
void rt_exit_critical(void); void rt_exit_critical(void);
rt_uint16_t rt_critical_level(void);
#ifdef RT_USING_HOOK #ifdef RT_USING_HOOK
void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to)); void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to));
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
* 2006-03-23 Bernard the first version * 2006-03-23 Bernard the first version
* 2010-11-10 Bernard add cleanup callback function in thread exit. * 2010-11-10 Bernard add cleanup callback function in thread exit.
* 2012-12-29 Bernard fix compiling warning. * 2012-12-29 Bernard fix compiling warning.
* 2013-12-21 Grissiom let rt_thread_idle_excute loop until there is no
* dead thread.
*/ */
#include <rthw.h> #include <rthw.h>
...@@ -72,8 +74,9 @@ void rt_thread_idle_sethook(void (*hook)(void)) ...@@ -72,8 +74,9 @@ void rt_thread_idle_sethook(void (*hook)(void))
*/ */
void rt_thread_idle_excute(void) void rt_thread_idle_excute(void)
{ {
/* check the defunct thread list */ /* Loop until there is no dead thread. So one call to rt_thread_idle_excute
if (!rt_list_isempty(&rt_thread_defunct)) * will do all the cleanups. */
while (!rt_list_isempty(&rt_thread_defunct))
{ {
rt_base_t lock; rt_base_t lock;
rt_thread_t thread; rt_thread_t thread;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
* issue found by kuronca * issue found by kuronca
* 2010-12-13 Bernard add defunct list initialization even if not use heap. * 2010-12-13 Bernard add defunct list initialization even if not use heap.
* 2011-05-10 Bernard clean scheduler debug log. * 2011-05-10 Bernard clean scheduler debug log.
* 2013-12-21 Grissiom add rt_critical_level
*/ */
#include <rtthread.h> #include <rtthread.h>
...@@ -398,5 +399,14 @@ void rt_exit_critical(void) ...@@ -398,5 +399,14 @@ void rt_exit_critical(void)
} }
} }
/**
* Get the scheduler lock level
*
* @return the level of the scheduler lock. 0 means unlocked.
*/
rt_uint16_t rt_critical_level(void)
{
return rt_scheduler_lock_nest;
}
/*@}*/ /*@}*/
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册