Merge branch 'master' of https://github.com/RT-Thread/rt-thread
This commit is contained in:
commit
a93251ae2b
|
@ -43,7 +43,8 @@ void rtthread_startup(void)
|
||||||
/* initialize timer */
|
/* initialize timer */
|
||||||
rt_system_timer_init();
|
rt_system_timer_init();
|
||||||
|
|
||||||
/* initialize soft timer thread */
|
/* initialize timer */
|
||||||
|
rt_system_timer_init();
|
||||||
rt_system_timer_thread_init();
|
rt_system_timer_thread_init();
|
||||||
|
|
||||||
/* initialize application */
|
/* initialize application */
|
||||||
|
|
|
@ -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 */
|
||||||
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 (
|
||||||
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 {
|
||||||
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 @@
|
||||||
*
|
*
|
||||||
* @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 */
|
||||||
|
if (*iter == RT_NULL)
|
||||||
|
(empty == RT_NULL) ? (empty = iter) : 0;
|
||||||
|
else if (strcmp((*iter)->name, ops->name) == 0)
|
||||||
{
|
{
|
||||||
/* find out an empty filesystem type entry */
|
ret = -1;
|
||||||
if (free_index == DFS_FILESYSTEM_TYPES_MAX)
|
break;
|
||||||
free_index = index;
|
|
||||||
}
|
}
|
||||||
else if (strcmp(filesystem_operation_table[index]->name, ops->name) == 0)
|
|
||||||
{
|
|
||||||
result = -1;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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,37 +79,33 @@ 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(filesystem_table[index].path);
|
|
||||||
if (fspath < prefixlen)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((filesystem_table[index].ops != RT_NULL) &&
|
fspath = strlen(iter->path);
|
||||||
(strncmp(filesystem_table[index].path, path, fspath) == 0))
|
if ((fspath < prefixlen)
|
||||||
{
|
|| (strncmp(iter->path, path, fspath) != 0))
|
||||||
/* check next path separator */
|
continue;
|
||||||
if (fspath > 1 && (strlen(path) > fspath) && (path[fspath] != '/'))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
fs = &filesystem_table[index];
|
/* check next path separator */
|
||||||
prefixlen = fspath;
|
if (fspath > 1 && (strlen(path) > fspath) && (path[fspath] != '/'))
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
fs = iter;
|
||||||
|
prefixlen = fspath;
|
||||||
}
|
}
|
||||||
|
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
@ -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;
|
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;
|
||||||
|
|
||||||
/* get partition offset and size */
|
rt_kprintf("found part[%d], begin: %d, size: ",
|
||||||
part->offset = *(dpt+8) | *(dpt+9)<<8 | *(dpt+10)<<16 | *(dpt+11)<<24;
|
pindex, part->offset*512);
|
||||||
part->size = *(dpt+12) | *(dpt+13)<<8 | *(dpt+14)<<16 | *(dpt+15)<<24;
|
if ((part->size>>11) == 0)
|
||||||
|
rt_kprintf("%d%s",part->size>>1,"KB\n"); /* KB */
|
||||||
rt_kprintf("found part[%d], begin: %d, size: ",
|
|
||||||
pindex, part->offset*512);
|
|
||||||
if ((part->size>>11) > 0) /* MB */
|
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
|
||||||
/* MB */
|
|
||||||
rt_kprintf("%d.%d%s",part_size,(part->size>>1)&0x3FF,"MB\r\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* KB */
|
|
||||||
rt_kprintf("%d%s",part->size>>1,"KB\r\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = -RT_ERROR;
|
unsigned int part_size;
|
||||||
|
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
|
||||||
|
rt_kprintf("%d.%d%s",part_size>>10,part_size&0x3FF,"GB\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
|
||||||
if (dev_id == RT_NULL)
|
|
||||||
{
|
|
||||||
/* no this device */
|
|
||||||
rt_set_errno(-DFS_STATUS_ENODEV);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* which is a non-device filesystem mount */
|
/* which is a non-device filesystem mount */
|
||||||
dev_id = RT_NULL;
|
dev_id = NULL;
|
||||||
}
|
}
|
||||||
|
else if ((dev_id = rt_device_find(device_name)) == RT_NULL)
|
||||||
/* find out specific filesystem */
|
|
||||||
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)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
dfs_unlock();
|
|
||||||
|
|
||||||
/* can't find filesystem */
|
|
||||||
if (index == DFS_FILESYSTEM_TYPES_MAX)
|
|
||||||
{
|
{
|
||||||
|
/* no this device */
|
||||||
rt_set_errno(-DFS_STATUS_ENODEV);
|
rt_set_errno(-DFS_STATUS_ENODEV);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ops = filesystem_operation_table[index];
|
|
||||||
|
/* find out the specific filesystem */
|
||||||
|
dfs_lock();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
if (ops == &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX])
|
||||||
|
{
|
||||||
|
/* can't find filesystem */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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,
|
||||||
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];
|
||||||
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
{
|
{
|
||||||
if (filesystem_table[index].ops == RT_NULL)
|
/* check if it is an empty filesystem table entry? if it is, save fs */
|
||||||
{
|
if (iter->ops == RT_NULL)
|
||||||
/* find out an empty filesystem table entry */
|
(fs == RT_NULL) ? (fs = iter) : 0;
|
||||||
if (free_index == DFS_FILESYSTEMS_MAX)
|
/* check if the PATH is mounted */
|
||||||
free_index = index;
|
else if (strcmp(iter->path, path) == 0)
|
||||||
}
|
|
||||||
else if (strcmp(filesystem_table[index].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)
|
||||||
dfs_lock();
|
{
|
||||||
/* clear filesystem table entry */
|
/* The underlaying device has error, clear the entry. */
|
||||||
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
dfs_lock();
|
||||||
dfs_unlock();
|
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
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,19 +307,14 @@ 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:
|
||||||
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)
|
||||||
/* 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:
|
||||||
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,19 +413,23 @@ 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)
|
||||||
{
|
|
||||||
/* find file system operation */
|
|
||||||
const struct dfs_filesystem_operation *ops = filesystem_operation_table[index];
|
|
||||||
dfs_unlock();
|
|
||||||
|
|
||||||
if (ops->mkfs != RT_NULL)
|
|
||||||
return ops->mkfs(dev_id);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
|
if (index < DFS_FILESYSTEM_TYPES_MAX)
|
||||||
|
{
|
||||||
|
/* find file system operation */
|
||||||
|
const struct dfs_filesystem_operation *ops = filesystem_operation_table[index];
|
||||||
|
if (ops->mkfs == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_set_errno(-DFS_STATUS_ENOSYS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ops->mkfs(dev_id);
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
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");
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
* SQLite compile macro
|
* SQLite compile macro
|
||||||
*/
|
*/
|
||||||
#define RT_USING_SQLITE
|
#define RT_USING_SQLITE
|
||||||
|
2.
|
||||||
|
关注SQLite目录下的src/sqlite_config_rtthread.h
|
||||||
#define SQLITE_MINIMUM_FILE_DESCRIPTOR 0
|
#define SQLITE_MINIMUM_FILE_DESCRIPTOR 0
|
||||||
#define SQLITE_OMIT_LOAD_EXTENSION 1
|
#define SQLITE_OMIT_LOAD_EXTENSION 1
|
||||||
#define SQLITE_OMIT_WAL
|
#define SQLITE_OMIT_WAL
|
||||||
|
@ -23,8 +25,8 @@
|
||||||
#define _HAVE_SQLITE_CONFIG_H
|
#define _HAVE_SQLITE_CONFIG_H
|
||||||
#define BUILD_sqlite
|
#define BUILD_sqlite
|
||||||
#define SQLITE_OS_OTHER 1
|
#define SQLITE_OS_OTHER 1
|
||||||
#define SQLITE_OS_RTT 1
|
#define SQLITE_OS_RTTHREAD 1
|
||||||
2.
|
3.
|
||||||
用test目录下的test10.c来进行测试.
|
用test目录下的test10.c来进行测试.
|
||||||
推荐用mini2440bsp,因为板子的ram较大。
|
推荐用mini2440bsp,因为板子的ram较大。
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,71 @@
|
||||||
#ifndef SQLITE_API
|
#ifndef SQLITE_API
|
||||||
# define SQLITE_API
|
# define SQLITE_API
|
||||||
#endif
|
#endif
|
||||||
|
/************** Begin file sqlite_config_rtthread.h **************************/
|
||||||
|
#ifndef _SQLITE_CONFIG_RTTHREAD_H_
|
||||||
|
#define _SQLITE_CONFIG_RTTHREAD_H_
|
||||||
|
/*
|
||||||
|
* SQLite compile macro
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR
|
||||||
|
#define SQLITE_MINIMUM_FILE_DESCRIPTOR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||||
|
#define SQLITE_OMIT_LOAD_EXTENSION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#ifndef #define SQLITE_OMIT_WAL
|
||||||
|
#define SQLITE_OMIT_WAL
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_RTTHREAD_NO_WIDE
|
||||||
|
#define SQLITE_RTTHREAD_NO_WIDE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_ENABLE_LOCKING_STYLE
|
||||||
|
#define SQLITE_ENABLE_LOCKING_STYLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_DISABLE_LOCKING_STYLE
|
||||||
|
#define SQLITE_DISABLE_LOCKING_STYLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_TEMP_STORE
|
||||||
|
#define SQLITE_TEMP_STORE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_THREADSAFE
|
||||||
|
#define SQLITE_THREADSAFE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_READLINE
|
||||||
|
#define HAVE_READLINE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define NDEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _HAVE_SQLITE_CONFIG_H
|
||||||
|
#define _HAVE_SQLITE_CONFIG_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUILD_sqlite
|
||||||
|
#define BUILD_sqlite
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_OS_OTHER
|
||||||
|
#define SQLITE_OS_OTHER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_OS_RTTHREAD
|
||||||
|
#define SQLITE_OS_RTTHREAD 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************** End of sqlite_config_rtthread.h ******************************/
|
||||||
/************** Begin file sqlite3.h *****************************************/
|
/************** Begin file sqlite3.h *****************************************/
|
||||||
/*
|
/*
|
||||||
** 2001 September 15
|
** 2001 September 15
|
||||||
|
@ -22649,6 +22714,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
|
||||||
#if SQLITE_OS_RTTHREAD /* This file is used for rt-thread only */
|
#if SQLITE_OS_RTTHREAD /* This file is used for rt-thread only */
|
||||||
|
|
||||||
/* #include <rtthread.h> */
|
/* #include <rtthread.h> */
|
||||||
|
#include <dfs_posix.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Include code that is common to all os_*.c files
|
** Include code that is common to all os_*.c files
|
||||||
|
@ -22863,6 +22929,51 @@ SQLITE_API int sqlite3_open_file_count = 0;
|
||||||
/************** End of os_common.h *******************************************/
|
/************** End of os_common.h *******************************************/
|
||||||
/************** Continuing where we left off in os_rtthread.c ****************/
|
/************** Continuing where we left off in os_rtthread.c ****************/
|
||||||
|
|
||||||
|
#ifndef RT_USING_NEWLIB
|
||||||
|
|
||||||
|
#ifndef EINTR
|
||||||
|
#define EINTR 4 /* Interrupted system call */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENOLCK
|
||||||
|
#define ENOLCK 46 /* No record locks available */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EACCES
|
||||||
|
#define EACCES 13 /* Permission denied */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EPERM
|
||||||
|
#define EPERM 1 /* Operation not permitted */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ETIMEDOUT
|
||||||
|
#define ETIMEDOUT 145 /* Connection timed out */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENOTCONN
|
||||||
|
#define ENOTCONN 134 /* Transport endpoint is not connected */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__ADSPBLACKFIN__)
|
||||||
|
int _gettimeofday(struct timeval *tp, void *ignore) __attribute__((weak));
|
||||||
|
int _gettimeofday(struct timeval *tp, void *ignore)
|
||||||
|
#elif defined(__CC_ARM)
|
||||||
|
__weak int _gettimeofday(struct timeval *tp, void *ignore)
|
||||||
|
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||||
|
#if __VER__ > 540
|
||||||
|
__weak
|
||||||
|
#endif
|
||||||
|
int _gettimeofday(struct timeval *tp, void *ignore)
|
||||||
|
#else
|
||||||
|
int _gettimeofday(struct timeval *tp, void *ignore)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* RT_USING_NEWLIB */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Compiling and using WAL mode requires several APIs that are not
|
** Compiling and using WAL mode requires several APIs that are not
|
||||||
** available in rt-thread.
|
** available in rt-thread.
|
||||||
|
@ -23019,7 +23130,7 @@ static int sqlite3_os_type = 0;
|
||||||
# define SYSCALL sqlite3_syscall_ptr
|
# define SYSCALL sqlite3_syscall_ptr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <dfs_posix.h>
|
/* #include <dfs_posix.h> */
|
||||||
|
|
||||||
static int _Access(const char *pathname, int mode)
|
static int _Access(const char *pathname, int mode)
|
||||||
{
|
{
|
||||||
|
@ -23110,10 +23221,10 @@ static struct rtthread_syscall {
|
||||||
#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
|
#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
|
||||||
|
|
||||||
{ "read", (sqlite3_syscall_ptr)read, 0 },
|
{ "read", (sqlite3_syscall_ptr)read, 0 },
|
||||||
#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[6].pCurrent)
|
#define osRead ((int(*)(int,void*,size_t))aSyscall[6].pCurrent)
|
||||||
|
|
||||||
{ "write", (sqlite3_syscall_ptr)write, 0 },
|
{ "write", (sqlite3_syscall_ptr)write, 0 },
|
||||||
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[7].pCurrent)
|
#define osWrite ((int(*)(int,const void*,size_t))aSyscall[7].pCurrent)
|
||||||
|
|
||||||
{ "unlink", (sqlite3_syscall_ptr)unlink, 0 },
|
{ "unlink", (sqlite3_syscall_ptr)unlink, 0 },
|
||||||
#define osUnlink ((int(*)(const char*))aSyscall[8].pCurrent)
|
#define osUnlink ((int(*)(const char*))aSyscall[8].pCurrent)
|
||||||
|
@ -23465,9 +23576,9 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case EAGAIN:
|
case DFS_STATUS_EAGAIN:
|
||||||
case ETIMEDOUT:
|
case ETIMEDOUT:
|
||||||
case EBUSY:
|
case DFS_STATUS_EBUSY:
|
||||||
case EINTR:
|
case EINTR:
|
||||||
case ENOLCK:
|
case ENOLCK:
|
||||||
/* random NFS retry error, unless during file system support
|
/* random NFS retry error, unless during file system support
|
||||||
|
@ -23506,17 +23617,17 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
|
||||||
/* invalid fd, unless during file system support introspection, in which
|
/* invalid fd, unless during file system support introspection, in which
|
||||||
* it actually means what it says */
|
* it actually means what it says */
|
||||||
#endif
|
#endif
|
||||||
case EIO:
|
case DFS_STATUS_EIO:
|
||||||
case EBADF:
|
case DFS_STATUS_EBADF:
|
||||||
case EINVAL:
|
case DFS_STATUS_EINVAL:
|
||||||
case ENOTCONN:
|
case ENOTCONN:
|
||||||
case ENODEV:
|
case DFS_STATUS_ENODEV:
|
||||||
case ENXIO:
|
case DFS_STATUS_ENXIO:
|
||||||
case ENOENT:
|
case DFS_STATUS_ENOENT:
|
||||||
#ifdef ESTALE /* ESTALE is not defined on Interix systems */
|
#ifdef ESTALE /* ESTALE is not defined on Interix systems */
|
||||||
case ESTALE:
|
case ESTALE:
|
||||||
#endif
|
#endif
|
||||||
case ENOSYS:
|
case DFS_STATUS_ENOSYS:
|
||||||
/* these should force the client to close the file and reconnect */
|
/* these should force the client to close the file and reconnect */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -23573,11 +23684,14 @@ static void verifyDbFile(rtthreadFile *pFile){
|
||||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#warning " struct \"stat\" has no field \"st_nlink\""
|
||||||
|
#ifndef RT_USING_SQLITE
|
||||||
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
|
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
|
||||||
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
||||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -23760,7 +23874,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
|
||||||
if( rc<0 ){
|
if( rc<0 ){
|
||||||
/* failed to open/create the lock directory */
|
/* failed to open/create the lock directory */
|
||||||
int tErrno = errno;
|
int tErrno = errno;
|
||||||
if( EEXIST == tErrno ){
|
if( DFS_STATUS_EEXIST == tErrno ){
|
||||||
rc = SQLITE_BUSY;
|
rc = SQLITE_BUSY;
|
||||||
} else {
|
} else {
|
||||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
||||||
|
@ -23811,11 +23925,11 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
|
||||||
/* To fully unlock the database, delete the lock file */
|
/* To fully unlock the database, delete the lock file */
|
||||||
assert( eFileLock==NO_LOCK );
|
assert( eFileLock==NO_LOCK );
|
||||||
rc = osRmdir(zLockFile);
|
rc = osRmdir(zLockFile);
|
||||||
if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
|
if( rc<0 && errno==DFS_STATUS_ENOTDIR ) rc = osUnlink(zLockFile);
|
||||||
if( rc<0 ){
|
if( rc<0 ){
|
||||||
int tErrno = errno;
|
int tErrno = errno;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
if( ENOENT != tErrno ){
|
if( DFS_STATUS_ENOENT != tErrno ){
|
||||||
rc = SQLITE_IOERR_UNLOCK;
|
rc = SQLITE_IOERR_UNLOCK;
|
||||||
}
|
}
|
||||||
if( IS_LOCK_ERROR(rc) ){
|
if( IS_LOCK_ERROR(rc) ){
|
||||||
|
@ -24258,7 +24372,7 @@ static int rtthreadWrite(
|
||||||
SimulateDiskfullError(( wrote=0, amt=1 ));
|
SimulateDiskfullError(( wrote=0, amt=1 ));
|
||||||
|
|
||||||
if( amt>0 ){
|
if( amt>0 ){
|
||||||
if( wrote<0 && pFile->lastErrno!=ENOSPC ){
|
if( wrote<0 && pFile->lastErrno!=DFS_STATUS_ENOSPC ){
|
||||||
/* lastErrno set by seekAndWrite */
|
/* lastErrno set by seekAndWrite */
|
||||||
return SQLITE_IOERR_WRITE;
|
return SQLITE_IOERR_WRITE;
|
||||||
}else{
|
}else{
|
||||||
|
@ -25090,7 +25204,7 @@ static int rtthreadOpen(
|
||||||
|
|
||||||
fd = robust_open(zName, openFlags, openMode);
|
fd = robust_open(zName, openFlags, openMode);
|
||||||
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
|
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
|
||||||
if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
|
if( fd<0 && errno!=DFS_STATUS_EISDIR && isReadWrite && !isExclusive ){
|
||||||
/* Failed to open the file for read/write access. Try read-only. */
|
/* Failed to open the file for read/write access. Try read-only. */
|
||||||
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
||||||
openFlags &= ~(O_RDWR|O_CREAT);
|
openFlags &= ~(O_RDWR|O_CREAT);
|
||||||
|
@ -25148,7 +25262,7 @@ static int rtthreadDelete(
|
||||||
UNUSED_PARAMETER(NotUsed);
|
UNUSED_PARAMETER(NotUsed);
|
||||||
SimulateIOError(return SQLITE_IOERR_DELETE);
|
SimulateIOError(return SQLITE_IOERR_DELETE);
|
||||||
if( osUnlink(zPath)==(-1) ){
|
if( osUnlink(zPath)==(-1) ){
|
||||||
if( errno==ENOENT ){
|
if( errno==DFS_STATUS_ENOENT ){
|
||||||
rc = SQLITE_IOERR_DELETE_NOENT;
|
rc = SQLITE_IOERR_DELETE_NOENT;
|
||||||
}else{
|
}else{
|
||||||
rc = rtthreadLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
|
rc = rtthreadLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
|
||||||
|
@ -25179,6 +25293,17 @@ static int rtthreadDelete(
|
||||||
**
|
**
|
||||||
** Otherwise return 0.
|
** Otherwise return 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef F_OK
|
||||||
|
# define F_OK 0
|
||||||
|
#endif
|
||||||
|
#ifndef R_OK
|
||||||
|
# define R_OK 4
|
||||||
|
#endif
|
||||||
|
#ifndef W_OK
|
||||||
|
# define W_OK 2
|
||||||
|
#endif
|
||||||
|
|
||||||
static int rtthreadAccess(
|
static int rtthreadAccess(
|
||||||
sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */
|
sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */
|
||||||
const char *zPath, /* Path of the file to examine */
|
const char *zPath, /* Path of the file to examine */
|
||||||
|
|
|
@ -347,6 +347,8 @@ SRC += \
|
||||||
config.h \
|
config.h \
|
||||||
sqlite3.h
|
sqlite3.h
|
||||||
|
|
||||||
|
SRC += $(TOP)/src/sqlite_config_rtthread.h
|
||||||
|
|
||||||
# Source code to the test files.
|
# Source code to the test files.
|
||||||
#
|
#
|
||||||
TESTSRC = \
|
TESTSRC = \
|
||||||
|
|
|
@ -16,12 +16,58 @@
|
||||||
#if SQLITE_OS_RTTHREAD /* This file is used for rt-thread only */
|
#if SQLITE_OS_RTTHREAD /* This file is used for rt-thread only */
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
#include <dfs_posix.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Include code that is common to all os_*.c files
|
** Include code that is common to all os_*.c files
|
||||||
*/
|
*/
|
||||||
#include "os_common.h"
|
#include "os_common.h"
|
||||||
|
|
||||||
|
#ifndef RT_USING_NEWLIB
|
||||||
|
|
||||||
|
#ifndef EINTR
|
||||||
|
#define EINTR 4 /* Interrupted system call */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENOLCK
|
||||||
|
#define ENOLCK 46 /* No record locks available */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EACCES
|
||||||
|
#define EACCES 13 /* Permission denied */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EPERM
|
||||||
|
#define EPERM 1 /* Operation not permitted */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ETIMEDOUT
|
||||||
|
#define ETIMEDOUT 145 /* Connection timed out */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENOTCONN
|
||||||
|
#define ENOTCONN 134 /* Transport endpoint is not connected */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__ADSPBLACKFIN__)
|
||||||
|
int _gettimeofday(struct timeval *tp, void *ignore) __attribute__((weak));
|
||||||
|
int _gettimeofday(struct timeval *tp, void *ignore)
|
||||||
|
#elif defined(__CC_ARM)
|
||||||
|
__weak int _gettimeofday(struct timeval *tp, void *ignore)
|
||||||
|
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||||
|
#if __VER__ > 540
|
||||||
|
__weak
|
||||||
|
#endif
|
||||||
|
int _gettimeofday(struct timeval *tp, void *ignore)
|
||||||
|
#else
|
||||||
|
int _gettimeofday(struct timeval *tp, void *ignore)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* RT_USING_NEWLIB */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Compiling and using WAL mode requires several APIs that are not
|
** Compiling and using WAL mode requires several APIs that are not
|
||||||
** available in rt-thread.
|
** available in rt-thread.
|
||||||
|
@ -269,10 +315,10 @@ static struct rtthread_syscall {
|
||||||
#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
|
#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
|
||||||
|
|
||||||
{ "read", (sqlite3_syscall_ptr)read, 0 },
|
{ "read", (sqlite3_syscall_ptr)read, 0 },
|
||||||
#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[6].pCurrent)
|
#define osRead ((int(*)(int,void*,size_t))aSyscall[6].pCurrent)
|
||||||
|
|
||||||
{ "write", (sqlite3_syscall_ptr)write, 0 },
|
{ "write", (sqlite3_syscall_ptr)write, 0 },
|
||||||
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[7].pCurrent)
|
#define osWrite ((int(*)(int,const void*,size_t))aSyscall[7].pCurrent)
|
||||||
|
|
||||||
{ "unlink", (sqlite3_syscall_ptr)unlink, 0 },
|
{ "unlink", (sqlite3_syscall_ptr)unlink, 0 },
|
||||||
#define osUnlink ((int(*)(const char*))aSyscall[8].pCurrent)
|
#define osUnlink ((int(*)(const char*))aSyscall[8].pCurrent)
|
||||||
|
@ -624,9 +670,9 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case EAGAIN:
|
case DFS_STATUS_EAGAIN:
|
||||||
case ETIMEDOUT:
|
case ETIMEDOUT:
|
||||||
case EBUSY:
|
case DFS_STATUS_EBUSY:
|
||||||
case EINTR:
|
case EINTR:
|
||||||
case ENOLCK:
|
case ENOLCK:
|
||||||
/* random NFS retry error, unless during file system support
|
/* random NFS retry error, unless during file system support
|
||||||
|
@ -665,17 +711,17 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
|
||||||
/* invalid fd, unless during file system support introspection, in which
|
/* invalid fd, unless during file system support introspection, in which
|
||||||
* it actually means what it says */
|
* it actually means what it says */
|
||||||
#endif
|
#endif
|
||||||
case EIO:
|
case DFS_STATUS_EIO:
|
||||||
case EBADF:
|
case DFS_STATUS_EBADF:
|
||||||
case EINVAL:
|
case DFS_STATUS_EINVAL:
|
||||||
case ENOTCONN:
|
case ENOTCONN:
|
||||||
case ENODEV:
|
case DFS_STATUS_ENODEV:
|
||||||
case ENXIO:
|
case DFS_STATUS_ENXIO:
|
||||||
case ENOENT:
|
case DFS_STATUS_ENOENT:
|
||||||
#ifdef ESTALE /* ESTALE is not defined on Interix systems */
|
#ifdef ESTALE /* ESTALE is not defined on Interix systems */
|
||||||
case ESTALE:
|
case ESTALE:
|
||||||
#endif
|
#endif
|
||||||
case ENOSYS:
|
case DFS_STATUS_ENOSYS:
|
||||||
/* these should force the client to close the file and reconnect */
|
/* these should force the client to close the file and reconnect */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -732,11 +778,14 @@ static void verifyDbFile(rtthreadFile *pFile){
|
||||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#warning " struct \"stat\" has no field \"st_nlink\""
|
||||||
|
#ifndef RT_USING_SQLITE
|
||||||
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
|
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
|
||||||
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
||||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -919,7 +968,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
|
||||||
if( rc<0 ){
|
if( rc<0 ){
|
||||||
/* failed to open/create the lock directory */
|
/* failed to open/create the lock directory */
|
||||||
int tErrno = errno;
|
int tErrno = errno;
|
||||||
if( EEXIST == tErrno ){
|
if( DFS_STATUS_EEXIST == tErrno ){
|
||||||
rc = SQLITE_BUSY;
|
rc = SQLITE_BUSY;
|
||||||
} else {
|
} else {
|
||||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
||||||
|
@ -970,11 +1019,11 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
|
||||||
/* To fully unlock the database, delete the lock file */
|
/* To fully unlock the database, delete the lock file */
|
||||||
assert( eFileLock==NO_LOCK );
|
assert( eFileLock==NO_LOCK );
|
||||||
rc = osRmdir(zLockFile);
|
rc = osRmdir(zLockFile);
|
||||||
if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
|
if( rc<0 && errno==DFS_STATUS_ENOTDIR ) rc = osUnlink(zLockFile);
|
||||||
if( rc<0 ){
|
if( rc<0 ){
|
||||||
int tErrno = errno;
|
int tErrno = errno;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
if( ENOENT != tErrno ){
|
if( DFS_STATUS_ENOENT != tErrno ){
|
||||||
rc = SQLITE_IOERR_UNLOCK;
|
rc = SQLITE_IOERR_UNLOCK;
|
||||||
}
|
}
|
||||||
if( IS_LOCK_ERROR(rc) ){
|
if( IS_LOCK_ERROR(rc) ){
|
||||||
|
@ -1417,7 +1466,7 @@ static int rtthreadWrite(
|
||||||
SimulateDiskfullError(( wrote=0, amt=1 ));
|
SimulateDiskfullError(( wrote=0, amt=1 ));
|
||||||
|
|
||||||
if( amt>0 ){
|
if( amt>0 ){
|
||||||
if( wrote<0 && pFile->lastErrno!=ENOSPC ){
|
if( wrote<0 && pFile->lastErrno!=DFS_STATUS_ENOSPC ){
|
||||||
/* lastErrno set by seekAndWrite */
|
/* lastErrno set by seekAndWrite */
|
||||||
return SQLITE_IOERR_WRITE;
|
return SQLITE_IOERR_WRITE;
|
||||||
}else{
|
}else{
|
||||||
|
@ -2249,7 +2298,7 @@ static int rtthreadOpen(
|
||||||
|
|
||||||
fd = robust_open(zName, openFlags, openMode);
|
fd = robust_open(zName, openFlags, openMode);
|
||||||
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
|
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
|
||||||
if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
|
if( fd<0 && errno!=DFS_STATUS_EISDIR && isReadWrite && !isExclusive ){
|
||||||
/* Failed to open the file for read/write access. Try read-only. */
|
/* Failed to open the file for read/write access. Try read-only. */
|
||||||
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
||||||
openFlags &= ~(O_RDWR|O_CREAT);
|
openFlags &= ~(O_RDWR|O_CREAT);
|
||||||
|
@ -2307,7 +2356,7 @@ static int rtthreadDelete(
|
||||||
UNUSED_PARAMETER(NotUsed);
|
UNUSED_PARAMETER(NotUsed);
|
||||||
SimulateIOError(return SQLITE_IOERR_DELETE);
|
SimulateIOError(return SQLITE_IOERR_DELETE);
|
||||||
if( osUnlink(zPath)==(-1) ){
|
if( osUnlink(zPath)==(-1) ){
|
||||||
if( errno==ENOENT ){
|
if( errno==DFS_STATUS_ENOENT ){
|
||||||
rc = SQLITE_IOERR_DELETE_NOENT;
|
rc = SQLITE_IOERR_DELETE_NOENT;
|
||||||
}else{
|
}else{
|
||||||
rc = rtthreadLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
|
rc = rtthreadLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
|
||||||
|
@ -2338,6 +2387,17 @@ static int rtthreadDelete(
|
||||||
**
|
**
|
||||||
** Otherwise return 0.
|
** Otherwise return 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef F_OK
|
||||||
|
# define F_OK 0
|
||||||
|
#endif
|
||||||
|
#ifndef R_OK
|
||||||
|
# define R_OK 4
|
||||||
|
#endif
|
||||||
|
#ifndef W_OK
|
||||||
|
# define W_OK 2
|
||||||
|
#endif
|
||||||
|
|
||||||
static int rtthreadAccess(
|
static int rtthreadAccess(
|
||||||
sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */
|
sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */
|
||||||
const char *zPath, /* Path of the file to examine */
|
const char *zPath, /* Path of the file to examine */
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef _SQLITE_CONFIG_RTTHREAD_H_
|
||||||
|
#define _SQLITE_CONFIG_RTTHREAD_H_
|
||||||
|
/*
|
||||||
|
* SQLite compile macro
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR
|
||||||
|
#define SQLITE_MINIMUM_FILE_DESCRIPTOR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||||
|
#define SQLITE_OMIT_LOAD_EXTENSION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#ifndef #define SQLITE_OMIT_WAL
|
||||||
|
#define SQLITE_OMIT_WAL
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_RTTHREAD_NO_WIDE
|
||||||
|
#define SQLITE_RTTHREAD_NO_WIDE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_ENABLE_LOCKING_STYLE
|
||||||
|
#define SQLITE_ENABLE_LOCKING_STYLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_DISABLE_LOCKING_STYLE
|
||||||
|
#define SQLITE_DISABLE_LOCKING_STYLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_TEMP_STORE
|
||||||
|
#define SQLITE_TEMP_STORE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_THREADSAFE
|
||||||
|
#define SQLITE_THREADSAFE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_READLINE
|
||||||
|
#define HAVE_READLINE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define NDEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _HAVE_SQLITE_CONFIG_H
|
||||||
|
#define _HAVE_SQLITE_CONFIG_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUILD_sqlite
|
||||||
|
#define BUILD_sqlite
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_OS_OTHER
|
||||||
|
#define SQLITE_OS_OTHER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_OS_RTTHREAD
|
||||||
|
#define SQLITE_OS_RTTHREAD 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -228,6 +228,7 @@ proc copy_file {filename} {
|
||||||
# inlining opportunities.
|
# inlining opportunities.
|
||||||
#
|
#
|
||||||
foreach file {
|
foreach file {
|
||||||
|
sqlite_config_rtthread.h
|
||||||
sqlite3.h
|
sqlite3.h
|
||||||
sqliteInt.h
|
sqliteInt.h
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
|
* 2013-12-23 Bernard Add the checking for ESHUTDOWN
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __POSIX_TYPES_H__
|
#ifndef __POSIX_TYPES_H__
|
||||||
|
@ -37,7 +38,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#ifndef ESHUTDOWN
|
||||||
#define ESHUTDOWN 180
|
#define ESHUTDOWN 180
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ memp_simple.c
|
||||||
tc_sample.c
|
tc_sample.c
|
||||||
""")
|
""")
|
||||||
|
|
||||||
group = DefineGroup('examples', src, depend = ['RT_USING_TC'])
|
group = DefineGroup('examples', src,
|
||||||
|
depend = ['RT_USING_TC'],
|
||||||
|
CPPPATH=[GetCurrentDir()])
|
||||||
|
|
||||||
Return('group')
|
Return('group')
|
||||||
|
|
|
@ -1,70 +1,70 @@
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <rthw.h>
|
#include <rthw.h>
|
||||||
|
|
||||||
#define CPU_USAGE_CALC_TICK 10
|
#define CPU_USAGE_CALC_TICK 10
|
||||||
#define CPU_USAGE_LOOP 100
|
#define CPU_USAGE_LOOP 100
|
||||||
|
|
||||||
static rt_uint8_t cpu_usage_major = 0, cpu_usage_minor= 0;
|
static rt_uint8_t cpu_usage_major = 0, cpu_usage_minor= 0;
|
||||||
static rt_uint32_t total_count = 0;
|
static rt_uint32_t total_count = 0;
|
||||||
|
|
||||||
static void cpu_usage_idle_hook()
|
static void cpu_usage_idle_hook()
|
||||||
{
|
{
|
||||||
rt_tick_t tick;
|
rt_tick_t tick;
|
||||||
rt_uint32_t count;
|
rt_uint32_t count;
|
||||||
volatile rt_uint32_t loop;
|
volatile rt_uint32_t loop;
|
||||||
|
|
||||||
if (total_count == 0)
|
if (total_count == 0)
|
||||||
{
|
{
|
||||||
/* get total count */
|
/* get total count */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
tick = rt_tick_get();
|
tick = rt_tick_get();
|
||||||
while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK)
|
while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK)
|
||||||
{
|
{
|
||||||
total_count ++;
|
total_count ++;
|
||||||
loop = 0;
|
loop = 0;
|
||||||
while (loop < CPU_USAGE_LOOP) loop ++;
|
while (loop < CPU_USAGE_LOOP) loop ++;
|
||||||
}
|
}
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
/* get CPU usage */
|
/* get CPU usage */
|
||||||
tick = rt_tick_get();
|
tick = rt_tick_get();
|
||||||
while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK)
|
while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK)
|
||||||
{
|
{
|
||||||
count ++;
|
count ++;
|
||||||
loop = 0;
|
loop = 0;
|
||||||
while (loop < CPU_USAGE_LOOP) loop ++;
|
while (loop < CPU_USAGE_LOOP) loop ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate major and minor */
|
/* calculate major and minor */
|
||||||
if (count < total_count)
|
if (count < total_count)
|
||||||
{
|
{
|
||||||
count = total_count - count;
|
count = total_count - count;
|
||||||
cpu_usage_major = (count * 100) / total_count;
|
cpu_usage_major = (count * 100) / total_count;
|
||||||
cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count;
|
cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
total_count = count;
|
total_count = count;
|
||||||
|
|
||||||
/* no CPU usage */
|
/* no CPU usage */
|
||||||
cpu_usage_major = 0;
|
cpu_usage_major = 0;
|
||||||
cpu_usage_minor = 0;
|
cpu_usage_minor = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor)
|
void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor)
|
||||||
{
|
{
|
||||||
RT_ASSERT(major != RT_NULL);
|
RT_ASSERT(major != RT_NULL);
|
||||||
RT_ASSERT(minor != RT_NULL);
|
RT_ASSERT(minor != RT_NULL);
|
||||||
|
|
||||||
*major = cpu_usage_major;
|
*major = cpu_usage_major;
|
||||||
*minor = cpu_usage_minor;
|
*minor = cpu_usage_minor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_usage_init()
|
void cpu_usage_init()
|
||||||
{
|
{
|
||||||
/* set idle thread hook */
|
/* set idle thread hook */
|
||||||
rt_thread_idle_sethook(cpu_usage_idle_hook);
|
rt_thread_idle_sethook(cpu_usage_idle_hook);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,124 +20,124 @@ static struct rt_event event;
|
||||||
/* 线程1入口函数 */
|
/* 线程1入口函数 */
|
||||||
static void thread1_entry(void *param)
|
static void thread1_entry(void *param)
|
||||||
{
|
{
|
||||||
rt_uint32_t e;
|
rt_uint32_t e;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* receive first event */
|
/* receive first event */
|
||||||
if (rt_event_recv(&event, ((1 << 3) | (1 << 5)),
|
if (rt_event_recv(&event, ((1 << 3) | (1 << 5)),
|
||||||
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
|
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
|
||||||
RT_WAITING_FOREVER, &e) == RT_EOK)
|
RT_WAITING_FOREVER, &e) == RT_EOK)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread1: AND recv event 0x%x\n", e);
|
rt_kprintf("thread1: AND recv event 0x%x\n", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_kprintf("thread1: delay 1s to prepare second event\n");
|
rt_kprintf("thread1: delay 1s to prepare second event\n");
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
|
|
||||||
/* receive second event */
|
/* receive second event */
|
||||||
if (rt_event_recv(&event, ((1 << 3) | (1 << 5)),
|
if (rt_event_recv(&event, ((1 << 3) | (1 << 5)),
|
||||||
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
|
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
|
||||||
RT_WAITING_FOREVER, &e) == RT_EOK)
|
RT_WAITING_FOREVER, &e) == RT_EOK)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread1: OR recv event 0x%x\n", e);
|
rt_kprintf("thread1: OR recv event 0x%x\n", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_thread_delay(5);
|
rt_thread_delay(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口函数 */
|
/* 线程2入口函数 */
|
||||||
static void thread2_entry(void *param)
|
static void thread2_entry(void *param)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread2: send event1\n");
|
rt_kprintf("thread2: send event1\n");
|
||||||
rt_event_send(&event, (1 << 3));
|
rt_event_send(&event, (1 << 3));
|
||||||
|
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程3入口函数 */
|
/* 线程3入口函数 */
|
||||||
static void thread3_entry(void *param)
|
static void thread3_entry(void *param)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread3: send event2\n");
|
rt_kprintf("thread3: send event2\n");
|
||||||
rt_event_send(&event, (1 << 5));
|
rt_event_send(&event, (1 << 5));
|
||||||
|
|
||||||
rt_thread_delay(20);
|
rt_thread_delay(20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int event_simple_init()
|
int event_simple_init()
|
||||||
{
|
{
|
||||||
/* 初始化事件对象 */
|
/* 初始化事件对象 */
|
||||||
rt_event_init(&event, "event", RT_IPC_FLAG_FIFO);
|
rt_event_init(&event, "event", RT_IPC_FLAG_FIFO);
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("t1",
|
tid1 = rt_thread_create("t1",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("t2",
|
tid2 = rt_thread_create("t2",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程3 */
|
/* 创建线程3 */
|
||||||
tid3 = rt_thread_create("t3",
|
tid3 = rt_thread_create("t3",
|
||||||
thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */
|
thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid3 != RT_NULL)
|
if (tid3 != RT_NULL)
|
||||||
rt_thread_startup(tid3);
|
rt_thread_startup(tid3);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE)
|
if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid3);
|
rt_thread_delete(tid3);
|
||||||
|
|
||||||
/* 执行事件对象脱离 */
|
/* 执行事件对象脱离 */
|
||||||
rt_event_detach(&event);
|
rt_event_detach(&event);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_event_simple()
|
int _tc_event_simple()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
event_simple_init();
|
event_simple_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_event_simple, a simple event example);
|
FINSH_FUNCTION_EXPORT(_tc_event_simple, a simple event example);
|
||||||
|
@ -145,8 +145,8 @@ FINSH_FUNCTION_EXPORT(_tc_event_simple, a simple event example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
event_simple_init();
|
event_simple_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,66 +7,68 @@
|
||||||
|
|
||||||
static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
|
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 ++;
|
||||||
|
len --;
|
||||||
|
}
|
||||||
|
|
||||||
ptr ++;
|
return RT_TRUE;
|
||||||
len --;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RT_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heap_malloc_init()
|
static void heap_malloc_init()
|
||||||
{
|
{
|
||||||
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
|
rt_uint8_t res = TC_STAT_PASSED;
|
||||||
|
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
|
||||||
|
|
||||||
ptr1 = rt_malloc(1);
|
ptr1 = rt_malloc(1);
|
||||||
ptr2 = rt_malloc(13);
|
ptr2 = rt_malloc(13);
|
||||||
ptr3 = rt_malloc(31);
|
ptr3 = rt_malloc(31);
|
||||||
ptr4 = rt_malloc(127);
|
ptr4 = rt_malloc(127);
|
||||||
ptr5 = rt_malloc(0);
|
ptr5 = rt_malloc(0);
|
||||||
|
|
||||||
memset(ptr1, 1, 1);
|
memset(ptr1, 1, 1);
|
||||||
memset(ptr2, 2, 13);
|
memset(ptr2, 2, 13);
|
||||||
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)
|
||||||
{
|
{
|
||||||
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
|
||||||
int _tc_heap_malloc()
|
int _tc_heap_malloc()
|
||||||
{
|
{
|
||||||
heap_malloc_init();
|
heap_malloc_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_heap_malloc, a heap malloc test);
|
FINSH_FUNCTION_EXPORT(_tc_heap_malloc, a heap malloc test);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
heap_malloc_init();
|
heap_malloc_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,77 +7,96 @@
|
||||||
|
|
||||||
static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
|
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 --;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RT_TRUE;
|
return RT_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heap_realloc_init()
|
static void heap_realloc_init()
|
||||||
{
|
{
|
||||||
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
|
rt_uint8_t res = TC_STAT_PASSED;
|
||||||
|
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
|
||||||
|
|
||||||
ptr1 = rt_malloc(1);
|
ptr1 = rt_malloc(1);
|
||||||
ptr2 = rt_malloc(13);
|
ptr2 = rt_malloc(13);
|
||||||
ptr3 = rt_malloc(31);
|
ptr3 = rt_malloc(31);
|
||||||
ptr4 = rt_malloc(127);
|
ptr4 = rt_malloc(127);
|
||||||
ptr5 = rt_malloc(0);
|
ptr5 = rt_malloc(0);
|
||||||
|
|
||||||
memset(ptr1, 1, 1);
|
memset(ptr1, 1, 1);
|
||||||
memset(ptr2, 2, 13);
|
memset(ptr2, 2, 13);
|
||||||
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;
|
||||||
|
|
||||||
rt_free(ptr4);
|
_free:
|
||||||
rt_free(ptr3);
|
rt_free(ptr4);
|
||||||
rt_free(ptr3);
|
rt_free(ptr3);
|
||||||
rt_free(ptr1);
|
rt_free(ptr2);
|
||||||
|
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
|
||||||
int _tc_heap_realloc()
|
int _tc_heap_realloc()
|
||||||
{
|
{
|
||||||
heap_realloc_init();
|
heap_realloc_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_heap_realloc, a heap re-malloc test);
|
FINSH_FUNCTION_EXPORT(_tc_heap_realloc, a heap re-malloc test);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
heap_realloc_init();
|
heap_realloc_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,110 +22,110 @@ static char mb_str2[] = "this is another mail!";
|
||||||
/* 线程1入口 */
|
/* 线程1入口 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
unsigned char* str;
|
unsigned char* str;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 从邮箱中收取邮件 */
|
/* 从邮箱中收取邮件 */
|
||||||
if (rt_mb_recv(&mb, (rt_uint32_t*)&str, RT_WAITING_FOREVER) == RT_EOK)
|
if (rt_mb_recv(&mb, (rt_uint32_t*)&str, RT_WAITING_FOREVER) == RT_EOK)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str);
|
rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str);
|
||||||
|
|
||||||
/* 延时20个OS Tick */
|
/* 延时20个OS Tick */
|
||||||
rt_thread_delay(50);
|
rt_thread_delay(50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口 */
|
/* 线程2入口 */
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint8_t count;
|
rt_uint8_t count;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
count ++;
|
count ++;
|
||||||
if (count & 0x1)
|
if (count & 0x1)
|
||||||
{
|
{
|
||||||
/* 发送mb_str1地址到邮箱中 */
|
/* 发送mb_str1地址到邮箱中 */
|
||||||
str = mb_str1;
|
str = mb_str1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 发送mb_str2地址到邮箱中 */
|
/* 发送mb_str2地址到邮箱中 */
|
||||||
str = mb_str2;
|
str = mb_str2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 不停的发送邮件,如果满了则等待10个tick,然后超时 */
|
/* 不停的发送邮件,如果满了则等待10个tick,然后超时 */
|
||||||
if( rt_mb_send_wait(&mb, (rt_uint32_t)str,10) == RT_EOK )
|
if( rt_mb_send_wait(&mb, (rt_uint32_t)str,10) == RT_EOK )
|
||||||
rt_kprintf("thread2: sent a mail to mailbox, the content:%s\n", str);
|
rt_kprintf("thread2: sent a mail to mailbox, the content:%s\n", str);
|
||||||
else
|
else
|
||||||
rt_kprintf("thread2: timeout while waiting to send a mail.\n");
|
rt_kprintf("thread2: timeout while waiting to send a mail.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbox_send_wait_init()
|
int mbox_send_wait_init()
|
||||||
{
|
{
|
||||||
/* 初始化一个mailbox */
|
/* 初始化一个mailbox */
|
||||||
rt_mb_init(&mb,
|
rt_mb_init(&mb,
|
||||||
"mbt", /* 名称是mbt */
|
"mbt", /* 名称是mbt */
|
||||||
&mb_pool[0], /* 邮箱用到的内存池是mb_pool */
|
&mb_pool[0], /* 邮箱用到的内存池是mb_pool */
|
||||||
sizeof(mb_pool)/4, /* 大小是mb_pool大小除以4,因为一封邮件的大小是4字节 */
|
sizeof(mb_pool)/4, /* 大小是mb_pool大小除以4,因为一封邮件的大小是4字节 */
|
||||||
RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */
|
RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("t1",
|
tid1 = rt_thread_create("t1",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("t2",
|
tid2 = rt_thread_create("t2",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
|
|
||||||
/* 执行邮箱对象脱离 */
|
/* 执行邮箱对象脱离 */
|
||||||
rt_mb_detach(&mb);
|
rt_mb_detach(&mb);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_mbox_send_wait()
|
int _tc_mbox_send_wait()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
mbox_send_wait_init();
|
mbox_send_wait_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 300;
|
return 300;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_mbox_send_wait, a example of mailbox send wait);
|
FINSH_FUNCTION_EXPORT(_tc_mbox_send_wait, a example of mailbox send wait);
|
||||||
|
@ -133,9 +133,9 @@ FINSH_FUNCTION_EXPORT(_tc_mbox_send_wait, a example of mailbox send wait);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
mbox_send_wait_init();
|
mbox_send_wait_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -22,108 +22,108 @@ static char mb_str2[] = "this is another mail!";
|
||||||
/* 线程1入口 */
|
/* 线程1入口 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
unsigned char* str;
|
unsigned char* str;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread1: try to recv a mail\n");
|
rt_kprintf("thread1: try to recv a mail\n");
|
||||||
|
|
||||||
/* 从邮箱中收取邮件 */
|
/* 从邮箱中收取邮件 */
|
||||||
if (rt_mb_recv(&mb, (rt_uint32_t*)&str, RT_WAITING_FOREVER) == RT_EOK)
|
if (rt_mb_recv(&mb, (rt_uint32_t*)&str, RT_WAITING_FOREVER) == RT_EOK)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str);
|
rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str);
|
||||||
|
|
||||||
/* 延时10个OS Tick */
|
/* 延时10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口 */
|
/* 线程2入口 */
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint8_t count;
|
rt_uint8_t count;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
count ++;
|
count ++;
|
||||||
if (count & 0x1)
|
if (count & 0x1)
|
||||||
{
|
{
|
||||||
/* 发送mb_str1地址到邮箱中 */
|
/* 发送mb_str1地址到邮箱中 */
|
||||||
rt_mb_send(&mb, (rt_uint32_t)&mb_str1[0]);
|
rt_mb_send(&mb, (rt_uint32_t)&mb_str1[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 发送mb_str2地址到邮箱中 */
|
/* 发送mb_str2地址到邮箱中 */
|
||||||
rt_mb_send(&mb, (rt_uint32_t)&mb_str2[0]);
|
rt_mb_send(&mb, (rt_uint32_t)&mb_str2[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 延时20个OS Tick */
|
/* 延时20个OS Tick */
|
||||||
rt_thread_delay(20);
|
rt_thread_delay(20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbox_simple_init()
|
int mbox_simple_init()
|
||||||
{
|
{
|
||||||
/* 初始化一个mailbox */
|
/* 初始化一个mailbox */
|
||||||
rt_mb_init(&mb,
|
rt_mb_init(&mb,
|
||||||
"mbt", /* 名称是mbt */
|
"mbt", /* 名称是mbt */
|
||||||
&mb_pool[0], /* 邮箱用到的内存池是mb_pool */
|
&mb_pool[0], /* 邮箱用到的内存池是mb_pool */
|
||||||
sizeof(mb_pool)/4, /* 大小是mb_pool大小除以4,因为一封邮件的大小是4字节 */
|
sizeof(mb_pool)/4, /* 大小是mb_pool大小除以4,因为一封邮件的大小是4字节 */
|
||||||
RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */
|
RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("t1",
|
tid1 = rt_thread_create("t1",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("t2",
|
tid2 = rt_thread_create("t2",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
|
|
||||||
/* 执行邮箱对象脱离 */
|
/* 执行邮箱对象脱离 */
|
||||||
rt_mb_detach(&mb);
|
rt_mb_detach(&mb);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_mbox_simple()
|
int _tc_mbox_simple()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
mbox_simple_init();
|
mbox_simple_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_mbox_simple, a simple mailbox example);
|
FINSH_FUNCTION_EXPORT(_tc_mbox_simple, a simple mailbox example);
|
||||||
|
@ -131,8 +131,8 @@ FINSH_FUNCTION_EXPORT(_tc_mbox_simple, a simple mailbox example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
mbox_simple_init();
|
mbox_simple_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,115 +18,115 @@ static rt_thread_t tid2 = RT_NULL;
|
||||||
/* 线程1入口 */
|
/* 线程1入口 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *block;
|
char *block;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 48; i++)
|
for (i = 0; i < 48; i++)
|
||||||
{
|
{
|
||||||
/* 申请内存块 */
|
/* 申请内存块 */
|
||||||
rt_kprintf("allocate No.%d\n", i);
|
rt_kprintf("allocate No.%d\n", i);
|
||||||
if (ptr[i] == RT_NULL)
|
if (ptr[i] == RT_NULL)
|
||||||
{
|
{
|
||||||
ptr[i] = rt_mp_alloc(&mp, RT_WAITING_FOREVER);
|
ptr[i] = rt_mp_alloc(&mp, RT_WAITING_FOREVER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 继续申请一个内存块,因为已经没有内存块,线程应该被挂起 */
|
/* 继续申请一个内存块,因为已经没有内存块,线程应该被挂起 */
|
||||||
block = rt_mp_alloc(&mp, RT_WAITING_FOREVER);
|
block = rt_mp_alloc(&mp, RT_WAITING_FOREVER);
|
||||||
rt_kprintf("allocate the block mem\n");
|
rt_kprintf("allocate the block mem\n");
|
||||||
/* 释放这个内存块 */
|
/* 释放这个内存块 */
|
||||||
rt_mp_free(block);
|
rt_mp_free(block);
|
||||||
block = RT_NULL;
|
block = RT_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口,线程2的优先级比线程1低,应该线程1先获得执行。*/
|
/* 线程2入口,线程2的优先级比线程1低,应该线程1先获得执行。*/
|
||||||
static void thread2_entry(void *parameter)
|
static void thread2_entry(void *parameter)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
rt_kprintf("try to release block\n");
|
rt_kprintf("try to release block\n");
|
||||||
|
|
||||||
for (i = 0 ; i < 48; i ++)
|
for (i = 0 ; i < 48; i ++)
|
||||||
{
|
{
|
||||||
/* 释放所有分配成功的内存块 */
|
/* 释放所有分配成功的内存块 */
|
||||||
if (ptr[i] != RT_NULL)
|
if (ptr[i] != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_kprintf("release block %d\n", i);
|
rt_kprintf("release block %d\n", i);
|
||||||
|
|
||||||
rt_mp_free(ptr[i]);
|
rt_mp_free(ptr[i]);
|
||||||
ptr[i] = RT_NULL;
|
ptr[i] = RT_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 休眠10个OS Tick */
|
/* 休眠10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mempool_simple_init()
|
int mempool_simple_init()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 48; i ++) ptr[i] = RT_NULL;
|
for (i = 0; i < 48; i ++) ptr[i] = RT_NULL;
|
||||||
|
|
||||||
/* 初始化内存池对象 */
|
/* 初始化内存池对象 */
|
||||||
rt_mp_init(&mp, "mp1", &mempool[0], sizeof(mempool), 80);
|
rt_mp_init(&mp, "mp1", &mempool[0], sizeof(mempool), 80);
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("t1",
|
tid1 = rt_thread_create("t1",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("t2",
|
tid2 = rt_thread_create("t2",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
|
|
||||||
/* 执行内存池脱离 */
|
/* 执行内存池脱离 */
|
||||||
rt_mp_detach(&mp);
|
rt_mp_detach(&mp);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_mempool_simple()
|
int _tc_mempool_simple()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
mempool_simple_init();
|
mempool_simple_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_mempool_simple, a memory pool example);
|
FINSH_FUNCTION_EXPORT(_tc_mempool_simple, a memory pool example);
|
||||||
|
@ -134,8 +134,8 @@ FINSH_FUNCTION_EXPORT(_tc_mempool_simple, a memory pool example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
mempool_simple_init();
|
mempool_simple_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,139 +20,139 @@ static char msg_pool[2048];
|
||||||
/* 线程1入口函数 */
|
/* 线程1入口函数 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rt_memset(&buf[0], 0, sizeof(buf));
|
rt_memset(&buf[0], 0, sizeof(buf));
|
||||||
|
|
||||||
/* 从消息队列中接收消息 */
|
/* 从消息队列中接收消息 */
|
||||||
if (rt_mq_recv(&mq, &buf[0], sizeof(buf), RT_WAITING_FOREVER) == RT_EOK)
|
if (rt_mq_recv(&mq, &buf[0], sizeof(buf), RT_WAITING_FOREVER) == RT_EOK)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread1: recv msg from message queue, the content:%s\n", buf);
|
rt_kprintf("thread1: recv msg from message queue, the content:%s\n", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 延迟10个OS Tick */
|
/* 延迟10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口函数 */
|
/* 线程2入口函数 */
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
int i, result;
|
int i, result;
|
||||||
char buf[] = "this is message No.x";
|
char buf[] = "this is message No.x";
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
buf[sizeof(buf) - 2] = '0' + i;
|
buf[sizeof(buf) - 2] = '0' + i;
|
||||||
|
|
||||||
rt_kprintf("thread2: send message - %s\n", buf);
|
rt_kprintf("thread2: send message - %s\n", buf);
|
||||||
/* 发送消息到消息队列中 */
|
/* 发送消息到消息队列中 */
|
||||||
result = rt_mq_send(&mq, &buf[0], sizeof(buf));
|
result = rt_mq_send(&mq, &buf[0], sizeof(buf));
|
||||||
if ( result == -RT_EFULL)
|
if ( result == -RT_EFULL)
|
||||||
{
|
{
|
||||||
/* 消息队列满, 延迟1s时间 */
|
/* 消息队列满, 延迟1s时间 */
|
||||||
rt_kprintf("message queue full, delay 1s\n");
|
rt_kprintf("message queue full, delay 1s\n");
|
||||||
rt_thread_delay(100);
|
rt_thread_delay(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 延时10个OS Tick */
|
/* 延时10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程3入口函数 */
|
/* 线程3入口函数 */
|
||||||
static void thread3_entry(void* parameter)
|
static void thread3_entry(void* parameter)
|
||||||
{
|
{
|
||||||
char buf[] = "this is an urgent message!";
|
char buf[] = "this is an urgent message!";
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread3: send an urgent message\n");
|
rt_kprintf("thread3: send an urgent message\n");
|
||||||
|
|
||||||
/* 发送紧急消息到消息队列中 */
|
/* 发送紧急消息到消息队列中 */
|
||||||
rt_mq_urgent(&mq, &buf[0], sizeof(buf));
|
rt_mq_urgent(&mq, &buf[0], sizeof(buf));
|
||||||
|
|
||||||
/* 延时25个OS Tick */
|
/* 延时25个OS Tick */
|
||||||
rt_thread_delay(25);
|
rt_thread_delay(25);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int messageq_simple_init()
|
int messageq_simple_init()
|
||||||
{
|
{
|
||||||
/* 初始化消息队列 */
|
/* 初始化消息队列 */
|
||||||
rt_mq_init(&mq, "mqt",
|
rt_mq_init(&mq, "mqt",
|
||||||
&msg_pool[0], /* 内存池指向msg_pool */
|
&msg_pool[0], /* 内存池指向msg_pool */
|
||||||
128 - sizeof(void*), /* 每个消息的大小是 128 - void* */
|
128 - sizeof(void*), /* 每个消息的大小是 128 - void* */
|
||||||
sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */
|
sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */
|
||||||
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
|
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("t1",
|
tid1 = rt_thread_create("t1",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("t2",
|
tid2 = rt_thread_create("t2",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程3 */
|
/* 创建线程3 */
|
||||||
tid3 = rt_thread_create("t3",
|
tid3 = rt_thread_create("t3",
|
||||||
thread3_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread3_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid3 != RT_NULL)
|
if (tid3 != RT_NULL)
|
||||||
rt_thread_startup(tid3);
|
rt_thread_startup(tid3);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE)
|
if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid3);
|
rt_thread_delete(tid3);
|
||||||
|
|
||||||
/* 执行消息队列对象脱离 */
|
/* 执行消息队列对象脱离 */
|
||||||
rt_mq_detach(&mq);
|
rt_mq_detach(&mq);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_messageq_simple()
|
int _tc_messageq_simple()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
messageq_simple_init();
|
messageq_simple_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_messageq_simple, a simple message queue example);
|
FINSH_FUNCTION_EXPORT(_tc_messageq_simple, a simple message queue example);
|
||||||
|
@ -160,8 +160,8 @@ FINSH_FUNCTION_EXPORT(_tc_messageq_simple, a simple message queue example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
messageq_simple_init();
|
messageq_simple_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,142 +13,142 @@ static rt_mutex_t mutex = RT_NULL;
|
||||||
/* 线程1入口 */
|
/* 线程1入口 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
/* 先让低优先级线程运行 */
|
/* 先让低优先级线程运行 */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
|
|
||||||
/* 此时thread3持有mutex,并且thread2等待持有mutex */
|
/* 此时thread3持有mutex,并且thread2等待持有mutex */
|
||||||
|
|
||||||
/* 检查thread2与thread3的优先级情况 */
|
/* 检查thread2与thread3的优先级情况 */
|
||||||
if (tid2->current_priority != tid3->current_priority)
|
if (tid2->current_priority != tid3->current_priority)
|
||||||
{
|
{
|
||||||
/* 优先级不相同,测试失败 */
|
/* 优先级不相同,测试失败 */
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口 */
|
/* 线程2入口 */
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
/* 先让低优先级线程运行 */
|
/* 先让低优先级线程运行 */
|
||||||
rt_thread_delay(5);
|
rt_thread_delay(5);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* 试图持有互斥锁,此时thread3持有,应把thread3的优先级提升到thread2相同
|
* 试图持有互斥锁,此时thread3持有,应把thread3的优先级提升到thread2相同
|
||||||
* 的优先级
|
* 的优先级
|
||||||
*/
|
*/
|
||||||
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
|
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
{
|
{
|
||||||
/* 释放互斥锁 */
|
/* 释放互斥锁 */
|
||||||
rt_mutex_release(mutex);
|
rt_mutex_release(mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程3入口 */
|
/* 线程3入口 */
|
||||||
static void thread3_entry(void* parameter)
|
static void thread3_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_tick_t tick;
|
rt_tick_t tick;
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
|
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
|
||||||
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
|
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
|
||||||
if (result != RT_EOK)
|
if (result != RT_EOK)
|
||||||
{
|
{
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 做一个长时间的循环,总共50个OS Tick */
|
/* 做一个长时间的循环,总共50个OS Tick */
|
||||||
tick = rt_tick_get();
|
tick = rt_tick_get();
|
||||||
while (rt_tick_get() - tick < 50) ;
|
while (rt_tick_get() - tick < 50) ;
|
||||||
|
|
||||||
rt_mutex_release(mutex);
|
rt_mutex_release(mutex);
|
||||||
rt_mutex_release(mutex);
|
rt_mutex_release(mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mutex_simple_init()
|
int mutex_simple_init()
|
||||||
{
|
{
|
||||||
/* 创建互斥锁 */
|
/* 创建互斥锁 */
|
||||||
mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO);
|
mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO);
|
||||||
if (mutex == RT_NULL)
|
if (mutex == RT_NULL)
|
||||||
{
|
{
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("t1",
|
tid1 = rt_thread_create("t1",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("t2",
|
tid2 = rt_thread_create("t2",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程3 */
|
/* 创建线程3 */
|
||||||
tid3 = rt_thread_create("t3",
|
tid3 = rt_thread_create("t3",
|
||||||
thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */
|
thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
||||||
if (tid3 != RT_NULL)
|
if (tid3 != RT_NULL)
|
||||||
rt_thread_startup(tid3);
|
rt_thread_startup(tid3);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE)
|
if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid3);
|
rt_thread_delete(tid3);
|
||||||
|
|
||||||
if (mutex != RT_NULL)
|
if (mutex != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_mutex_delete(mutex);
|
rt_mutex_delete(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_mutex_simple()
|
int _tc_mutex_simple()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
mutex_simple_init();
|
mutex_simple_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_mutex_simple, sime mutex example);
|
FINSH_FUNCTION_EXPORT(_tc_mutex_simple, sime mutex example);
|
||||||
|
@ -156,8 +156,8 @@ FINSH_FUNCTION_EXPORT(_tc_mutex_simple, sime mutex example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
mutex_simple_init();
|
mutex_simple_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
/* 一个环形buffer的实现 */
|
/* 一个环形buffer的实现 */
|
||||||
struct rb
|
struct rb
|
||||||
{
|
{
|
||||||
rt_uint16_t read_index, write_index;
|
rt_uint16_t read_index, write_index;
|
||||||
rt_uint8_t *buffer_ptr;
|
rt_uint8_t *buffer_ptr;
|
||||||
rt_uint16_t buffer_size;
|
rt_uint16_t buffer_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 指向信号量控制块的指针 */
|
/* 指向信号量控制块的指针 */
|
||||||
|
@ -23,236 +23,236 @@ static rt_sem_t sem = RT_NULL;
|
||||||
static rt_thread_t tid = RT_NULL, worker = RT_NULL;
|
static rt_thread_t tid = RT_NULL, worker = RT_NULL;
|
||||||
|
|
||||||
/* 环形buffer的内存块(用数组体现出来) */
|
/* 环形buffer的内存块(用数组体现出来) */
|
||||||
#define BUFFER_SIZE 256
|
#define BUFFER_SIZE 256
|
||||||
#define BUFFER_ITEM 32
|
#define BUFFER_ITEM 32
|
||||||
static rt_uint8_t working_buffer[BUFFER_SIZE];
|
static rt_uint8_t working_buffer[BUFFER_SIZE];
|
||||||
struct rb working_rb;
|
struct rb working_rb;
|
||||||
|
|
||||||
/* 初始化环形buffer,size指的是buffer的大小。注:这里并没对数据地址对齐做处理 */
|
/* 初始化环形buffer,size指的是buffer的大小。注:这里并没对数据地址对齐做处理 */
|
||||||
static void rb_init(struct rb* rb, rt_uint8_t *pool, rt_uint16_t size)
|
static void rb_init(struct rb* rb, rt_uint8_t *pool, rt_uint16_t size)
|
||||||
{
|
{
|
||||||
RT_ASSERT(rb != RT_NULL);
|
RT_ASSERT(rb != RT_NULL);
|
||||||
|
|
||||||
/* 对读写指针清零*/
|
/* 对读写指针清零*/
|
||||||
rb->read_index = rb->write_index = 0;
|
rb->read_index = rb->write_index = 0;
|
||||||
|
|
||||||
/* 设置环形buffer的内存数据块 */
|
/* 设置环形buffer的内存数据块 */
|
||||||
rb->buffer_ptr = pool;
|
rb->buffer_ptr = pool;
|
||||||
rb->buffer_size = size;
|
rb->buffer_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 向环形buffer中写入数据 */
|
/* 向环形buffer中写入数据 */
|
||||||
static rt_bool_t rb_put(struct rb* rb, const rt_uint8_t *ptr, rt_uint16_t length)
|
static rt_bool_t rb_put(struct rb* rb, const rt_uint8_t *ptr, rt_uint16_t length)
|
||||||
{
|
{
|
||||||
rt_size_t size;
|
rt_size_t size;
|
||||||
|
|
||||||
/* 判断是否有足够的剩余空间 */
|
/* 判断是否有足够的剩余空间 */
|
||||||
if (rb->read_index > rb->write_index)
|
if (rb->read_index > rb->write_index)
|
||||||
size = rb->read_index - rb->write_index;
|
size = rb->read_index - rb->write_index;
|
||||||
else
|
else
|
||||||
size = rb->buffer_size - rb->write_index + rb->read_index;
|
size = rb->buffer_size - rb->write_index + rb->read_index;
|
||||||
|
|
||||||
/* 没有多余的空间 */
|
/* 没有多余的空间 */
|
||||||
if (size < length) return RT_FALSE;
|
if (size < length) return RT_FALSE;
|
||||||
|
|
||||||
if (rb->read_index > rb->write_index)
|
if (rb->read_index > rb->write_index)
|
||||||
{
|
{
|
||||||
/* read_index - write_index 即为总的空余空间 */
|
/* read_index - write_index 即为总的空余空间 */
|
||||||
memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
|
memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
|
||||||
rb->write_index += length;
|
rb->write_index += length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (rb->buffer_size - rb->write_index > length)
|
if (rb->buffer_size - rb->write_index > length)
|
||||||
{
|
{
|
||||||
/* write_index 后面剩余的空间有足够的长度 */
|
/* write_index 后面剩余的空间有足够的长度 */
|
||||||
memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
|
memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
|
||||||
rb->write_index += length;
|
rb->write_index += length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* write_index 后面剩余的空间不存在足够的长度,需要把部分数据复制到
|
* write_index 后面剩余的空间不存在足够的长度,需要把部分数据复制到
|
||||||
* 前面的剩余空间中
|
* 前面的剩余空间中
|
||||||
*/
|
*/
|
||||||
memcpy(&rb->buffer_ptr[rb->write_index], ptr,
|
memcpy(&rb->buffer_ptr[rb->write_index], ptr,
|
||||||
rb->buffer_size - rb->write_index);
|
rb->buffer_size - rb->write_index);
|
||||||
memcpy(&rb->buffer_ptr[0], &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));
|
length - (rb->buffer_size - rb->write_index));
|
||||||
rb->write_index = length - (rb->buffer_size - rb->write_index);
|
rb->write_index = length - (rb->buffer_size - rb->write_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RT_TRUE;
|
return RT_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 从环形buffer中读出数据 */
|
/* 从环形buffer中读出数据 */
|
||||||
static rt_bool_t rb_get(struct rb* rb, rt_uint8_t *ptr, rt_uint16_t length)
|
static rt_bool_t rb_get(struct rb* rb, rt_uint8_t *ptr, rt_uint16_t length)
|
||||||
{
|
{
|
||||||
rt_size_t size;
|
rt_size_t size;
|
||||||
|
|
||||||
/* 判断是否有足够的数据 */
|
/* 判断是否有足够的数据 */
|
||||||
if (rb->read_index > rb->write_index)
|
if (rb->read_index > rb->write_index)
|
||||||
size = rb->buffer_size - rb->read_index + rb->write_index;
|
size = rb->buffer_size - rb->read_index + rb->write_index;
|
||||||
else
|
else
|
||||||
size = rb->write_index - rb->read_index;
|
size = rb->write_index - rb->read_index;
|
||||||
|
|
||||||
/* 没有足够的数据 */
|
/* 没有足够的数据 */
|
||||||
if (size < length) return RT_FALSE;
|
if (size < length) return RT_FALSE;
|
||||||
|
|
||||||
if (rb->read_index > rb->write_index)
|
if (rb->read_index > rb->write_index)
|
||||||
{
|
{
|
||||||
if (rb->buffer_size - rb->read_index > length)
|
if (rb->buffer_size - rb->read_index > length)
|
||||||
{
|
{
|
||||||
/* read_index的数据足够多,直接复制 */
|
/* read_index的数据足够多,直接复制 */
|
||||||
memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
|
memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
|
||||||
rb->read_index += length;
|
rb->read_index += length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* read_index的数据不够,需要分段复制 */
|
/* read_index的数据不够,需要分段复制 */
|
||||||
memcpy(ptr, &rb->buffer_ptr[rb->read_index],
|
memcpy(ptr, &rb->buffer_ptr[rb->read_index],
|
||||||
rb->buffer_size - rb->read_index);
|
rb->buffer_size - rb->read_index);
|
||||||
memcpy(&ptr[rb->buffer_size - rb->read_index], &rb->buffer_ptr[0],
|
memcpy(&ptr[rb->buffer_size - rb->read_index], &rb->buffer_ptr[0],
|
||||||
length - rb->buffer_size + rb->read_index);
|
length - rb->buffer_size + rb->read_index);
|
||||||
rb->read_index = length - rb->buffer_size + rb->read_index;
|
rb->read_index = length - rb->buffer_size + rb->read_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* read_index要比write_index小,总的数据量够(前面已经有总数据量的判
|
* read_index要比write_index小,总的数据量够(前面已经有总数据量的判
|
||||||
* 断),直接复制出数据。
|
* 断),直接复制出数据。
|
||||||
*/
|
*/
|
||||||
memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
|
memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
|
||||||
rb->read_index += length;
|
rb->read_index += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RT_TRUE;
|
return RT_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 生产者线程入口 */
|
/* 生产者线程入口 */
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_bool_t result;
|
rt_bool_t result;
|
||||||
rt_uint8_t data_buffer[BUFFER_ITEM + 1];
|
rt_uint8_t data_buffer[BUFFER_ITEM + 1];
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 持有信号量 */
|
/* 持有信号量 */
|
||||||
rt_sem_take(sem, RT_WAITING_FOREVER);
|
rt_sem_take(sem, RT_WAITING_FOREVER);
|
||||||
/* 从环buffer中获得数据 */
|
/* 从环buffer中获得数据 */
|
||||||
result = rb_get(&working_rb, &data_buffer[0], BUFFER_ITEM);
|
result = rb_get(&working_rb, &data_buffer[0], BUFFER_ITEM);
|
||||||
/* 释放信号量 */
|
/* 释放信号量 */
|
||||||
rt_sem_release(sem);
|
rt_sem_release(sem);
|
||||||
data_buffer[BUFFER_ITEM] = '\0';
|
data_buffer[BUFFER_ITEM] = '\0';
|
||||||
|
|
||||||
if (result == RT_TRUE)
|
if (result == RT_TRUE)
|
||||||
{
|
{
|
||||||
/* 获取数据成功,打印数据 */
|
/* 获取数据成功,打印数据 */
|
||||||
rt_kprintf("%s\n", data_buffer);
|
rt_kprintf("%s\n", data_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 做一个5 OS Tick的休眠 */
|
/* 做一个5 OS Tick的休眠 */
|
||||||
rt_thread_delay(5);
|
rt_thread_delay(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* worker线程入口 */
|
/* worker线程入口 */
|
||||||
static void worker_entry(void* parameter)
|
static void worker_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_bool_t result;
|
rt_bool_t result;
|
||||||
rt_uint32_t index, setchar;
|
rt_uint32_t index, setchar;
|
||||||
rt_uint8_t data_buffer[BUFFER_ITEM];
|
rt_uint8_t data_buffer[BUFFER_ITEM];
|
||||||
|
|
||||||
setchar = 0x21;
|
setchar = 0x21;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 构造数据 */
|
/* 构造数据 */
|
||||||
for(index = 0; index < BUFFER_ITEM; index++)
|
for(index = 0; index < BUFFER_ITEM; index++)
|
||||||
{
|
{
|
||||||
data_buffer[index] = setchar;
|
data_buffer[index] = setchar;
|
||||||
if (++setchar == 0x7f)
|
if (++setchar == 0x7f)
|
||||||
setchar = 0x21;
|
setchar = 0x21;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 持有信号量 */
|
/* 持有信号量 */
|
||||||
rt_sem_take(sem, RT_WAITING_FOREVER);
|
rt_sem_take(sem, RT_WAITING_FOREVER);
|
||||||
/* 把数据放到环形buffer中 */
|
/* 把数据放到环形buffer中 */
|
||||||
result = rb_put(&working_rb, &data_buffer[0], BUFFER_ITEM);
|
result = rb_put(&working_rb, &data_buffer[0], BUFFER_ITEM);
|
||||||
/* 释放信号量 */
|
/* 释放信号量 */
|
||||||
rt_sem_release(sem);
|
rt_sem_release(sem);
|
||||||
|
|
||||||
/* 放入成功,做一个10 OS Tick的休眠 */
|
/* 放入成功,做一个10 OS Tick的休眠 */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int semaphore_buffer_worker_init()
|
int semaphore_buffer_worker_init()
|
||||||
{
|
{
|
||||||
/* 初始化ring buffer */
|
/* 初始化ring buffer */
|
||||||
rb_init(&working_rb, working_buffer, BUFFER_SIZE);
|
rb_init(&working_rb, working_buffer, BUFFER_SIZE);
|
||||||
|
|
||||||
/* 创建信号量 */
|
/* 创建信号量 */
|
||||||
sem = rt_sem_create("sem", 1, RT_IPC_FLAG_FIFO);
|
sem = rt_sem_create("sem", 1, RT_IPC_FLAG_FIFO);
|
||||||
if (sem == RT_NULL)
|
if (sem == RT_NULL)
|
||||||
{
|
{
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid = rt_thread_create("thread",
|
tid = rt_thread_create("thread",
|
||||||
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
|
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid != RT_NULL)
|
if (tid != RT_NULL)
|
||||||
rt_thread_startup(tid);
|
rt_thread_startup(tid);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
worker = rt_thread_create("worker",
|
worker = rt_thread_create("worker",
|
||||||
worker_entry, RT_NULL, /* 线程入口是worker_entry, 入口参数是RT_NULL */
|
worker_entry, RT_NULL, /* 线程入口是worker_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (worker != RT_NULL)
|
if (worker != RT_NULL)
|
||||||
rt_thread_startup(worker);
|
rt_thread_startup(worker);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除信号量 */
|
/* 删除信号量 */
|
||||||
if (sem != RT_NULL)
|
if (sem != RT_NULL)
|
||||||
rt_sem_delete(sem);
|
rt_sem_delete(sem);
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
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);
|
||||||
if (worker != RT_NULL && worker->stat != RT_THREAD_CLOSE)
|
if (worker != RT_NULL && worker->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(worker);
|
rt_thread_delete(worker);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_semaphore_buffer_worker()
|
int _tc_semaphore_buffer_worker()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
semaphore_buffer_worker_init();
|
semaphore_buffer_worker_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, a buffer worker with semaphore example);
|
FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, a buffer worker with semaphore example);
|
||||||
|
@ -260,8 +260,8 @@ FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, a buffer worker with semaphor
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
semaphore_buffer_worker_init();
|
semaphore_buffer_worker_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,105 +15,112 @@ static rt_sem_t sem = RT_NULL;
|
||||||
/* 线程入口 */
|
/* 线程入口 */
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
rt_tick_t tick;
|
rt_tick_t tick;
|
||||||
|
|
||||||
/* 获得当前的OS Tick */
|
/* 获得当前的OS Tick */
|
||||||
tick = rt_tick_get();
|
tick = rt_tick_get();
|
||||||
|
|
||||||
/* 试图持有一个信号量,如果10个OS Tick依然没拿到,则超时返回 */
|
/* 试图持有一个信号量,如果10个OS Tick依然没拿到,则超时返回 */
|
||||||
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)
|
||||||
/* 如果失败,则测试失败 */
|
{
|
||||||
tc_done(TC_STAT_FAILED);
|
rt_kprintf("tick error to large: expect: 10, get %d\n",
|
||||||
rt_sem_delete(sem);
|
new_tick - tick);
|
||||||
return;
|
|
||||||
}
|
|
||||||
rt_kprintf("take semaphore timeout\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 因为并没释放信号量,应该是超时返回,否则测试失败 */
|
|
||||||
tc_done(TC_STAT_FAILED);
|
|
||||||
rt_sem_delete(sem);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 释放一次信号量 */
|
/* 如果失败,则测试失败 */
|
||||||
rt_sem_release(sem);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* 继续持有信号量,并永远等待直到持有到信号量 */
|
/* 释放一次信号量 */
|
||||||
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
rt_sem_release(sem);
|
||||||
if (result != RT_EOK)
|
|
||||||
{
|
|
||||||
/* 返回不正确,测试失败 */
|
|
||||||
tc_done(TC_STAT_FAILED);
|
|
||||||
rt_sem_delete(sem);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 测试成功 */
|
/* 继续持有信号量,并永远等待直到持有到信号量 */
|
||||||
tc_done(TC_STAT_PASSED);
|
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
||||||
/* 删除信号量 */
|
if (result != RT_EOK)
|
||||||
rt_sem_delete(sem);
|
{
|
||||||
|
/* 返回不正确,测试失败 */
|
||||||
|
tc_done(TC_STAT_FAILED);
|
||||||
|
rt_sem_delete(sem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 测试成功 */
|
||||||
|
tc_done(TC_STAT_PASSED);
|
||||||
|
/* 删除信号量 */
|
||||||
|
rt_sem_delete(sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int semaphore_dynamic_init()
|
int semaphore_dynamic_init()
|
||||||
{
|
{
|
||||||
/* 创建一个信号量,初始值是0 */
|
/* 创建一个信号量,初始值是0 */
|
||||||
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
|
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
|
||||||
if (sem == RT_NULL)
|
if (sem == RT_NULL)
|
||||||
{
|
{
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 创建线程 */
|
/* 创建线程 */
|
||||||
tid = rt_thread_create("thread",
|
tid = rt_thread_create("thread",
|
||||||
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
|
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid != RT_NULL)
|
if (tid != RT_NULL)
|
||||||
rt_thread_startup(tid);
|
rt_thread_startup(tid);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
if (sem)
|
||||||
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
|
{
|
||||||
{
|
rt_sem_delete(sem);
|
||||||
rt_thread_delete(tid);
|
sem = RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* 删除信号量 */
|
/* 删除线程 */
|
||||||
rt_sem_delete(sem);
|
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
|
||||||
}
|
{
|
||||||
|
rt_thread_delete(tid);
|
||||||
|
}
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_semaphore_dynamic()
|
int _tc_semaphore_dynamic()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
semaphore_dynamic_init();
|
semaphore_dynamic_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore example);
|
FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore example);
|
||||||
|
@ -121,8 +128,8 @@ FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
semaphore_dynamic_init();
|
semaphore_dynamic_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,123 +6,129 @@ static rt_uint8_t t1_count, t2_count;
|
||||||
static rt_thread_t t1, t2, worker;
|
static rt_thread_t t1, t2, worker;
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
||||||
if (result != RT_EOK)
|
if (result != RT_EOK)
|
||||||
{
|
{
|
||||||
tc_done(TC_STAT_FAILED);
|
tc_done(TC_STAT_FAILED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t1_count ++;
|
t1_count ++;
|
||||||
rt_kprintf("thread1: got semaphore, count: %d\n", t1_count);
|
rt_kprintf("thread1: got semaphore, count: %d\n", t1_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
||||||
if (result != RT_EOK)
|
if (result != RT_EOK)
|
||||||
{
|
{
|
||||||
tc_done(TC_STAT_FAILED);
|
tc_done(TC_STAT_FAILED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t2_count ++;
|
t2_count ++;
|
||||||
rt_kprintf("thread2: got semaphore, count: %d\n", t2_count);
|
rt_kprintf("thread2: got semaphore, count: %d\n", t2_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void worker_thread_entry(void* parameter)
|
static void worker_thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rt_sem_release(sem);
|
rt_sem_release(sem);
|
||||||
rt_thread_delay(5);
|
rt_thread_delay(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int semaphore_priority_init()
|
int semaphore_priority_init()
|
||||||
{
|
{
|
||||||
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO);
|
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO);
|
||||||
if (sem == RT_NULL)
|
if (sem == RT_NULL)
|
||||||
{
|
{
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
t1_count = t2_count = 0;
|
t1_count = t2_count = 0;
|
||||||
|
|
||||||
t1 = rt_thread_create("t1",
|
t1 = rt_thread_create("t1",
|
||||||
thread1_entry, RT_NULL,
|
thread1_entry, RT_NULL,
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
||||||
if (t1 != RT_NULL)
|
if (t1 != RT_NULL)
|
||||||
rt_thread_startup(t1);
|
rt_thread_startup(t1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
t2 = rt_thread_create("t2",
|
t2 = rt_thread_create("t2",
|
||||||
thread2_entry, RT_NULL,
|
thread2_entry, RT_NULL,
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
||||||
if (t2 != RT_NULL)
|
if (t2 != RT_NULL)
|
||||||
rt_thread_startup(t2);
|
rt_thread_startup(t2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
worker = rt_thread_create("worker",
|
worker = rt_thread_create("worker",
|
||||||
worker_thread_entry, RT_NULL,
|
worker_thread_entry, RT_NULL,
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (worker != RT_NULL)
|
if (worker != RT_NULL)
|
||||||
rt_thread_startup(worker);
|
rt_thread_startup(worker);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* lock scheduler */
|
/* lock scheduler */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* delete t1, t2 and worker thread */
|
/* delete t1, t2 and worker thread */
|
||||||
rt_thread_delete(t1);
|
rt_thread_delete(t1);
|
||||||
rt_thread_delete(t2);
|
rt_thread_delete(t2);
|
||||||
rt_thread_delete(worker);
|
rt_thread_delete(worker);
|
||||||
|
|
||||||
if (t1_count > t2_count)
|
if (sem)
|
||||||
tc_done(TC_STAT_FAILED);
|
{
|
||||||
else
|
rt_sem_delete(sem);
|
||||||
tc_done(TC_STAT_PASSED);
|
sem = RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* unlock scheduler */
|
if (t1_count > t2_count)
|
||||||
rt_exit_critical();
|
tc_done(TC_STAT_FAILED);
|
||||||
|
else
|
||||||
|
tc_done(TC_STAT_PASSED);
|
||||||
|
|
||||||
|
/* unlock scheduler */
|
||||||
|
rt_exit_critical();
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_semaphore_priority()
|
int _tc_semaphore_priority()
|
||||||
{
|
{
|
||||||
/* set tc cleanup */
|
/* set tc cleanup */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
semaphore_priority_init();
|
semaphore_priority_init();
|
||||||
|
|
||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_semaphore_priority, a priority semaphore test);
|
FINSH_FUNCTION_EXPORT(_tc_semaphore_priority, a priority semaphore test);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
semaphore_priority_init();
|
semaphore_priority_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,122 +24,126 @@ struct rt_semaphore sem_empty, sem_full;
|
||||||
/* 生成者线程入口 */
|
/* 生成者线程入口 */
|
||||||
void producer_thread_entry(void* parameter)
|
void producer_thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
/* 运行100次 */
|
/* 运行100次 */
|
||||||
while( cnt < 100)
|
while( cnt < 100)
|
||||||
{
|
{
|
||||||
/* 获取一个空位 */
|
/* 获取一个空位 */
|
||||||
rt_sem_take(&sem_empty, RT_WAITING_FOREVER);
|
rt_sem_take(&sem_empty, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
/* 修改array内容,上锁 */
|
/* 修改array内容,上锁 */
|
||||||
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
|
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
|
||||||
array[set%MAXSEM] = cnt + 1;
|
array[set%MAXSEM] = cnt + 1;
|
||||||
rt_kprintf("the producer generates a number: %d\n", array[set%MAXSEM]);
|
rt_kprintf("the producer generates a number: %d\n", array[set%MAXSEM]);
|
||||||
set++;
|
set++;
|
||||||
rt_sem_release(&sem_lock);
|
rt_sem_release(&sem_lock);
|
||||||
|
|
||||||
/* 发布一个满位 */
|
/* 发布一个满位 */
|
||||||
rt_sem_release(&sem_full);
|
rt_sem_release(&sem_full);
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
/* 暂停一段时间 */
|
/* 暂停一段时间 */
|
||||||
rt_thread_delay(50);
|
rt_thread_delay(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_kprintf("the producer exit!\n");
|
rt_kprintf("the producer exit!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 消费者线程入口 */
|
/* 消费者线程入口 */
|
||||||
void consumer_thread_entry(void* parameter)
|
void consumer_thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint32_t no;
|
rt_uint32_t no;
|
||||||
rt_uint32_t sum;
|
rt_uint32_t sum;
|
||||||
|
|
||||||
/* 第n个线程,由入口参数传进来 */
|
/* 第n个线程,由入口参数传进来 */
|
||||||
no = (rt_uint32_t)parameter;
|
no = (rt_uint32_t)parameter;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
/* 获取一个满位 */
|
/* 获取一个满位 */
|
||||||
rt_sem_take(&sem_full, RT_WAITING_FOREVER);
|
rt_sem_take(&sem_full, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
/* 临界区,上锁进行操作 */
|
/* 临界区,上锁进行操作 */
|
||||||
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
|
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
|
||||||
sum += array[get%MAXSEM];
|
sum += array[get%MAXSEM];
|
||||||
rt_kprintf("the consumer[%d] get a number: %d\n", no, array[get%MAXSEM] );
|
rt_kprintf("the consumer[%d] get a number: %d\n", no, array[get%MAXSEM] );
|
||||||
get++;
|
get++;
|
||||||
rt_sem_release(&sem_lock);
|
rt_sem_release(&sem_lock);
|
||||||
|
|
||||||
/* 释放一个空位 */
|
/* 释放一个空位 */
|
||||||
rt_sem_release(&sem_empty);
|
rt_sem_release(&sem_empty);
|
||||||
|
|
||||||
/* 生产者生产到100个数目,停止,消费者线程相应停止 */
|
/* 生产者生产到100个数目,停止,消费者线程相应停止 */
|
||||||
if (get == 100) break;
|
if (get == 100) break;
|
||||||
|
|
||||||
/* 暂停一小会时间 */
|
/* 暂停一小会时间 */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_kprintf("the consumer[%d] sum is %d \n ", no, sum);
|
rt_kprintf("the consumer[%d] sum is %d \n ", no, sum);
|
||||||
rt_kprintf("the consumer[%d] exit!\n");
|
rt_kprintf("the consumer[%d] exit!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int semaphore_producer_consumer_init()
|
int semaphore_producer_consumer_init()
|
||||||
{
|
{
|
||||||
/* 初始化3个信号量 */
|
/* 初始化3个信号量 */
|
||||||
rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_FIFO);
|
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_empty, "empty", MAXSEM, RT_IPC_FLAG_FIFO);
|
||||||
rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO);
|
rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO);
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
producer_tid = rt_thread_create("producer",
|
producer_tid = rt_thread_create("producer",
|
||||||
producer_thread_entry, RT_NULL, /* 线程入口是producer_thread_entry, 入口参数是RT_NULL */
|
producer_thread_entry, RT_NULL, /* 线程入口是producer_thread_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
||||||
if (producer_tid != RT_NULL)
|
if (producer_tid != RT_NULL)
|
||||||
rt_thread_startup(producer_tid);
|
rt_thread_startup(producer_tid);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
consumer_tid = rt_thread_create("consumer",
|
consumer_tid = rt_thread_create("consumer",
|
||||||
consumer_thread_entry, RT_NULL, /* 线程入口是consumer_thread_entry, 入口参数是RT_NULL */
|
consumer_thread_entry, RT_NULL, /* 线程入口是consumer_thread_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
||||||
if (consumer_tid != RT_NULL)
|
if (consumer_tid != RT_NULL)
|
||||||
rt_thread_startup(consumer_tid);
|
rt_thread_startup(consumer_tid);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
rt_sem_detach(&sem_lock);
|
||||||
if (producer_tid != RT_NULL && producer_tid->stat != RT_THREAD_CLOSE)
|
rt_sem_detach(&sem_empty);
|
||||||
rt_thread_delete(producer_tid);
|
rt_sem_detach(&sem_full);
|
||||||
if (consumer_tid != RT_NULL && consumer_tid->stat != RT_THREAD_CLOSE)
|
|
||||||
rt_thread_delete(consumer_tid);
|
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 删除线程 */
|
||||||
rt_exit_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);
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 调度器解锁 */
|
||||||
tc_done(TC_STAT_PASSED);
|
rt_exit_critical();
|
||||||
|
|
||||||
|
/* 设置TestCase状态 */
|
||||||
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_semaphore_producer_consumer()
|
int _tc_semaphore_producer_consumer()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
semaphore_producer_consumer_init();
|
semaphore_producer_consumer_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_semaphore_producer_consumer, producer and consumer example);
|
FINSH_FUNCTION_EXPORT(_tc_semaphore_producer_consumer, producer and consumer example);
|
||||||
|
@ -147,8 +151,8 @@ FINSH_FUNCTION_EXPORT(_tc_semaphore_producer_consumer, producer and consumer exa
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
semaphore_producer_consumer_init();
|
semaphore_producer_consumer_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,107 +17,111 @@ static struct rt_semaphore sem;
|
||||||
/* 线程入口 */
|
/* 线程入口 */
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
rt_tick_t tick;
|
rt_tick_t tick;
|
||||||
|
|
||||||
/* 获得当前的OS Tick */
|
/* 获得当前的OS Tick */
|
||||||
tick = rt_tick_get();
|
tick = rt_tick_get();
|
||||||
|
|
||||||
/* 试图持有信号量,最大等待10个OS Tick后返回 */
|
/* 试图持有信号量,最大等待10个OS Tick后返回 */
|
||||||
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)
|
||||||
tc_done(TC_STAT_FAILED);
|
{
|
||||||
rt_sem_detach(&sem);
|
rt_kprintf("tick error to large: expect: 10, get %d\n",
|
||||||
return;
|
new_tick - tick);
|
||||||
}
|
|
||||||
rt_kprintf("take semaphore timeout\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 因为没有其他地方是否信号量,所以不应该成功持有信号量,否则测试失败 */
|
|
||||||
tc_done(TC_STAT_FAILED);
|
|
||||||
rt_sem_detach(&sem);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 释放一次信号量 */
|
tc_done(TC_STAT_FAILED);
|
||||||
rt_sem_release(&sem);
|
rt_sem_detach(&sem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rt_kprintf("take semaphore timeout\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 因为没有其他地方是否信号量,所以不应该成功持有信号量,否则测试失败 */
|
||||||
|
tc_done(TC_STAT_FAILED);
|
||||||
|
rt_sem_detach(&sem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* 永久等待方式持有信号量 */
|
/* 释放一次信号量 */
|
||||||
result = rt_sem_take(&sem, RT_WAITING_FOREVER);
|
rt_sem_release(&sem);
|
||||||
if (result != RT_EOK)
|
|
||||||
{
|
|
||||||
/* 不成功则测试失败 */
|
|
||||||
tc_done(TC_STAT_FAILED);
|
|
||||||
rt_sem_detach(&sem);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 测试通过 */
|
/* 永久等待方式持有信号量 */
|
||||||
tc_done(TC_STAT_PASSED);
|
result = rt_sem_take(&sem, RT_WAITING_FOREVER);
|
||||||
/* 脱离信号量对象 */
|
if (result != RT_EOK)
|
||||||
rt_sem_detach(&sem);
|
{
|
||||||
|
/* 不成功则测试失败 */
|
||||||
|
tc_done(TC_STAT_FAILED);
|
||||||
|
rt_sem_detach(&sem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 测试通过 */
|
||||||
|
tc_done(TC_STAT_PASSED);
|
||||||
|
/* 脱离信号量对象 */
|
||||||
|
rt_sem_detach(&sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int semaphore_static_init(void)
|
int semaphore_static_init(void)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
/* 初始化信号量,初始值是0 */
|
/* 初始化信号量,初始值是0 */
|
||||||
result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO);
|
result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO);
|
||||||
if (result != RT_EOK)
|
if (result != RT_EOK)
|
||||||
{
|
{
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 初始化线程1 */
|
/* 初始化线程1 */
|
||||||
result = rt_thread_init(&thread, "thread", /* 线程名:thread */
|
result = rt_thread_init(&thread, "thread", /* 线程名:thread */
|
||||||
thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是RT_NULL*/
|
thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是RT_NULL*/
|
||||||
&thread_stack[0], sizeof(thread_stack), /* 线程栈是thread_stack */
|
&thread_stack[0], sizeof(thread_stack), /* 线程栈是thread_stack */
|
||||||
THREAD_PRIORITY, 10);
|
THREAD_PRIORITY, 10);
|
||||||
if (result == RT_EOK) /* 如果返回正确,启动线程1 */
|
if (result == RT_EOK) /* 如果返回正确,启动线程1 */
|
||||||
rt_thread_startup(&thread);
|
rt_thread_startup(&thread);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup(void)
|
static void _tc_cleanup(void)
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 执行线程脱离 */
|
/* 执行线程脱离 */
|
||||||
if (thread.stat != RT_THREAD_CLOSE)
|
if (thread.stat != RT_THREAD_CLOSE)
|
||||||
{
|
{
|
||||||
rt_thread_detach(&thread);
|
rt_thread_detach(&thread);
|
||||||
|
|
||||||
/* 执行信号量对象脱离 */
|
/* 执行信号量对象脱离 */
|
||||||
rt_sem_detach(&sem);
|
rt_sem_detach(&sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_semaphore_static(void)
|
int _tc_semaphore_static(void)
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
semaphore_static_init();
|
semaphore_static_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example);
|
FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example);
|
||||||
|
@ -125,8 +129,8 @@ FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init(void)
|
int rt_application_init(void)
|
||||||
{
|
{
|
||||||
semaphore_static_init();
|
semaphore_static_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
#define TC_PRIORITY 25
|
#define TC_PRIORITY 25
|
||||||
#define TC_STACK_SIZE 0x400
|
#define TC_STACK_SIZE 0x400
|
||||||
|
|
||||||
static rt_uint8_t _tc_stat;
|
static rt_uint8_t _tc_stat;
|
||||||
static struct rt_semaphore _tc_sem;
|
static struct rt_semaphore _tc_sem;
|
||||||
|
@ -18,158 +18,180 @@ static void (*_tc_cleanup)(void) = RT_NULL;
|
||||||
static rt_uint32_t _tc_scale = 1;
|
static rt_uint32_t _tc_scale = 1;
|
||||||
FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale)
|
FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale)
|
||||||
|
|
||||||
|
static rt_uint32_t _tc_loop;
|
||||||
|
|
||||||
void tc_thread_entry(void* parameter)
|
void tc_thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
struct finsh_syscall* index;
|
unsigned int fail_count = 0;
|
||||||
|
struct finsh_syscall* index;
|
||||||
|
|
||||||
/* create tc semaphore */
|
/* create tc semaphore */
|
||||||
rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO);
|
rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO);
|
||||||
|
|
||||||
while (_tc_stat & TC_STAT_RUNNING)
|
do {
|
||||||
{
|
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
|
||||||
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
|
{
|
||||||
{
|
/* search testcase */
|
||||||
/* search testcase */
|
if (rt_strstr(index->name, _tc_prefix) == index->name)
|
||||||
if (rt_strstr(index->name, _tc_prefix) == index->name)
|
{
|
||||||
{
|
long tick;
|
||||||
long tick;
|
|
||||||
|
|
||||||
_tc_current = index->name + 4;
|
_tc_current = index->name + 4;
|
||||||
rt_kprintf("Run TestCase: %s\n", _tc_current);
|
rt_kprintf("Run TestCase: %s\n", _tc_current);
|
||||||
_tc_stat = TC_STAT_PASSED | TC_STAT_RUNNING;
|
_tc_stat = TC_STAT_PASSED | TC_STAT_RUNNING;
|
||||||
tick = index->func();
|
tick = index->func();
|
||||||
if (tick > 0)
|
if (tick > 0)
|
||||||
{
|
{
|
||||||
rt_sem_take(&_tc_sem, tick * _tc_scale);
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
if (_tc_cleanup != RT_NULL)
|
if (_tc_cleanup != RT_NULL)
|
||||||
{
|
{
|
||||||
/* perform testcase cleanup */
|
/* perform testcase cleanup */
|
||||||
_tc_cleanup();
|
_tc_cleanup();
|
||||||
_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);
|
{
|
||||||
else
|
rt_kprintf("TestCase[%s] failed\n", _tc_current);
|
||||||
rt_kprintf("TestCase[%s] passed\n", _tc_current);
|
fail_count++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_tc_cleanup != RT_NULL)
|
rt_kprintf("TestCase[%s] passed\n", _tc_current);
|
||||||
{
|
}
|
||||||
/* perform testcase cleanup */
|
}
|
||||||
_tc_cleanup();
|
}
|
||||||
_tc_cleanup = RT_NULL;
|
} while (_tc_loop);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_kprintf("RT-Thread TestCase Running Done!\n");
|
rt_kprintf("RT-Thread TestCase Running Done!\n");
|
||||||
/* detach tc semaphore */
|
if (fail_count)
|
||||||
rt_sem_detach(&_tc_sem);
|
{
|
||||||
|
rt_kprintf("%d tests failed\n", fail_count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("All tests passed\n");
|
||||||
|
}
|
||||||
|
/* detach tc semaphore */
|
||||||
|
rt_sem_detach(&_tc_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tc_stop()
|
void tc_stop()
|
||||||
{
|
{
|
||||||
_tc_stat &= ~TC_STAT_RUNNING;
|
_tc_loop = 0;
|
||||||
|
|
||||||
rt_thread_delay(RT_TICK_PER_SECOND/2);
|
rt_thread_delay(10 * RT_TICK_PER_SECOND);
|
||||||
if (_tc_thread.stat != RT_THREAD_INIT)
|
if (_tc_thread.stat != RT_THREAD_INIT)
|
||||||
{
|
{
|
||||||
/* lock scheduler */
|
/* lock scheduler */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* detach old tc thread */
|
/* detach old tc thread */
|
||||||
rt_thread_detach(&_tc_thread);
|
rt_thread_detach(&_tc_thread);
|
||||||
rt_sem_detach(&_tc_sem);
|
rt_sem_detach(&_tc_sem);
|
||||||
|
|
||||||
/* unlock scheduler */
|
/* unlock scheduler */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
}
|
}
|
||||||
rt_thread_delay(RT_TICK_PER_SECOND/2);
|
rt_thread_delay(RT_TICK_PER_SECOND/2);
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(tc_stop, stop testcase thread);
|
FINSH_FUNCTION_EXPORT(tc_stop, stop testcase thread);
|
||||||
|
|
||||||
void tc_done(rt_uint8_t stat)
|
void tc_done(rt_uint8_t stat)
|
||||||
{
|
{
|
||||||
_tc_stat |= stat;
|
_tc_stat |= stat;
|
||||||
_tc_stat &= ~TC_STAT_RUNNING;
|
_tc_stat &= ~TC_STAT_RUNNING;
|
||||||
|
|
||||||
/* release semaphore */
|
/* release semaphore */
|
||||||
rt_sem_release(&_tc_sem);
|
rt_sem_release(&_tc_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tc_stat(rt_uint8_t stat)
|
void tc_stat(rt_uint8_t stat)
|
||||||
{
|
{
|
||||||
if (stat & TC_STAT_FAILED)
|
if (stat & TC_STAT_FAILED)
|
||||||
{
|
{
|
||||||
rt_kprintf("TestCases[%s] failed\n", _tc_current);
|
rt_kprintf("TestCases[%s] failed\n", _tc_current);
|
||||||
}
|
}
|
||||||
_tc_stat |= stat;
|
_tc_stat |= stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tc_cleanup(void (*cleanup)())
|
void tc_cleanup(void (*cleanup)())
|
||||||
{
|
{
|
||||||
_tc_cleanup = cleanup;
|
_tc_cleanup = cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tc_start(const char* tc_prefix)
|
void tc_start(const char* tc_prefix)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
/* tesecase prefix is null */
|
/* tesecase prefix is null */
|
||||||
if (tc_prefix == RT_NULL)
|
if (tc_prefix == RT_NULL)
|
||||||
{
|
{
|
||||||
rt_kprintf("TestCase Usage: tc_start(prefix)\n\n");
|
rt_kprintf("TestCase Usage: tc_start(prefix)\n\n");
|
||||||
rt_kprintf("list_tc() can list all testcases.\n");
|
rt_kprintf("list_tc() can list all testcases.\n");
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init tc thread */
|
/* init tc thread */
|
||||||
if (_tc_stat & TC_STAT_RUNNING)
|
if (_tc_stat & TC_STAT_RUNNING)
|
||||||
{
|
{
|
||||||
/* stop old tc thread */
|
/* stop old tc thread */
|
||||||
tc_stop();
|
tc_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_memset(_tc_prefix, 0, sizeof(_tc_prefix));
|
rt_memset(_tc_prefix, 0, sizeof(_tc_prefix));
|
||||||
rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix);
|
rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix);
|
||||||
|
|
||||||
result = rt_thread_init(&_tc_thread, "tc",
|
result = rt_thread_init(&_tc_thread, "tc",
|
||||||
tc_thread_entry, RT_NULL,
|
tc_thread_entry, RT_NULL,
|
||||||
&_tc_stack[0], sizeof(_tc_stack),
|
&_tc_stack[0], sizeof(_tc_stack),
|
||||||
TC_PRIORITY - 3, 5);
|
TC_PRIORITY - 3, 5);
|
||||||
|
|
||||||
/* set tc stat */
|
/* set tc stat */
|
||||||
_tc_stat = TC_STAT_RUNNING | TC_STAT_FAILED;
|
_tc_stat = TC_STAT_RUNNING | TC_STAT_FAILED;
|
||||||
|
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
rt_thread_startup(&_tc_thread);
|
rt_thread_startup(&_tc_thread);
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(tc_start, start testcase with testcase prefix or name);
|
FINSH_FUNCTION_EXPORT(tc_start, start testcase with testcase prefix or name);
|
||||||
|
|
||||||
|
void tc_loop(const char *tc_prefix)
|
||||||
|
{
|
||||||
|
_tc_loop = 1;
|
||||||
|
tc_start(tc_prefix);
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT(tc_loop, start testcase with testcase prefix or name in loop mode);
|
||||||
|
|
||||||
void list_tc()
|
void list_tc()
|
||||||
{
|
{
|
||||||
struct finsh_syscall* index;
|
struct finsh_syscall* index;
|
||||||
|
|
||||||
rt_kprintf("TestCases List:\n");
|
rt_kprintf("TestCases List:\n");
|
||||||
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
|
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
|
||||||
{
|
{
|
||||||
/* search testcase */
|
/* search testcase */
|
||||||
if (rt_strstr(index->name, "_tc_") == index->name)
|
if (rt_strstr(index->name, "_tc_") == index->name)
|
||||||
{
|
{
|
||||||
#ifdef FINSH_USING_DESCRIPTION
|
#ifdef FINSH_USING_DESCRIPTION
|
||||||
rt_kprintf("%-16s -- %s\n", index->name + 4, index->desc);
|
rt_kprintf("%-16s -- %s\n", index->name + 4, index->desc);
|
||||||
#else
|
#else
|
||||||
rt_kprintf("%s\n", index->name + 4);
|
rt_kprintf("%s\n", index->name + 4);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(list_tc, list all testcases);
|
FINSH_FUNCTION_EXPORT(list_tc, list all testcases);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,19 +11,19 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RT_THREAD_PRIORITY_MAX == 8
|
#if RT_THREAD_PRIORITY_MAX == 8
|
||||||
#define THREAD_PRIORITY 6
|
#define THREAD_PRIORITY 6
|
||||||
#elif RT_THREAD_PRIORITY_MAX == 32
|
#elif RT_THREAD_PRIORITY_MAX == 32
|
||||||
#define THREAD_PRIORITY 25
|
#define THREAD_PRIORITY 25
|
||||||
#elif RT_THREAD_PRIORITY_MAX == 256
|
#elif RT_THREAD_PRIORITY_MAX == 256
|
||||||
#define THREAD_PRIORITY 200
|
#define THREAD_PRIORITY 200
|
||||||
#endif
|
#endif
|
||||||
#define THREAD_STACK_SIZE 512
|
#define THREAD_STACK_SIZE 512
|
||||||
#define THREAD_TIMESLICE 5
|
#define THREAD_TIMESLICE 5
|
||||||
|
|
||||||
#define TC_STAT_END 0x00
|
#define TC_STAT_END 0x00
|
||||||
#define TC_STAT_RUNNING 0x01
|
#define TC_STAT_RUNNING 0x01
|
||||||
#define TC_STAT_FAILED 0x10
|
#define TC_STAT_FAILED 0x10
|
||||||
#define TC_STAT_PASSED 0x00
|
#define TC_STAT_PASSED 0x00
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
void tc_start(const char* tc_prefix);
|
void tc_start(const char* tc_prefix);
|
||||||
|
|
|
@ -4,59 +4,59 @@
|
||||||
static rt_thread_t tid = RT_NULL;
|
static rt_thread_t tid = RT_NULL;
|
||||||
static void sample_thread(void* parameter)
|
static void sample_thread(void* parameter)
|
||||||
{
|
{
|
||||||
rt_kprintf("I'm sample!\n");
|
rt_kprintf("I'm sample!\n");
|
||||||
}
|
}
|
||||||
static void sample_thread_cleanup(struct rt_thread *p)
|
static void sample_thread_cleanup(struct rt_thread *p)
|
||||||
{
|
{
|
||||||
tid = RT_NULL;
|
tid = RT_NULL;
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sample_init()
|
int sample_init()
|
||||||
{
|
{
|
||||||
tid = rt_thread_create("t",
|
tid = rt_thread_create("t",
|
||||||
sample_thread, RT_NULL,
|
sample_thread, RT_NULL,
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid != RT_NULL)
|
if (tid != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_thread_startup(tid);
|
rt_thread_startup(tid);
|
||||||
tid->cleanup = sample_thread_cleanup;
|
tid->cleanup = sample_thread_cleanup;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* lock scheduler */
|
/* lock scheduler */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
/* delete thread */
|
/* delete thread */
|
||||||
if (tid != RT_NULL)
|
if (tid != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_kprintf("tid1 is bad\n");
|
rt_kprintf("tid1 is bad\n");
|
||||||
tc_stat(TC_STAT_FAILED);
|
tc_stat(TC_STAT_FAILED);
|
||||||
}
|
}
|
||||||
/* unlock scheduler */
|
/* unlock scheduler */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_sample()
|
int _tc_sample()
|
||||||
{
|
{
|
||||||
/* set tc cleanup */
|
/* set tc cleanup */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
sample_init();
|
sample_init();
|
||||||
|
|
||||||
return 25;
|
return 25;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_sample, a thread testcase example);
|
FINSH_FUNCTION_EXPORT(_tc_sample, a thread testcase example);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
sample_init();
|
sample_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,63 +8,63 @@ static struct rt_thread thread;
|
||||||
static char thread_stack[THREAD_STACK_SIZE];
|
static char thread_stack[THREAD_STACK_SIZE];
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_tick_t tick;
|
rt_tick_t tick;
|
||||||
rt_kprintf("thread inited ok\n");
|
rt_kprintf("thread inited ok\n");
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_kprintf("thread exit\n");
|
rt_kprintf("thread exit\n");
|
||||||
|
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_err_t thread_delay_init()
|
rt_err_t thread_delay_init()
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
result = rt_thread_init(&thread,
|
result = rt_thread_init(&thread,
|
||||||
"test",
|
"test",
|
||||||
thread_entry, RT_NULL,
|
thread_entry, RT_NULL,
|
||||||
&thread_stack[0], sizeof(thread_stack),
|
&thread_stack[0], sizeof(thread_stack),
|
||||||
THREAD_PRIORITY, 10);
|
THREAD_PRIORITY, 10);
|
||||||
|
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
rt_thread_startup(&thread);
|
rt_thread_startup(&thread);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
int _tc_thread_delay()
|
int _tc_thread_delay()
|
||||||
{
|
{
|
||||||
thread_delay_init();
|
thread_delay_init();
|
||||||
|
|
||||||
return 30;
|
return 30;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_delay, a thread delay test);
|
FINSH_FUNCTION_EXPORT(_tc_thread_delay, a thread delay test);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_delay_init();
|
thread_delay_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,130 +15,128 @@ static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL;
|
||||||
/* 线程1的入口函数 */
|
/* 线程1的入口函数 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint32_t count = 0;
|
rt_uint32_t count = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 线程1采用低优先级运行,一直打印计数值 */
|
/* 线程1采用低优先级运行,一直打印计数值 */
|
||||||
// rt_kprintf("thread count: %d\n", count ++);
|
// rt_kprintf("thread count: %d\n", count ++);
|
||||||
count ++;
|
count ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void thread1_cleanup(struct rt_thread *tid)
|
static void thread1_cleanup(struct rt_thread *tid)
|
||||||
{
|
{
|
||||||
if (tid != tid1)
|
if (tid != tid1)
|
||||||
{
|
{
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
rt_kprintf("thread1 end\n");
|
rt_kprintf("thread1 end\n");
|
||||||
tid1 = RT_NULL;
|
tid1 = RT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2的入口函数 */
|
/* 线程2的入口函数 */
|
||||||
static void thread2_entry(void* parameter)
|
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自动脱离就绪线程
|
||||||
* 队列
|
* 队列
|
||||||
*/
|
*/
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 线程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)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线
|
* 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线
|
||||||
* 程中释放)
|
* 程中释放)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (tid != tid2)
|
if (tid != tid2)
|
||||||
{
|
{
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
rt_kprintf("thread2 end\n");
|
rt_kprintf("thread2 end\n");
|
||||||
tid2 = RT_NULL;
|
tid2 = RT_NULL;
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程删除示例的初始化 */
|
/* 线程删除示例的初始化 */
|
||||||
int thread_delete_init()
|
int thread_delete_init()
|
||||||
{
|
{
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */
|
tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */
|
||||||
thread1_entry, RT_NULL, /* 入口是thread1_entry,参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 入口是thread1_entry,参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
|
if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
|
||||||
{
|
{
|
||||||
tid1->cleanup = thread1_cleanup;
|
tid1->cleanup = thread1_cleanup;
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */
|
tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */
|
||||||
thread2_entry, RT_NULL, /* 入口是thread2_entry,参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 入口是thread2_entry,参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
|
if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
|
||||||
{
|
{
|
||||||
tid2->cleanup = thread2_cleanup;
|
tid2->cleanup = thread2_cleanup;
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
}
|
}
|
||||||
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
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* lock scheduler */
|
/* lock scheduler */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unlock scheduler */
|
/* unlock scheduler */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_thread_delete()
|
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
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_delete_init();
|
thread_delete_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,92 +18,92 @@ static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
|
||||||
/* 线程1入口 */
|
/* 线程1入口 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint32_t count = 0;
|
rt_uint32_t count = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 线程1采用低优先级运行,一直打印计数值 */
|
/* 线程1采用低优先级运行,一直打印计数值 */
|
||||||
rt_kprintf("thread count: %d\n", count ++);
|
rt_kprintf("thread count: %d\n", count ++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口 */
|
/* 线程2入口 */
|
||||||
static void thread2_entry(void* parameter)
|
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(10);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 线程2唤醒后直接执行线程1脱离,线程1将从就绪线程队列中删除
|
* 线程2唤醒后直接执行线程1脱离,线程1将从就绪线程队列中删除
|
||||||
*/
|
*/
|
||||||
rt_thread_detach(&thread1);
|
rt_thread_detach(&thread1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 线程2继续休眠10个OS Tick然后退出
|
* 线程2继续休眠10个OS Tick然后退出
|
||||||
*/
|
*/
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 线程2运行结束后也将自动被从就绪队列中删除,并脱离线程队列
|
* 线程2运行结束后也将自动被从就绪队列中删除,并脱离线程队列
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_detach_init()
|
int thread_detach_init()
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
/* 初始化线程1 */
|
/* 初始化线程1 */
|
||||||
result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */
|
result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */
|
||||||
thread1_entry, RT_NULL, /* 线程的入口是thread1_entry,入口参数是RT_NULL*/
|
thread1_entry, RT_NULL, /* 线程的入口是thread1_entry,入口参数是RT_NULL*/
|
||||||
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
|
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
|
||||||
THREAD_PRIORITY, 10);
|
THREAD_PRIORITY, 10);
|
||||||
if (result == RT_EOK) /* 如果返回正确,启动线程1 */
|
if (result == RT_EOK) /* 如果返回正确,启动线程1 */
|
||||||
rt_thread_startup(&thread1);
|
rt_thread_startup(&thread1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 初始化线程2 */
|
/* 初始化线程2 */
|
||||||
result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */
|
result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */
|
||||||
thread2_entry, RT_NULL, /* 线程的入口是thread2_entry,入口参数是RT_NULL*/
|
thread2_entry, RT_NULL, /* 线程的入口是thread2_entry,入口参数是RT_NULL*/
|
||||||
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
|
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
|
||||||
THREAD_PRIORITY - 1, 10);
|
THREAD_PRIORITY - 1, 10);
|
||||||
if (result == RT_EOK) /* 如果返回正确,启动线程2 */
|
if (result == RT_EOK) /* 如果返回正确,启动线程2 */
|
||||||
rt_thread_startup(&thread2);
|
rt_thread_startup(&thread2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 执行线程脱离 */
|
/* 执行线程脱离 */
|
||||||
if (thread1.stat != RT_THREAD_CLOSE)
|
if (thread1.stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_detach(&thread1);
|
rt_thread_detach(&thread1);
|
||||||
if (thread2.stat != RT_THREAD_CLOSE)
|
if (thread2.stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_detach(&thread2);
|
rt_thread_detach(&thread2);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_thread_detach()
|
int _tc_thread_detach()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
thread_detach_init();
|
thread_detach_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 25;
|
return 25;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_detach, a static thread example);
|
FINSH_FUNCTION_EXPORT(_tc_thread_detach, a static thread example);
|
||||||
|
@ -111,8 +111,8 @@ FINSH_FUNCTION_EXPORT(_tc_thread_detach, a static thread example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_detach_init();
|
thread_detach_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,42 +3,42 @@
|
||||||
|
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread dynamicly created ok\n");
|
rt_kprintf("thread dynamicly created ok\n");
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
rt_kprintf("thread exit\n");
|
rt_kprintf("thread exit\n");
|
||||||
|
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_dynamic_init()
|
int thread_dynamic_init()
|
||||||
{
|
{
|
||||||
rt_thread_t tid;
|
rt_thread_t tid;
|
||||||
|
|
||||||
tid = rt_thread_create("test",
|
tid = rt_thread_create("test",
|
||||||
thread_entry, RT_NULL,
|
thread_entry, RT_NULL,
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid != RT_NULL)
|
if (tid != RT_NULL)
|
||||||
rt_thread_startup(tid);
|
rt_thread_startup(tid);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
int _tc_thread_dynamic()
|
int _tc_thread_dynamic()
|
||||||
{
|
{
|
||||||
thread_dynamic_init();
|
thread_dynamic_init();
|
||||||
|
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_dynamic, a dynamic thread test);
|
FINSH_FUNCTION_EXPORT(_tc_thread_dynamic, a dynamic thread test);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_dynamic_init();
|
thread_dynamic_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -12,69 +12,69 @@ static rt_thread_t tid2 = RT_NULL;
|
||||||
/* 线程入口 */
|
/* 线程入口 */
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint32_t count = 0;
|
rt_uint32_t count = 0;
|
||||||
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
|
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 打印线程计数值输出 */
|
/* 打印线程计数值输出 */
|
||||||
rt_kprintf("thread%d count: %d\n", no, count ++);
|
rt_kprintf("thread%d count: %d\n", no, count ++);
|
||||||
|
|
||||||
/* 休眠10个OS Tick */
|
/* 休眠10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_dynamic_simple_init()
|
int thread_dynamic_simple_init()
|
||||||
{
|
{
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("t1",
|
tid1 = rt_thread_create("t1",
|
||||||
thread_entry, (void*)1, /* 线程入口是thread_entry, 入口参数是1 */
|
thread_entry, (void*)1, /* 线程入口是thread_entry, 入口参数是1 */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("t2",
|
tid2 = rt_thread_create("t2",
|
||||||
thread_entry, (void*)2, /* 线程入口是thread_entry, 入口参数是2 */
|
thread_entry, (void*)2, /* 线程入口是thread_entry, 入口参数是2 */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_thread_dynamic_simple()
|
int _tc_thread_dynamic_simple()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
thread_dynamic_simple_init();
|
thread_dynamic_simple_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_dynamic_simple, a dynamic thread example);
|
FINSH_FUNCTION_EXPORT(_tc_thread_dynamic_simple, a dynamic thread example);
|
||||||
|
@ -82,8 +82,8 @@ FINSH_FUNCTION_EXPORT(_tc_thread_dynamic_simple, a dynamic thread example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_dynamic_simple_init();
|
thread_dynamic_simple_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,94 +12,94 @@ static rt_uint32_t count = 0;
|
||||||
*/
|
*/
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
count ++;
|
count ++;
|
||||||
rt_kprintf("count = %d\n", count);
|
rt_kprintf("count = %d\n", count);
|
||||||
|
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_tick_t tick;
|
rt_tick_t tick;
|
||||||
|
|
||||||
tick = rt_tick_get();
|
tick = rt_tick_get();
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (rt_tick_get() - tick >= 50)
|
if (rt_tick_get() - tick >= 50)
|
||||||
{
|
{
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
tc_done(TC_STAT_FAILED);
|
tc_done(TC_STAT_FAILED);
|
||||||
else
|
else
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_priority_init()
|
int thread_priority_init()
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
result = rt_thread_init(&thread1,
|
result = rt_thread_init(&thread1,
|
||||||
"t1",
|
"t1",
|
||||||
thread1_entry, RT_NULL,
|
thread1_entry, RT_NULL,
|
||||||
&thread1_stack[0], sizeof(thread1_stack),
|
&thread1_stack[0], sizeof(thread1_stack),
|
||||||
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
||||||
|
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
rt_thread_startup(&thread1);
|
rt_thread_startup(&thread1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_FAILED);
|
tc_stat(TC_STAT_FAILED);
|
||||||
|
|
||||||
rt_thread_init(&thread2,
|
rt_thread_init(&thread2,
|
||||||
"t2",
|
"t2",
|
||||||
thread2_entry, RT_NULL,
|
thread2_entry, RT_NULL,
|
||||||
&thread2_stack[0], sizeof(thread2_stack),
|
&thread2_stack[0], sizeof(thread2_stack),
|
||||||
THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
THREAD_PRIORITY + 1, THREAD_TIMESLICE);
|
||||||
|
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
rt_thread_startup(&thread2);
|
rt_thread_startup(&thread2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_FAILED);
|
tc_stat(TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* lock scheduler */
|
/* lock scheduler */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
if (thread1.stat != RT_THREAD_CLOSE)
|
if (thread1.stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_detach(&thread1);
|
rt_thread_detach(&thread1);
|
||||||
if (thread2.stat != RT_THREAD_CLOSE)
|
if (thread2.stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_detach(&thread2);
|
rt_thread_detach(&thread2);
|
||||||
|
|
||||||
/* unlock scheduler */
|
/* unlock scheduler */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
}
|
}
|
||||||
int _tc_thread_priority()
|
int _tc_thread_priority()
|
||||||
{
|
{
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
/* set tc cleanup */
|
/* set tc cleanup */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
thread_priority_init();
|
thread_priority_init();
|
||||||
|
|
||||||
return RT_TICK_PER_SECOND;
|
return RT_TICK_PER_SECOND;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_priority, a priority thread test);
|
FINSH_FUNCTION_EXPORT(_tc_thread_priority, a priority thread test);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_priority_init();
|
thread_priority_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -13,102 +13,102 @@ static rt_thread_t tid2 = RT_NULL;
|
||||||
/* 线程1入口 */
|
/* 线程1入口 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
/* 低优先级线程1开始运行 */
|
/* 低优先级线程1开始运行 */
|
||||||
rt_kprintf("thread1 startup%d\n");
|
rt_kprintf("thread1 startup%d\n");
|
||||||
|
|
||||||
/* 挂起自身 */
|
/* 挂起自身 */
|
||||||
rt_kprintf("suspend thread self\n");
|
rt_kprintf("suspend thread self\n");
|
||||||
rt_thread_suspend(tid1);
|
rt_thread_suspend(tid1);
|
||||||
/* 主动执行线程调度 */
|
/* 主动执行线程调度 */
|
||||||
rt_schedule();
|
rt_schedule();
|
||||||
|
|
||||||
/* 当线程1被唤醒时 */
|
/* 当线程1被唤醒时 */
|
||||||
rt_kprintf("thread1 resumed\n");
|
rt_kprintf("thread1 resumed\n");
|
||||||
}
|
}
|
||||||
static void thread_cleanup(rt_thread_t tid)
|
static void thread_cleanup(rt_thread_t tid)
|
||||||
{
|
{
|
||||||
if (tid == tid1)
|
if (tid == tid1)
|
||||||
{
|
{
|
||||||
tid1 = RT_NULL;
|
tid1 = RT_NULL;
|
||||||
}
|
}
|
||||||
if (tid == tid2)
|
if (tid == tid2)
|
||||||
{
|
{
|
||||||
tid = RT_NULL;
|
tid = RT_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口 */
|
/* 线程2入口 */
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
/* 延时10个OS Tick */
|
/* 延时10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
|
|
||||||
/* 唤醒线程1 */
|
/* 唤醒线程1 */
|
||||||
rt_thread_resume(tid1);
|
rt_thread_resume(tid1);
|
||||||
rt_kprintf("thread2: to resume thread1\n");
|
rt_kprintf("thread2: to resume thread1\n");
|
||||||
|
|
||||||
/* 延时10个OS Tick */
|
/* 延时10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
|
|
||||||
/* 线程2自动退出 */
|
/* 线程2自动退出 */
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_resume_init()
|
int thread_resume_init()
|
||||||
{
|
{
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("thread",
|
tid1 = rt_thread_create("thread",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
{
|
{
|
||||||
tid1->cleanup = thread_cleanup;
|
tid1->cleanup = thread_cleanup;
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("thread",
|
tid2 = rt_thread_create("thread",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
{
|
{
|
||||||
tid2->cleanup = thread_cleanup;
|
tid2->cleanup = thread_cleanup;
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_thread_resume()
|
int _tc_thread_resume()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
thread_resume_init();
|
thread_resume_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 25;
|
return 25;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_resume, a thread resume example);
|
FINSH_FUNCTION_EXPORT(_tc_thread_resume, a thread resume example);
|
||||||
|
@ -116,8 +116,8 @@ FINSH_FUNCTION_EXPORT(_tc_thread_resume, a thread resume example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_resume_init();
|
thread_resume_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,87 +10,87 @@ volatile static rt_uint32_t t1_count = 0;
|
||||||
volatile static rt_uint32_t t2_count = 0;
|
volatile static rt_uint32_t t2_count = 0;
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
t1_count ++;
|
t1_count ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
t2_count ++;
|
t2_count ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_err_t thread_same_priority_init()
|
rt_err_t thread_same_priority_init()
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
result = rt_thread_init(&thread1,
|
result = rt_thread_init(&thread1,
|
||||||
"t1",
|
"t1",
|
||||||
thread1_entry, RT_NULL,
|
thread1_entry, RT_NULL,
|
||||||
&thread1_stack[0], sizeof(thread1_stack),
|
&thread1_stack[0], sizeof(thread1_stack),
|
||||||
THREAD_PRIORITY, 10);
|
THREAD_PRIORITY, 10);
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
rt_thread_startup(&thread1);
|
rt_thread_startup(&thread1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
result = rt_thread_init(&thread2,
|
result = rt_thread_init(&thread2,
|
||||||
"t2",
|
"t2",
|
||||||
thread2_entry, RT_NULL,
|
thread2_entry, RT_NULL,
|
||||||
&thread2_stack[0], sizeof(thread2_stack),
|
&thread2_stack[0], sizeof(thread2_stack),
|
||||||
THREAD_PRIORITY, 5);
|
THREAD_PRIORITY, 5);
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
rt_thread_startup(&thread2);
|
rt_thread_startup(&thread2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* lock scheduler */
|
/* lock scheduler */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
if (thread1.stat != RT_THREAD_CLOSE)
|
if (thread1.stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_detach(&thread1);
|
rt_thread_detach(&thread1);
|
||||||
if (thread2.stat != RT_THREAD_CLOSE)
|
if (thread2.stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_detach(&thread2);
|
rt_thread_detach(&thread2);
|
||||||
|
|
||||||
/* unlock scheduler */
|
/* unlock scheduler */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
rt_kprintf("t1_count=%d t2_count=%d\n",t1_count,t2_count);
|
rt_kprintf("t1_count=%d t2_count=%d\n",t1_count,t2_count);
|
||||||
|
|
||||||
if (t1_count / t2_count != 2)
|
if (t1_count / t2_count != 2)
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
else
|
else
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_thread_same_priority()
|
int _tc_thread_same_priority()
|
||||||
{
|
{
|
||||||
t1_count = 0;
|
t1_count = 0;
|
||||||
t2_count = 0;
|
t2_count = 0;
|
||||||
|
|
||||||
/* set tc cleanup */
|
/* set tc cleanup */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
|
|
||||||
thread_same_priority_init();
|
thread_same_priority_init();
|
||||||
|
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_same_priority, a same priority thread test);
|
FINSH_FUNCTION_EXPORT(_tc_thread_same_priority, a same priority thread test);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_same_priority_init();
|
thread_same_priority_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,45 +8,45 @@ static struct rt_thread thread;
|
||||||
static char thread_stack[THREAD_STACK_SIZE];
|
static char thread_stack[THREAD_STACK_SIZE];
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_kprintf("thread staticly inited ok\n");
|
rt_kprintf("thread staticly inited ok\n");
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
rt_kprintf("thread exit\n");
|
rt_kprintf("thread exit\n");
|
||||||
|
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_err_t thread_static_init()
|
rt_err_t thread_static_init()
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
result = rt_thread_init(&thread,
|
result = rt_thread_init(&thread,
|
||||||
"test",
|
"test",
|
||||||
thread_entry, RT_NULL,
|
thread_entry, RT_NULL,
|
||||||
&thread_stack[0], sizeof(thread_stack),
|
&thread_stack[0], sizeof(thread_stack),
|
||||||
THREAD_PRIORITY, 10);
|
THREAD_PRIORITY, 10);
|
||||||
|
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
rt_thread_startup(&thread);
|
rt_thread_startup(&thread);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
int _tc_thread_static()
|
int _tc_thread_static()
|
||||||
{
|
{
|
||||||
thread_static_init();
|
thread_static_init();
|
||||||
|
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_static, a static thread test);
|
FINSH_FUNCTION_EXPORT(_tc_thread_static, a static thread test);
|
||||||
#else
|
#else
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_static_init();
|
thread_static_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -18,73 +18,73 @@ static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
|
||||||
/* 线程入口 */
|
/* 线程入口 */
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint32_t count = 0;
|
rt_uint32_t count = 0;
|
||||||
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
|
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 打印线程计数值输出 */
|
/* 打印线程计数值输出 */
|
||||||
rt_kprintf("thread%d count: %d\n", no, count ++);
|
rt_kprintf("thread%d count: %d\n", no, count ++);
|
||||||
|
|
||||||
/* 休眠10个OS Tick */
|
/* 休眠10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_static_simple_init()
|
int thread_static_simple_init()
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
/* 初始化线程1 */
|
/* 初始化线程1 */
|
||||||
result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */
|
result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */
|
||||||
thread_entry, (void*)1, /* 线程的入口是thread_entry,入口参数是1 */
|
thread_entry, (void*)1, /* 线程的入口是thread_entry,入口参数是1 */
|
||||||
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
|
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
|
||||||
THREAD_PRIORITY, 10);
|
THREAD_PRIORITY, 10);
|
||||||
if (result == RT_EOK) /* 如果返回正确,启动线程1 */
|
if (result == RT_EOK) /* 如果返回正确,启动线程1 */
|
||||||
rt_thread_startup(&thread1);
|
rt_thread_startup(&thread1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 初始化线程2 */
|
/* 初始化线程2 */
|
||||||
result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */
|
result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */
|
||||||
thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是2 */
|
thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是2 */
|
||||||
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
|
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
|
||||||
THREAD_PRIORITY + 1, 10);
|
THREAD_PRIORITY + 1, 10);
|
||||||
if (result == RT_EOK) /* 如果返回正确,启动线程2 */
|
if (result == RT_EOK) /* 如果返回正确,启动线程2 */
|
||||||
rt_thread_startup(&thread2);
|
rt_thread_startup(&thread2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 执行线程脱离 */
|
/* 执行线程脱离 */
|
||||||
if (thread1.stat != RT_THREAD_CLOSE)
|
if (thread1.stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_detach(&thread1);
|
rt_thread_detach(&thread1);
|
||||||
if (thread2.stat != RT_THREAD_CLOSE)
|
if (thread2.stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_detach(&thread2);
|
rt_thread_detach(&thread2);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_thread_static_simple()
|
int _tc_thread_static_simple()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
thread_static_simple_init();
|
thread_static_simple_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example);
|
FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example);
|
||||||
|
@ -92,8 +92,8 @@ FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_static_simple_init();
|
thread_static_simple_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,81 +12,81 @@ static rt_thread_t tid2 = RT_NULL;
|
||||||
/* 线程1入口 */
|
/* 线程1入口 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint32_t count = 0;
|
rt_uint32_t count = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 线程1采用低优先级运行,一直打印计数值 */
|
/* 线程1采用低优先级运行,一直打印计数值 */
|
||||||
rt_kprintf("thread count: %d\n", count ++);
|
rt_kprintf("thread count: %d\n", count ++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口 */
|
/* 线程2入口 */
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
/* 延时10个OS Tick */
|
/* 延时10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
|
|
||||||
/* 挂起线程1 */
|
/* 挂起线程1 */
|
||||||
rt_thread_suspend(tid1);
|
rt_thread_suspend(tid1);
|
||||||
|
|
||||||
/* 延时10个OS Tick */
|
/* 延时10个OS Tick */
|
||||||
rt_thread_delay(10);
|
rt_thread_delay(10);
|
||||||
|
|
||||||
/* 线程2自动退出 */
|
/* 线程2自动退出 */
|
||||||
tid2 = RT_NULL;
|
tid2 = RT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_suspend_init()
|
int thread_suspend_init()
|
||||||
{
|
{
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("thread",
|
tid1 = rt_thread_create("thread",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("thread",
|
tid2 = rt_thread_create("thread",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_thread_suspend()
|
int _tc_thread_suspend()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
thread_suspend_init();
|
thread_suspend_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_suspend, a thread suspend example);
|
FINSH_FUNCTION_EXPORT(_tc_thread_suspend, a thread suspend example);
|
||||||
|
@ -94,8 +94,8 @@ FINSH_FUNCTION_EXPORT(_tc_thread_suspend, a thread suspend example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_suspend_init();
|
thread_suspend_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,83 +10,83 @@ static rt_thread_t tid2 = RT_NULL;
|
||||||
/* 线程1入口 */
|
/* 线程1入口 */
|
||||||
static void thread1_entry(void* parameter)
|
static void thread1_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint32_t count = 0;
|
rt_uint32_t count = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 打印线程1的输出 */
|
/* 打印线程1的输出 */
|
||||||
rt_kprintf("thread1: count = %d\n", count ++);
|
rt_kprintf("thread1: count = %d\n", count ++);
|
||||||
|
|
||||||
/* 执行yield后应该切换到thread2执行 */
|
/* 执行yield后应该切换到thread2执行 */
|
||||||
rt_thread_yield();
|
rt_thread_yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程2入口 */
|
/* 线程2入口 */
|
||||||
static void thread2_entry(void* parameter)
|
static void thread2_entry(void* parameter)
|
||||||
{
|
{
|
||||||
rt_uint32_t count = 0;
|
rt_uint32_t count = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* 打印线程2的输出 */
|
/* 打印线程2的输出 */
|
||||||
rt_kprintf("thread2: count = %d\n", count ++);
|
rt_kprintf("thread2: count = %d\n", count ++);
|
||||||
|
|
||||||
/* 执行yield后应该切换到thread1执行 */
|
/* 执行yield后应该切换到thread1执行 */
|
||||||
rt_thread_yield();
|
rt_thread_yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_yield_init()
|
int thread_yield_init()
|
||||||
{
|
{
|
||||||
/* 创建线程1 */
|
/* 创建线程1 */
|
||||||
tid1 = rt_thread_create("thread",
|
tid1 = rt_thread_create("thread",
|
||||||
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid1 != RT_NULL)
|
if (tid1 != RT_NULL)
|
||||||
rt_thread_startup(tid1);
|
rt_thread_startup(tid1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建线程2 */
|
/* 创建线程2 */
|
||||||
tid2 = rt_thread_create("thread",
|
tid2 = rt_thread_create("thread",
|
||||||
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid2 != RT_NULL)
|
if (tid2 != RT_NULL)
|
||||||
rt_thread_startup(tid2);
|
rt_thread_startup(tid2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid1);
|
rt_thread_delete(tid1);
|
||||||
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
|
||||||
rt_thread_delete(tid2);
|
rt_thread_delete(tid2);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_thread_yield()
|
int _tc_thread_yield()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
thread_yield_init();
|
thread_yield_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 30;
|
return 30;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_thread_yield, a thread yield example);
|
FINSH_FUNCTION_EXPORT(_tc_thread_yield, a thread yield example);
|
||||||
|
@ -94,8 +94,8 @@ FINSH_FUNCTION_EXPORT(_tc_thread_yield, a thread yield example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
thread_yield_init();
|
thread_yield_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,63 +13,63 @@ static rt_uint8_t count;
|
||||||
/* 定时器超时函数 */
|
/* 定时器超时函数 */
|
||||||
static void timeout1(void* parameter)
|
static void timeout1(void* parameter)
|
||||||
{
|
{
|
||||||
rt_tick_t timeout = 50;
|
rt_tick_t timeout = 50;
|
||||||
|
|
||||||
rt_kprintf("periodic timer is timeout\n");
|
rt_kprintf("periodic timer is timeout\n");
|
||||||
|
|
||||||
count ++;
|
count ++;
|
||||||
/* 停止定时器自身 */
|
/* 停止定时器自身 */
|
||||||
if (count >= 8)
|
if (count >= 8)
|
||||||
{
|
{
|
||||||
/* 控制定时器然后更改超时时间长度 */
|
/* 控制定时器然后更改超时时间长度 */
|
||||||
rt_timer_control(timer1, RT_TIMER_CTRL_SET_TIME, (void *)&timeout);
|
rt_timer_control(timer1, RT_TIMER_CTRL_SET_TIME, (void *)&timeout);
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_control_init()
|
void timer_control_init()
|
||||||
{
|
{
|
||||||
/* 创建定时器1 */
|
/* 创建定时器1 */
|
||||||
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
|
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
|
||||||
timeout1, /* 超时时回调的处理函数 */
|
timeout1, /* 超时时回调的处理函数 */
|
||||||
RT_NULL, /* 超时函数的入口参数 */
|
RT_NULL, /* 超时函数的入口参数 */
|
||||||
10, /* 定时长度,以OS Tick为单位,即10个OS Tick */
|
10, /* 定时长度,以OS Tick为单位,即10个OS Tick */
|
||||||
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
||||||
/* 启动定时器 */
|
/* 启动定时器 */
|
||||||
if (timer1 != RT_NULL)
|
if (timer1 != RT_NULL)
|
||||||
rt_timer_start(timer1);
|
rt_timer_start(timer1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除定时器对象 */
|
/* 删除定时器对象 */
|
||||||
rt_timer_delete(timer1);
|
rt_timer_delete(timer1);
|
||||||
timer1 = RT_NULL;
|
timer1 = RT_NULL;
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_timer_control()
|
int _tc_timer_control()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
|
|
||||||
/* 执行定时器例程 */
|
/* 执行定时器例程 */
|
||||||
count = 0;
|
count = 0;
|
||||||
timer_control_init();
|
timer_control_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_timer_control, a timer control example);
|
FINSH_FUNCTION_EXPORT(_tc_timer_control, a timer control example);
|
||||||
|
@ -77,8 +77,8 @@ FINSH_FUNCTION_EXPORT(_tc_timer_control, a timer control example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
timer_control_init();
|
timer_control_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,70 +13,70 @@ static rt_timer_t timer2;
|
||||||
/* 定时器1超时函数 */
|
/* 定时器1超时函数 */
|
||||||
static void timeout1(void* parameter)
|
static void timeout1(void* parameter)
|
||||||
{
|
{
|
||||||
rt_kprintf("periodic timer is timeout\n");
|
rt_kprintf("periodic timer is timeout\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 定时器2超时函数 */
|
/* 定时器2超时函数 */
|
||||||
static void timeout2(void* parameter)
|
static void timeout2(void* parameter)
|
||||||
{
|
{
|
||||||
rt_kprintf("one shot timer is timeout\n");
|
rt_kprintf("one shot timer is timeout\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_create_init()
|
void timer_create_init()
|
||||||
{
|
{
|
||||||
/* 创建定时器1 */
|
/* 创建定时器1 */
|
||||||
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
|
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
|
||||||
timeout1, /* 超时时回调的处理函数 */
|
timeout1, /* 超时时回调的处理函数 */
|
||||||
RT_NULL, /* 超时函数的入口参数 */
|
RT_NULL, /* 超时函数的入口参数 */
|
||||||
10, /* 定时长度,以OS Tick为单位,即10个OS Tick */
|
10, /* 定时长度,以OS Tick为单位,即10个OS Tick */
|
||||||
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
||||||
/* 启动定时器 */
|
/* 启动定时器 */
|
||||||
if (timer1 != RT_NULL)
|
if (timer1 != RT_NULL)
|
||||||
rt_timer_start(timer1);
|
rt_timer_start(timer1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
/* 创建定时器2 */
|
/* 创建定时器2 */
|
||||||
timer2 = rt_timer_create("timer2", /* 定时器名字是 timer2 */
|
timer2 = rt_timer_create("timer2", /* 定时器名字是 timer2 */
|
||||||
timeout2, /* 超时时回调的处理函数 */
|
timeout2, /* 超时时回调的处理函数 */
|
||||||
RT_NULL, /* 超时函数的入口参数 */
|
RT_NULL, /* 超时函数的入口参数 */
|
||||||
30, /* 定时长度为30个OS Tick */
|
30, /* 定时长度为30个OS Tick */
|
||||||
RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */
|
RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */
|
||||||
|
|
||||||
/* 启动定时器 */
|
/* 启动定时器 */
|
||||||
if (timer2 != RT_NULL)
|
if (timer2 != RT_NULL)
|
||||||
rt_timer_start(timer2);
|
rt_timer_start(timer2);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除定时器对象 */
|
/* 删除定时器对象 */
|
||||||
rt_timer_delete(timer1);
|
rt_timer_delete(timer1);
|
||||||
rt_timer_delete(timer2);
|
rt_timer_delete(timer2);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_timer_create()
|
int _tc_timer_create()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
|
|
||||||
/* 执行定时器例程 */
|
/* 执行定时器例程 */
|
||||||
timer_create_init();
|
timer_create_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_timer_create, a dynamic timer example);
|
FINSH_FUNCTION_EXPORT(_tc_timer_create, a dynamic timer example);
|
||||||
|
@ -84,8 +84,8 @@ FINSH_FUNCTION_EXPORT(_tc_timer_create, a dynamic timer example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
timer_create_init();
|
timer_create_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,61 +13,61 @@ static struct rt_timer timer2;
|
||||||
/* 定时器1超时函数 */
|
/* 定时器1超时函数 */
|
||||||
static void timeout1(void* parameter)
|
static void timeout1(void* parameter)
|
||||||
{
|
{
|
||||||
rt_kprintf("periodic timer is timeout\n");
|
rt_kprintf("periodic timer is timeout\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 定时器2超时函数 */
|
/* 定时器2超时函数 */
|
||||||
static void timeout2(void* parameter)
|
static void timeout2(void* parameter)
|
||||||
{
|
{
|
||||||
rt_kprintf("one shot timer is timeout\n");
|
rt_kprintf("one shot timer is timeout\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_static_init()
|
void timer_static_init()
|
||||||
{
|
{
|
||||||
/* 初始化定时器 */
|
/* 初始化定时器 */
|
||||||
rt_timer_init(&timer1, "timer1", /* 定时器名字是 timer1 */
|
rt_timer_init(&timer1, "timer1", /* 定时器名字是 timer1 */
|
||||||
timeout1, /* 超时时回调的处理函数 */
|
timeout1, /* 超时时回调的处理函数 */
|
||||||
RT_NULL, /* 超时函数的入口参数 */
|
RT_NULL, /* 超时函数的入口参数 */
|
||||||
10, /* 定时长度,以OS Tick为单位,即10个OS Tick */
|
10, /* 定时长度,以OS Tick为单位,即10个OS Tick */
|
||||||
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
||||||
rt_timer_init(&timer2, "timer2", /* 定时器名字是 timer2 */
|
rt_timer_init(&timer2, "timer2", /* 定时器名字是 timer2 */
|
||||||
timeout2, /* 超时时回调的处理函数 */
|
timeout2, /* 超时时回调的处理函数 */
|
||||||
RT_NULL, /* 超时函数的入口参数 */
|
RT_NULL, /* 超时函数的入口参数 */
|
||||||
30, /* 定时长度为30个OS Tick */
|
30, /* 定时长度为30个OS Tick */
|
||||||
RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */
|
RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */
|
||||||
|
|
||||||
/* 启动定时器 */
|
/* 启动定时器 */
|
||||||
rt_timer_start(&timer1);
|
rt_timer_start(&timer1);
|
||||||
rt_timer_start(&timer2);
|
rt_timer_start(&timer2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 执行定时器脱离 */
|
/* 执行定时器脱离 */
|
||||||
rt_timer_detach(&timer1);
|
rt_timer_detach(&timer1);
|
||||||
rt_timer_detach(&timer2);
|
rt_timer_detach(&timer2);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_timer_static()
|
int _tc_timer_static()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
|
|
||||||
/* 执行定时器例程 */
|
/* 执行定时器例程 */
|
||||||
timer_static_init();
|
timer_static_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_timer_static, a static timer example);
|
FINSH_FUNCTION_EXPORT(_tc_timer_static, a static timer example);
|
||||||
|
@ -75,8 +75,8 @@ FINSH_FUNCTION_EXPORT(_tc_timer_static, a static timer example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
timer_static_init();
|
timer_static_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,61 +13,61 @@ static rt_uint8_t count;
|
||||||
/* 定时器超时函数 */
|
/* 定时器超时函数 */
|
||||||
static void timeout1(void* parameter)
|
static void timeout1(void* parameter)
|
||||||
{
|
{
|
||||||
rt_kprintf("periodic timer is timeout\n");
|
rt_kprintf("periodic timer is timeout\n");
|
||||||
|
|
||||||
count ++;
|
count ++;
|
||||||
/* 停止定时器自身 */
|
/* 停止定时器自身 */
|
||||||
if (count >= 8)
|
if (count >= 8)
|
||||||
{
|
{
|
||||||
/* 停止定时器 */
|
/* 停止定时器 */
|
||||||
rt_timer_stop(timer1);
|
rt_timer_stop(timer1);
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_stop_self_init()
|
void timer_stop_self_init()
|
||||||
{
|
{
|
||||||
/* 创建定时器1 */
|
/* 创建定时器1 */
|
||||||
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
|
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
|
||||||
timeout1, /* 超时时回调的处理函数 */
|
timeout1, /* 超时时回调的处理函数 */
|
||||||
RT_NULL, /* 超时函数的入口参数 */
|
RT_NULL, /* 超时函数的入口参数 */
|
||||||
10, /* 定时长度,以OS Tick为单位,即10个OS Tick */
|
10, /* 定时长度,以OS Tick为单位,即10个OS Tick */
|
||||||
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
||||||
/* 启动定时器 */
|
/* 启动定时器 */
|
||||||
if (timer1 != RT_NULL)
|
if (timer1 != RT_NULL)
|
||||||
rt_timer_start(timer1);
|
rt_timer_start(timer1);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除定时器对象 */
|
/* 删除定时器对象 */
|
||||||
rt_timer_delete(timer1);
|
rt_timer_delete(timer1);
|
||||||
timer1 = RT_NULL;
|
timer1 = RT_NULL;
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_timer_stop_self()
|
int _tc_timer_stop_self()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
|
|
||||||
/* 执行定时器例程 */
|
/* 执行定时器例程 */
|
||||||
count = 0;
|
count = 0;
|
||||||
timer_stop_self_init();
|
timer_stop_self_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_timer_stop_self, a dynamic timer example);
|
FINSH_FUNCTION_EXPORT(_tc_timer_stop_self, a dynamic timer example);
|
||||||
|
@ -75,8 +75,8 @@ FINSH_FUNCTION_EXPORT(_tc_timer_stop_self, a dynamic timer example);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
timer_stop_self_init();
|
timer_stop_self_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,94 +20,94 @@ static struct rt_timer timer;
|
||||||
static rt_uint16_t no = 0;
|
static rt_uint16_t no = 0;
|
||||||
static void timer_timeout(void* parameter)
|
static void timer_timeout(void* parameter)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
rt_uint32_t length;
|
rt_uint32_t length;
|
||||||
|
|
||||||
length = rt_snprintf(buf, sizeof(buf), "message %d", no++);
|
length = rt_snprintf(buf, sizeof(buf), "message %d", no++);
|
||||||
rt_mq_send(&mq, &buf[0], length);
|
rt_mq_send(&mq, &buf[0], length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 线程入口函数 */
|
/* 线程入口函数 */
|
||||||
static void thread_entry(void* parameter)
|
static void thread_entry(void* parameter)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
/* 初始化定时器 */
|
/* 初始化定时器 */
|
||||||
rt_timer_init(&timer, "timer", /* 定时器名字是 timer1 */
|
rt_timer_init(&timer, "timer", /* 定时器名字是 timer1 */
|
||||||
timer_timeout, /* 超时时回调的处理函数 */
|
timer_timeout, /* 超时时回调的处理函数 */
|
||||||
RT_NULL, /* 超时函数的入口参数 */
|
RT_NULL, /* 超时函数的入口参数 */
|
||||||
1, /* 定时长度,以OS Tick为单位,即1个OS Tick */
|
1, /* 定时长度,以OS Tick为单位,即1个OS Tick */
|
||||||
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rt_memset(&buf[0], 0, sizeof(buf));
|
rt_memset(&buf[0], 0, sizeof(buf));
|
||||||
|
|
||||||
/* 从消息队列中接收消息 */
|
/* 从消息队列中接收消息 */
|
||||||
result = rt_mq_recv(&mq, &buf[0], sizeof(buf), 1);
|
result = rt_mq_recv(&mq, &buf[0], sizeof(buf), 1);
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
{
|
{
|
||||||
rt_kprintf("recv msg: %s\n", buf);
|
rt_kprintf("recv msg: %s\n", buf);
|
||||||
}
|
}
|
||||||
else if (result == -RT_ETIMEOUT)
|
else if (result == -RT_ETIMEOUT)
|
||||||
{
|
{
|
||||||
rt_kprintf("recv msg timeout\n");
|
rt_kprintf("recv msg timeout\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int timer_timeout_init()
|
int timer_timeout_init()
|
||||||
{
|
{
|
||||||
/* 初始化消息队列 */
|
/* 初始化消息队列 */
|
||||||
rt_mq_init(&mq, "mqt",
|
rt_mq_init(&mq, "mqt",
|
||||||
&msg_pool[0], /* 内存池指向msg_pool */
|
&msg_pool[0], /* 内存池指向msg_pool */
|
||||||
128 - sizeof(void*), /* 每个消息的大小是 128 - void* */
|
128 - sizeof(void*), /* 每个消息的大小是 128 - void* */
|
||||||
sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */
|
sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */
|
||||||
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
|
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
|
||||||
|
|
||||||
/* 创建线程 */
|
/* 创建线程 */
|
||||||
tid = rt_thread_create("t",
|
tid = rt_thread_create("t",
|
||||||
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
|
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
|
||||||
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
||||||
if (tid != RT_NULL)
|
if (tid != RT_NULL)
|
||||||
rt_thread_startup(tid);
|
rt_thread_startup(tid);
|
||||||
else
|
else
|
||||||
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
tc_stat(TC_STAT_END | TC_STAT_FAILED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_TC
|
#ifdef RT_USING_TC
|
||||||
static void _tc_cleanup()
|
static void _tc_cleanup()
|
||||||
{
|
{
|
||||||
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* 删除线程 */
|
/* 删除线程 */
|
||||||
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_mq_detach(&mq);
|
rt_mq_detach(&mq);
|
||||||
/* 执行定时器脱离 */
|
/* 执行定时器脱离 */
|
||||||
rt_timer_detach(&timer);
|
rt_timer_detach(&timer);
|
||||||
|
|
||||||
/* 调度器解锁 */
|
/* 调度器解锁 */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
/* 设置TestCase状态 */
|
/* 设置TestCase状态 */
|
||||||
tc_done(TC_STAT_PASSED);
|
tc_done(TC_STAT_PASSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tc_timer_timeout()
|
int _tc_timer_timeout()
|
||||||
{
|
{
|
||||||
/* 设置TestCase清理回调函数 */
|
/* 设置TestCase清理回调函数 */
|
||||||
tc_cleanup(_tc_cleanup);
|
tc_cleanup(_tc_cleanup);
|
||||||
timer_timeout_init();
|
timer_timeout_init();
|
||||||
|
|
||||||
/* 返回TestCase运行的最长时间 */
|
/* 返回TestCase运行的最长时间 */
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
/* 输出函数命令到finsh shell中 */
|
/* 输出函数命令到finsh shell中 */
|
||||||
FINSH_FUNCTION_EXPORT(_tc_timer_timeout, a thread timer testcase);
|
FINSH_FUNCTION_EXPORT(_tc_timer_timeout, a thread timer testcase);
|
||||||
|
@ -115,8 +115,8 @@ FINSH_FUNCTION_EXPORT(_tc_timer_timeout, a thread timer testcase);
|
||||||
/* 用户应用入口 */
|
/* 用户应用入口 */
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
timer_timeout_init();
|
timer_timeout_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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 @@
|
||||||
* 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))
|
||||||
*/
|
*/
|
||||||
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 @@
|
||||||
* 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue