commit
8932ffdb96
|
@ -1,964 +0,0 @@
|
|||
/*
|
||||
* File : dfs_elm.c
|
||||
* This file is part of Device File System in RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008-2011, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rt-thread.org/license/LICENSE.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-02-22 QiuYi The first version.
|
||||
* 2011-10-08 Bernard fixed the block size in statfs.
|
||||
* 2011-11-23 Bernard fixed the rename issue.
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "ffconf.h"
|
||||
#include "ff.h"
|
||||
|
||||
/* ELM FatFs provide a DIR struct */
|
||||
#define HAVE_DIR_STRUCTURE
|
||||
|
||||
#include <dfs_fs.h>
|
||||
#include <dfs.h>
|
||||
|
||||
#ifdef DFS_ELMFAT_INTERFACE_EFM
|
||||
#include "diskio.h"
|
||||
|
||||
/* Disk status */
|
||||
static volatile DSTATUS diskStat[_VOLUMES];
|
||||
#endif
|
||||
static rt_device_t disk[_VOLUMES] = {0};
|
||||
|
||||
static int elm_result_to_dfs(FRESULT result)
|
||||
{
|
||||
int status = DFS_STATUS_OK;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case FR_OK:
|
||||
break;
|
||||
|
||||
case FR_NO_FILE:
|
||||
case FR_NO_PATH:
|
||||
case FR_NO_FILESYSTEM:
|
||||
status = -DFS_STATUS_ENOENT;
|
||||
break;
|
||||
|
||||
case FR_INVALID_NAME:
|
||||
status = -DFS_STATUS_EINVAL;
|
||||
break;
|
||||
|
||||
case FR_EXIST:
|
||||
case FR_INVALID_OBJECT:
|
||||
status = -DFS_STATUS_EEXIST;
|
||||
break;
|
||||
|
||||
case FR_DISK_ERR:
|
||||
case FR_NOT_READY:
|
||||
case FR_INT_ERR:
|
||||
status = -DFS_STATUS_EIO;
|
||||
break;
|
||||
|
||||
case FR_WRITE_PROTECTED:
|
||||
case FR_DENIED:
|
||||
status = -DFS_STATUS_EROFS;
|
||||
break;
|
||||
|
||||
case FR_MKFS_ABORTED:
|
||||
status = -DFS_STATUS_EINVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
||||
{
|
||||
FATFS *fat;
|
||||
FRESULT result;
|
||||
rt_uint32_t index;
|
||||
|
||||
/* handle RT-Thread device routine */
|
||||
for (index = 0; index < _VOLUMES; index ++)
|
||||
{
|
||||
if (disk[index] == RT_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == _VOLUMES)
|
||||
return -DFS_STATUS_ENOSPC;
|
||||
|
||||
/* get device */
|
||||
disk[index] = fs->dev_id;
|
||||
|
||||
fat = (FATFS *)rt_malloc(sizeof(FATFS));
|
||||
if (fat == RT_NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* mount fatfs, always 0 logic driver */
|
||||
result = f_mount(index, fat);
|
||||
if (result == FR_OK)
|
||||
fs->data = fat;
|
||||
else
|
||||
{
|
||||
rt_free(fat);
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dfs_elm_unmount(struct dfs_filesystem *fs)
|
||||
{
|
||||
FATFS *fat;
|
||||
FRESULT result;
|
||||
rt_uint32_t index;
|
||||
|
||||
fat = (FATFS *)fs->data;
|
||||
|
||||
RT_ASSERT(fat != RT_NULL);
|
||||
|
||||
/* find the device index and then umount it */
|
||||
for (index = 0; index < _VOLUMES; index ++)
|
||||
{
|
||||
if (disk[index] == fs->dev_id)
|
||||
{
|
||||
result = f_mount(index, RT_NULL);
|
||||
|
||||
if (result == FR_OK)
|
||||
{
|
||||
fs->data = RT_NULL;
|
||||
disk[index] = RT_NULL;
|
||||
rt_free(fat);
|
||||
return DFS_STATUS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -DFS_STATUS_ENOENT;
|
||||
}
|
||||
|
||||
int dfs_elm_mkfs(const char *device_name)
|
||||
{
|
||||
BYTE drv;
|
||||
rt_device_t dev;
|
||||
FRESULT result;
|
||||
|
||||
/* find device name */
|
||||
for (drv = 0; drv < _VOLUMES; drv ++)
|
||||
{
|
||||
dev = disk[drv];
|
||||
if (rt_strncmp(dev->parent.name, device_name, RT_NAME_MAX) == 0)
|
||||
{
|
||||
/* 1: no partition table */
|
||||
/* 0: auto selection of cluster size */
|
||||
result = f_mkfs(drv, 1, 0);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
rt_kprintf("format error\n");
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
return DFS_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* can't find device driver */
|
||||
rt_kprintf("can not find device driver: %s\n", device_name);
|
||||
return -DFS_STATUS_EIO;
|
||||
}
|
||||
|
||||
int dfs_elm_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
||||
{
|
||||
FATFS *f;
|
||||
FRESULT res;
|
||||
char driver[4];
|
||||
DWORD fre_clust, fre_sect, tot_sect;
|
||||
|
||||
RT_ASSERT(fs != RT_NULL);
|
||||
RT_ASSERT(buf != RT_NULL);
|
||||
|
||||
f = (FATFS *)fs->data;
|
||||
|
||||
rt_snprintf(driver, sizeof(driver), "%d:", f->drv);
|
||||
res = f_getfree(driver, &fre_clust, &f);
|
||||
if (res)
|
||||
return elm_result_to_dfs(res);
|
||||
|
||||
/* Get total sectors and free sectors */
|
||||
tot_sect = (f->n_fatent - 2) * f->csize;
|
||||
fre_sect = fre_clust * f->csize;
|
||||
|
||||
buf->f_bfree = fre_sect;
|
||||
buf->f_blocks = tot_sect;
|
||||
#if _MAX_SS != 512
|
||||
buf->f_bsize = f->ssize;
|
||||
#else
|
||||
buf->f_bsize = 512;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dfs_elm_open(struct dfs_fd *file)
|
||||
{
|
||||
FIL *fd;
|
||||
BYTE mode;
|
||||
FRESULT result;
|
||||
char *drivers_fn;
|
||||
|
||||
#if (_VOLUMES > 1)
|
||||
int vol;
|
||||
extern int elm_get_vol(FATFS *fat);
|
||||
|
||||
/* add path for ELM FatFS driver support */
|
||||
vol = elm_get_vol((FATFS *)file->fs->data);
|
||||
if (vol < 0)
|
||||
return -DFS_STATUS_ENOENT;
|
||||
drivers_fn = rt_malloc(256);
|
||||
if (drivers_fn == RT_NULL)
|
||||
return -DFS_STATUS_ENOMEM;
|
||||
|
||||
rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->path);
|
||||
#else
|
||||
drivers_fn = file->path;
|
||||
#endif
|
||||
|
||||
if (file->flags & DFS_O_DIRECTORY)
|
||||
{
|
||||
DIR *dir;
|
||||
|
||||
if (file->flags & DFS_O_CREAT)
|
||||
{
|
||||
result = f_mkdir(drivers_fn);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
#if _VOLUMES > 1
|
||||
rt_free(drivers_fn);
|
||||
#endif
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
}
|
||||
|
||||
/* open directory */
|
||||
dir = (DIR *)rt_malloc(sizeof(DIR));
|
||||
if (dir == RT_NULL)
|
||||
{
|
||||
#if _VOLUMES > 1
|
||||
rt_free(drivers_fn);
|
||||
#endif
|
||||
return -DFS_STATUS_ENOMEM;
|
||||
}
|
||||
|
||||
result = f_opendir(dir, drivers_fn);
|
||||
#if _VOLUMES > 1
|
||||
rt_free(drivers_fn);
|
||||
#endif
|
||||
if (result != FR_OK)
|
||||
{
|
||||
rt_free(dir);
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
file->data = dir;
|
||||
return DFS_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = FA_READ;
|
||||
|
||||
if (file->flags & DFS_O_WRONLY)
|
||||
mode |= FA_WRITE;
|
||||
if ((file->flags & DFS_O_ACCMODE) & DFS_O_RDWR)
|
||||
mode |= FA_WRITE;
|
||||
/* Opens the file, if it is existing. If not, a new file is created. */
|
||||
if (file->flags & DFS_O_CREAT)
|
||||
mode |= FA_OPEN_ALWAYS;
|
||||
/* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
||||
if (file->flags & DFS_O_TRUNC)
|
||||
mode |= FA_CREATE_ALWAYS;
|
||||
/* Creates a new file. The function fails if the file is already existing. */
|
||||
if (file->flags & DFS_O_EXCL)
|
||||
mode |= FA_CREATE_NEW;
|
||||
|
||||
/* allocate a fd */
|
||||
fd = (FIL *)rt_malloc(sizeof(FIL));
|
||||
if (fd == RT_NULL)
|
||||
{
|
||||
return -DFS_STATUS_ENOMEM;
|
||||
}
|
||||
|
||||
result = f_open(fd, drivers_fn, mode);
|
||||
#if _VOLUMES > 1
|
||||
rt_free(drivers_fn);
|
||||
#endif
|
||||
if (result == FR_OK)
|
||||
{
|
||||
file->pos = fd->fptr;
|
||||
file->size = fd->fsize;
|
||||
file->data = fd;
|
||||
|
||||
if (file->flags & DFS_O_APPEND)
|
||||
{
|
||||
file->pos = f_lseek(fd, fd->fsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* open failed, return */
|
||||
rt_free(fd);
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
}
|
||||
|
||||
return DFS_STATUS_OK;
|
||||
}
|
||||
|
||||
int dfs_elm_close(struct dfs_fd *file)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
result = FR_OK;
|
||||
if (file->type == FT_DIRECTORY)
|
||||
{
|
||||
DIR *dir;
|
||||
|
||||
dir = (DIR *)(file->data);
|
||||
RT_ASSERT(dir != RT_NULL);
|
||||
|
||||
/* release memory */
|
||||
rt_free(dir);
|
||||
}
|
||||
else if (file->type == FT_REGULAR)
|
||||
{
|
||||
FIL *fd;
|
||||
fd = (FIL *)(file->data);
|
||||
RT_ASSERT(fd != RT_NULL);
|
||||
|
||||
result = f_close(fd);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
/* release memory */
|
||||
rt_free(fd);
|
||||
}
|
||||
}
|
||||
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args)
|
||||
{
|
||||
return -DFS_STATUS_ENOSYS;
|
||||
}
|
||||
|
||||
int dfs_elm_read(struct dfs_fd *file, void *buf, rt_size_t len)
|
||||
{
|
||||
FIL *fd;
|
||||
FRESULT result;
|
||||
UINT byte_read;
|
||||
|
||||
if (file->type == FT_DIRECTORY)
|
||||
{
|
||||
return -DFS_STATUS_EISDIR;
|
||||
}
|
||||
|
||||
fd = (FIL *)(file->data);
|
||||
RT_ASSERT(fd != RT_NULL);
|
||||
|
||||
result = f_read(fd, buf, len, &byte_read);
|
||||
/* update position */
|
||||
file->pos = fd->fptr;
|
||||
if (result == FR_OK)
|
||||
return byte_read;
|
||||
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
int dfs_elm_write(struct dfs_fd *file, const void *buf, rt_size_t len)
|
||||
{
|
||||
FIL *fd;
|
||||
FRESULT result;
|
||||
UINT byte_write;
|
||||
|
||||
if (file->type == FT_DIRECTORY)
|
||||
{
|
||||
return -DFS_STATUS_EISDIR;
|
||||
}
|
||||
|
||||
fd = (FIL *)(file->data);
|
||||
RT_ASSERT(fd != RT_NULL);
|
||||
|
||||
result = f_write(fd, buf, len, &byte_write);
|
||||
/* update position and file size */
|
||||
file->pos = fd->fptr;
|
||||
file->size = fd->fsize;
|
||||
if (result == FR_OK)
|
||||
return byte_write;
|
||||
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
int dfs_elm_flush(struct dfs_fd *file)
|
||||
{
|
||||
FIL *fd;
|
||||
FRESULT result;
|
||||
|
||||
fd = (FIL *)(file->data);
|
||||
RT_ASSERT(fd != RT_NULL);
|
||||
|
||||
result = f_sync(fd);
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
int dfs_elm_lseek(struct dfs_fd *file, rt_off_t offset)
|
||||
{
|
||||
FRESULT result = FR_OK;
|
||||
if (file->type == FT_REGULAR)
|
||||
{
|
||||
FIL *fd;
|
||||
|
||||
/* regular file type */
|
||||
fd = (FIL *)(file->data);
|
||||
RT_ASSERT(fd != RT_NULL);
|
||||
|
||||
result = f_lseek(fd, offset);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
/* return current position */
|
||||
return fd->fptr;
|
||||
}
|
||||
}
|
||||
else if (file->type == FT_DIRECTORY)
|
||||
{
|
||||
/* which is a directory */
|
||||
DIR *dir;
|
||||
|
||||
dir = (DIR *)(file->data);
|
||||
RT_ASSERT(dir != RT_NULL);
|
||||
|
||||
result = f_seekdir(dir, offset / sizeof(struct dirent));
|
||||
if (result == FR_OK)
|
||||
{
|
||||
/* update file position */
|
||||
file->pos = offset;
|
||||
return file->pos;
|
||||
}
|
||||
}
|
||||
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count)
|
||||
{
|
||||
DIR *dir;
|
||||
FILINFO fno;
|
||||
FRESULT result;
|
||||
rt_uint32_t index;
|
||||
struct dirent *d;
|
||||
|
||||
dir = (DIR *)(file->data);
|
||||
RT_ASSERT(dir != RT_NULL);
|
||||
|
||||
/* make integer count */
|
||||
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
||||
if (count == 0)
|
||||
return -DFS_STATUS_EINVAL;
|
||||
|
||||
#if _USE_LFN
|
||||
/* allocate long file name */
|
||||
fno.lfname = rt_malloc(256);
|
||||
fno.lfsize = 256;
|
||||
#endif
|
||||
|
||||
index = 0;
|
||||
while (1)
|
||||
{
|
||||
char *fn;
|
||||
|
||||
d = dirp + index;
|
||||
|
||||
result = f_readdir(dir, &fno);
|
||||
if (result != FR_OK || fno.fname[0] == 0)
|
||||
break;
|
||||
|
||||
#if _USE_LFN
|
||||
fn = *fno.lfname? fno.lfname : fno.fname;
|
||||
#else
|
||||
fn = fno.fname;
|
||||
#endif
|
||||
|
||||
d->d_type = DFS_DT_UNKNOWN;
|
||||
if (fno.fattrib & AM_DIR)
|
||||
d->d_type = DFS_DT_DIR;
|
||||
else
|
||||
d->d_type = DFS_DT_REG;
|
||||
|
||||
d->d_namlen = rt_strlen(fn);
|
||||
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||
rt_strncpy(d->d_name, fn, rt_strlen(fn) + 1);
|
||||
|
||||
index ++;
|
||||
if (index * sizeof(struct dirent) >= count)
|
||||
break;
|
||||
}
|
||||
|
||||
#if _USE_LFN
|
||||
rt_free(fno.lfname);
|
||||
#endif
|
||||
|
||||
if (index == 0)
|
||||
return elm_result_to_dfs(result);
|
||||
|
||||
file->pos += index * sizeof(struct dirent);
|
||||
|
||||
return index * sizeof(struct dirent);
|
||||
}
|
||||
|
||||
int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
#if _VOLUMES > 1
|
||||
int vol;
|
||||
char *drivers_fn;
|
||||
extern int elm_get_vol(FATFS *fat);
|
||||
|
||||
/* add path for ELM FatFS driver support */
|
||||
vol = elm_get_vol((FATFS *)fs->data);
|
||||
if (vol < 0)
|
||||
return -DFS_STATUS_ENOENT;
|
||||
drivers_fn = rt_malloc(256);
|
||||
if (drivers_fn == RT_NULL)
|
||||
return -DFS_STATUS_ENOMEM;
|
||||
|
||||
rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
|
||||
#else
|
||||
const char *drivers_fn;
|
||||
drivers_fn = path;
|
||||
#endif
|
||||
|
||||
result = f_unlink(drivers_fn);
|
||||
#if _VOLUMES > 1
|
||||
rt_free(drivers_fn);
|
||||
#endif
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *newpath)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
#if _VOLUMES > 1
|
||||
char *drivers_oldfn;
|
||||
const char *drivers_newfn;
|
||||
int vol;
|
||||
extern int elm_get_vol(FATFS *fat);
|
||||
|
||||
/* add path for ELM FatFS driver support */
|
||||
vol = elm_get_vol((FATFS *)fs->data);
|
||||
if (vol < 0)
|
||||
return -DFS_STATUS_ENOENT;
|
||||
|
||||
drivers_oldfn = rt_malloc(256);
|
||||
if (drivers_oldfn == RT_NULL)
|
||||
return -DFS_STATUS_ENOMEM;
|
||||
drivers_newfn = newpath;
|
||||
|
||||
rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath);
|
||||
#else
|
||||
const char *drivers_oldfn, *drivers_newfn;
|
||||
|
||||
drivers_oldfn = oldpath;
|
||||
drivers_newfn = newpath;
|
||||
#endif
|
||||
|
||||
result = f_rename(drivers_oldfn, drivers_newfn);
|
||||
#if _VOLUMES > 1
|
||||
rt_free(drivers_oldfn);
|
||||
#endif
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
||||
{
|
||||
FILINFO file_info;
|
||||
FRESULT result;
|
||||
|
||||
|
||||
#if _VOLUMES > 1
|
||||
int vol;
|
||||
char *drivers_fn;
|
||||
extern int elm_get_vol(FATFS *fat);
|
||||
|
||||
/* add path for ELM FatFS driver support */
|
||||
vol = elm_get_vol((FATFS *)fs->data);
|
||||
if (vol < 0)
|
||||
return -DFS_STATUS_ENOENT;
|
||||
drivers_fn = rt_malloc(256);
|
||||
if (drivers_fn == RT_NULL)
|
||||
return -DFS_STATUS_ENOMEM;
|
||||
|
||||
rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
|
||||
#else
|
||||
const char *drivers_fn;
|
||||
drivers_fn = path;
|
||||
#endif
|
||||
|
||||
#if _USE_LFN
|
||||
/* allocate long file name */
|
||||
file_info.lfname = rt_malloc(256);
|
||||
file_info.lfsize = 256;
|
||||
#endif
|
||||
|
||||
result = f_stat(drivers_fn, &file_info);
|
||||
#if _VOLUMES > 1
|
||||
rt_free(drivers_fn);
|
||||
#endif
|
||||
if (result == FR_OK)
|
||||
{
|
||||
/* convert to dfs stat structure */
|
||||
st->st_dev = 0;
|
||||
|
||||
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
||||
if (file_info.fattrib & AM_DIR)
|
||||
{
|
||||
st->st_mode &= ~DFS_S_IFREG;
|
||||
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
||||
}
|
||||
if (file_info.fattrib & AM_RDO)
|
||||
st->st_mode &= ~(DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH);
|
||||
|
||||
st->st_size = file_info.fsize;
|
||||
st->st_mtime = file_info.ftime;
|
||||
}
|
||||
|
||||
#if _USE_LFN
|
||||
rt_free(file_info.lfname);
|
||||
#endif
|
||||
|
||||
return elm_result_to_dfs(result);
|
||||
}
|
||||
|
||||
static const struct dfs_filesystem_operation dfs_elm =
|
||||
{
|
||||
"elm",
|
||||
dfs_elm_mount,
|
||||
dfs_elm_unmount,
|
||||
dfs_elm_mkfs,
|
||||
dfs_elm_statfs,
|
||||
|
||||
dfs_elm_open,
|
||||
dfs_elm_close,
|
||||
dfs_elm_ioctl,
|
||||
dfs_elm_read,
|
||||
dfs_elm_write,
|
||||
dfs_elm_flush,
|
||||
dfs_elm_lseek,
|
||||
dfs_elm_getdents,
|
||||
dfs_elm_unlink,
|
||||
dfs_elm_stat,
|
||||
dfs_elm_rename,
|
||||
};
|
||||
|
||||
int elm_init(void)
|
||||
{
|
||||
#ifdef DFS_ELMFAT_INTERFACE_EFM
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _VOLUMES; i++)
|
||||
{
|
||||
diskStat[i] = STA_NOINIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* register fatfs file system */
|
||||
dfs_register(&dfs_elm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* RT-Thread Device Interface for ELM FatFs
|
||||
*/
|
||||
#ifdef DFS_ELMFAT_INTERFACE_EFM
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DSTATUS disk_initialize (
|
||||
BYTE drv /* Physical drive nmuber */
|
||||
)
|
||||
{
|
||||
rt_device_t device = disk[drv];
|
||||
|
||||
if (!device)
|
||||
{
|
||||
return RES_ERROR;
|
||||
}
|
||||
if (diskStat[drv] & STA_NODISK)
|
||||
{
|
||||
/* No card in the socket */
|
||||
return diskStat[drv];
|
||||
}
|
||||
|
||||
/* Initialize hardware: the actual operation is performed in dfs_mount() */
|
||||
diskStat[drv] &= ~STA_NOINIT;
|
||||
|
||||
return diskStat[drv];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DSTATUS disk_status (
|
||||
BYTE drv /* Physical drive nmuber */
|
||||
)
|
||||
{
|
||||
return diskStat[drv];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DRESULT disk_read (
|
||||
BYTE drv, /* Physical drive nmuber */
|
||||
BYTE *buff, /* Pointer to the data buffer to store read data */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
rt_device_t device = disk[drv];
|
||||
|
||||
if (!device)
|
||||
{
|
||||
return RES_ERROR;
|
||||
}
|
||||
if (!count)
|
||||
{
|
||||
return RES_PARERR;
|
||||
}
|
||||
if (diskStat[drv] & STA_NOINIT)
|
||||
{
|
||||
return RES_NOTRDY;
|
||||
}
|
||||
|
||||
if (rt_device_read(device, sector, buff, count) != count)
|
||||
{
|
||||
return RES_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (
|
||||
BYTE drv, /* Physical drive nmuber */
|
||||
const BYTE *buff, /* Pointer to the data to be written */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
rt_device_t device = disk[drv];
|
||||
|
||||
if (!device)
|
||||
{
|
||||
return RES_ERROR;
|
||||
}
|
||||
if (!count)
|
||||
{
|
||||
return RES_PARERR;
|
||||
}
|
||||
if (diskStat[drv] & STA_NOINIT)
|
||||
{
|
||||
return RES_NOTRDY;
|
||||
}
|
||||
if (diskStat[drv] & STA_PROTECT)
|
||||
{
|
||||
return RES_WRPRT;
|
||||
}
|
||||
|
||||
if (rt_device_write(device, sector, buff, count) != count)
|
||||
{
|
||||
return RES_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
#endif /* _READONLY */
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive data block */
|
||||
)
|
||||
{
|
||||
rt_device_t device = disk[drv];
|
||||
|
||||
if (!device)
|
||||
{
|
||||
return RES_ERROR;
|
||||
}
|
||||
if (diskStat[drv] & STA_NOINIT)
|
||||
{
|
||||
return RES_NOTRDY;
|
||||
}
|
||||
|
||||
if (rt_device_control(device, ctrl, buff) != RT_EOK)
|
||||
{
|
||||
return RES_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#include "diskio.h"
|
||||
|
||||
/* Inidialize a Drive */
|
||||
DSTATUS disk_initialize(BYTE drv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return Disk Status */
|
||||
DSTATUS disk_status(BYTE drv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read Sector(s) */
|
||||
DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, BYTE count)
|
||||
{
|
||||
rt_size_t result;
|
||||
rt_device_t device = disk[drv];
|
||||
|
||||
result = rt_device_read(device, sector, buff, count);
|
||||
if (result == count)
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
/* Write Sector(s) */
|
||||
DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, BYTE count)
|
||||
{
|
||||
rt_size_t result;
|
||||
rt_device_t device = disk[drv];
|
||||
|
||||
result = rt_device_write(device, sector, buff, count);
|
||||
if (result == count)
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
/* Miscellaneous Functions */
|
||||
DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff)
|
||||
{
|
||||
rt_device_t device = disk[drv];
|
||||
|
||||
if (device == RT_NULL)
|
||||
return RES_ERROR;
|
||||
|
||||
if (ctrl == GET_SECTOR_COUNT)
|
||||
{
|
||||
struct rt_device_blk_geometry geometry;
|
||||
|
||||
rt_memset(&geometry, 0, sizeof(geometry));
|
||||
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
|
||||
|
||||
*(DWORD *)buff = geometry.sector_count;
|
||||
if (geometry.sector_count == 0)
|
||||
return RES_ERROR;
|
||||
}
|
||||
else if (ctrl == GET_SECTOR_SIZE)
|
||||
{
|
||||
struct rt_device_blk_geometry geometry;
|
||||
|
||||
rt_memset(&geometry, 0, sizeof(geometry));
|
||||
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
|
||||
|
||||
*(WORD *)buff = geometry.bytes_per_sector;
|
||||
}
|
||||
else if (ctrl == GET_BLOCK_SIZE) /* Get erase block size in unit of sectors (DWORD) */
|
||||
{
|
||||
struct rt_device_blk_geometry geometry;
|
||||
|
||||
rt_memset(&geometry, 0, sizeof(geometry));
|
||||
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
|
||||
|
||||
*(DWORD *)buff = geometry.block_size/geometry.bytes_per_sector;
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
rt_time_t get_fattime(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj(BYTE drv, _SYNC_t *m)
|
||||
{
|
||||
char name[8];
|
||||
rt_mutex_t mutex;
|
||||
|
||||
rt_snprintf(name, sizeof(name), "fat%d", drv);
|
||||
mutex = rt_mutex_create(name, RT_IPC_FLAG_FIFO);
|
||||
if (mutex != RT_NULL)
|
||||
{
|
||||
*m = mutex;
|
||||
return RT_TRUE;
|
||||
}
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
int ff_del_syncobj(_SYNC_t m)
|
||||
{
|
||||
rt_mutex_delete(m);
|
||||
|
||||
return RT_TRUE;
|
||||
}
|
||||
|
||||
int ff_req_grant(_SYNC_t m)
|
||||
{
|
||||
if (rt_mutex_take(m, _FS_TIMEOUT) == RT_EOK)
|
||||
return RT_TRUE;
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
void ff_rel_grant(_SYNC_t m)
|
||||
{
|
||||
rt_mutex_release(m);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,521 +0,0 @@
|
|||
/*
|
||||
* File : shell.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rt-thread.org/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-04-30 Bernard the first verion for FinSH
|
||||
* 2006-05-08 Bernard change finsh thread stack to 2048
|
||||
* 2006-06-03 Bernard add support for skyeye
|
||||
* 2006-09-24 Bernard remove the code related with hardware
|
||||
* 2010-01-18 Bernard fix down then up key bug.
|
||||
* 2010-03-19 Bernard fix backspace issue and fix device read in shell.
|
||||
* 2010-04-01 Bernard add prompt output when start and remove the empty history
|
||||
* 2011-02-23 Bernard fix variable section end issue of finsh shell
|
||||
* initialization when use GNU GCC compiler.
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include "finsh.h"
|
||||
#include "shell.h"
|
||||
|
||||
/* finsh thread */
|
||||
static struct rt_thread finsh_thread;
|
||||
ALIGN(RT_ALIGN_SIZE)
|
||||
static char finsh_thread_stack[FINSH_THREAD_STACK_SIZE];
|
||||
struct finsh_shell* shell;
|
||||
|
||||
#if !defined (RT_USING_NEWLIB) && !defined (RT_USING_MINILIBC)
|
||||
int strcmp (const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 && *s1 == *s2) s1++, s2++;
|
||||
|
||||
return (*s1 - *s2);
|
||||
}
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
char *strdup(const char *s)
|
||||
{
|
||||
size_t len = strlen(s) + 1;
|
||||
char *tmp = (char *)rt_malloc(len);
|
||||
|
||||
if(!tmp) return NULL;
|
||||
|
||||
rt_memcpy(tmp, s, len);
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(__CC_ARM) && !defined(__IAR_SYSTEMS_ICC__)
|
||||
int isalpha( int ch )
|
||||
{
|
||||
return (unsigned int)((ch | 0x20) - 'a') < 26u;
|
||||
}
|
||||
|
||||
int atoi(const char* s)
|
||||
{
|
||||
long int v=0;
|
||||
int sign=1;
|
||||
while ( *s == ' ' || (unsigned int)(*s - 9) < 5u) s++;
|
||||
|
||||
switch (*s)
|
||||
{
|
||||
case '-': sign=-1;
|
||||
case '+': ++s;
|
||||
}
|
||||
|
||||
while ((unsigned int) (*s - '0') < 10u)
|
||||
{
|
||||
v=v*10+*s-'0'; ++s;
|
||||
}
|
||||
|
||||
return sign==-1?-v:v;
|
||||
}
|
||||
|
||||
int isprint(unsigned char ch)
|
||||
{
|
||||
return (unsigned int)(ch - ' ') < 127u - ' ';
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
|
||||
#include <dfs_posix.h>
|
||||
const char* finsh_get_prompt(void)
|
||||
{
|
||||
#define _PROMPT "finsh "
|
||||
static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = {_PROMPT};
|
||||
|
||||
/* get current working directory */
|
||||
getcwd(&finsh_prompt[6], RT_CONSOLEBUF_SIZE - 8);
|
||||
strcat(finsh_prompt, ">");
|
||||
|
||||
return finsh_prompt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size)
|
||||
{
|
||||
RT_ASSERT(shell != RT_NULL);
|
||||
|
||||
/* release semaphore to let finsh thread rx data */
|
||||
rt_sem_release(&shell->rx_sem);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup finsh
|
||||
*
|
||||
* This function sets the input device of finsh shell.
|
||||
*
|
||||
* @param device_name the name of new input device.
|
||||
*/
|
||||
void finsh_set_device(const char* device_name)
|
||||
{
|
||||
rt_device_t dev = RT_NULL;
|
||||
|
||||
RT_ASSERT(shell != RT_NULL);
|
||||
dev = rt_device_find(device_name);
|
||||
if (dev != RT_NULL && rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) == RT_EOK)
|
||||
{
|
||||
if (shell->device != RT_NULL)
|
||||
{
|
||||
/* close old finsh device */
|
||||
rt_device_close(shell->device);
|
||||
}
|
||||
|
||||
shell->device = dev;
|
||||
rt_device_set_rx_indicate(dev, finsh_rx_ind);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("finsh: can not find device:%s\n", device_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup finsh
|
||||
*
|
||||
* This function returns current finsh shell input device.
|
||||
*
|
||||
* @return the finsh shell input device name is returned.
|
||||
*/
|
||||
const char* finsh_get_device()
|
||||
{
|
||||
RT_ASSERT(shell != RT_NULL);
|
||||
return shell->device->parent.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup finsh
|
||||
*
|
||||
* This function set the echo mode of finsh shell.
|
||||
*
|
||||
* FINSH_OPTION_ECHO=0x01 is echo mode, other values are none-echo mode.
|
||||
*
|
||||
* @param echo the echo mode
|
||||
*/
|
||||
void finsh_set_echo(rt_uint32_t echo)
|
||||
{
|
||||
RT_ASSERT(shell != RT_NULL);
|
||||
shell->echo_mode = echo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup finsh
|
||||
*
|
||||
* This function gets the echo mode of finsh shell.
|
||||
*
|
||||
* @return the echo mode
|
||||
*/
|
||||
rt_uint32_t finsh_get_echo()
|
||||
{
|
||||
RT_ASSERT(shell != RT_NULL);
|
||||
|
||||
return shell->echo_mode;
|
||||
}
|
||||
|
||||
void finsh_auto_complete(char* prefix)
|
||||
{
|
||||
extern void list_prefix(char* prefix);
|
||||
|
||||
rt_kprintf("\n");
|
||||
list_prefix(prefix);
|
||||
rt_kprintf("%s%s", FINSH_PROMPT, prefix);
|
||||
}
|
||||
|
||||
void finsh_run_line(struct finsh_parser* parser, const char *line)
|
||||
{
|
||||
const char* err_str;
|
||||
|
||||
rt_kprintf("\n");
|
||||
finsh_parser_run(parser, (unsigned char*)line);
|
||||
|
||||
/* compile node root */
|
||||
if (finsh_errno() == 0)
|
||||
{
|
||||
finsh_compiler_run(parser->root);
|
||||
}
|
||||
else
|
||||
{
|
||||
err_str = finsh_error_string(finsh_errno());
|
||||
rt_kprintf("%s\n", err_str);
|
||||
}
|
||||
|
||||
/* run virtual machine */
|
||||
if (finsh_errno() == 0)
|
||||
{
|
||||
char ch;
|
||||
finsh_vm_run();
|
||||
|
||||
ch = (unsigned char)finsh_stack_bottom();
|
||||
if (ch > 0x20 && ch < 0x7e)
|
||||
{
|
||||
rt_kprintf("\t'%c', %d, 0x%08x\n",
|
||||
(unsigned char)finsh_stack_bottom(),
|
||||
(unsigned int)finsh_stack_bottom(),
|
||||
(unsigned int)finsh_stack_bottom());
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("\t%d, 0x%08x\n",
|
||||
(unsigned int)finsh_stack_bottom(),
|
||||
(unsigned int)finsh_stack_bottom());
|
||||
}
|
||||
}
|
||||
|
||||
finsh_flush(parser);
|
||||
}
|
||||
|
||||
#ifdef FINSH_USING_HISTORY
|
||||
rt_bool_t finsh_handle_history(struct finsh_shell* shell, char ch)
|
||||
{
|
||||
/*
|
||||
* handle up and down key
|
||||
* up key : 0x1b 0x5b 0x41
|
||||
* down key: 0x1b 0x5b 0x42
|
||||
*/
|
||||
if (ch == 0x1b)
|
||||
{
|
||||
shell->stat = WAIT_SPEC_KEY;
|
||||
return RT_TRUE;
|
||||
}
|
||||
|
||||
if ((shell->stat == WAIT_SPEC_KEY))
|
||||
{
|
||||
if (ch == 0x5b)
|
||||
{
|
||||
shell->stat = WAIT_FUNC_KEY;
|
||||
return RT_TRUE;
|
||||
}
|
||||
|
||||
shell->stat = WAIT_NORMAL;
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
if (shell->stat == WAIT_FUNC_KEY)
|
||||
{
|
||||
shell->stat = WAIT_NORMAL;
|
||||
|
||||
if (ch == 0x41) /* up key */
|
||||
{
|
||||
/* prev history */
|
||||
if (shell->current_history > 0)shell->current_history --;
|
||||
else
|
||||
{
|
||||
shell->current_history = 0;
|
||||
return RT_TRUE;
|
||||
}
|
||||
|
||||
/* copy the history command */
|
||||
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
|
||||
FINSH_CMD_SIZE);
|
||||
shell->line_position = strlen(shell->line);
|
||||
shell->use_history = 1;
|
||||
}
|
||||
else if (ch == 0x42) /* down key */
|
||||
{
|
||||
/* next history */
|
||||
if (shell->current_history < shell->history_count - 1)
|
||||
shell->current_history ++;
|
||||
else
|
||||
{
|
||||
/* set to the end of history */
|
||||
if (shell->history_count != 0)
|
||||
{
|
||||
shell->current_history = shell->history_count - 1;
|
||||
}
|
||||
else return RT_TRUE;
|
||||
}
|
||||
|
||||
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
|
||||
FINSH_CMD_SIZE);
|
||||
shell->line_position = strlen(shell->line);
|
||||
shell->use_history = 1;
|
||||
}
|
||||
|
||||
if (shell->use_history)
|
||||
{
|
||||
rt_kprintf("\033[2K\r");
|
||||
rt_kprintf("%s%s", FINSH_PROMPT, shell->line);
|
||||
return RT_TRUE;;
|
||||
}
|
||||
}
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
void finsh_push_history(struct finsh_shell* shell)
|
||||
{
|
||||
if ((shell->use_history == 0) && (shell->line_position != 0))
|
||||
{
|
||||
/* push history */
|
||||
if (shell->history_count >= FINSH_HISTORY_LINES)
|
||||
{
|
||||
/* move history */
|
||||
int index;
|
||||
for (index = 0; index < FINSH_HISTORY_LINES - 1; index ++)
|
||||
{
|
||||
memcpy(&shell->cmd_history[index][0],
|
||||
&shell->cmd_history[index + 1][0], FINSH_CMD_SIZE);
|
||||
}
|
||||
memset(&shell->cmd_history[index][0], 0, FINSH_CMD_SIZE);
|
||||
memcpy(&shell->cmd_history[index][0], shell->line, shell->line_position);
|
||||
|
||||
/* it's the maximum history */
|
||||
shell->history_count = FINSH_HISTORY_LINES;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&shell->cmd_history[shell->history_count][0], 0, FINSH_CMD_SIZE);
|
||||
memcpy(&shell->cmd_history[shell->history_count][0], shell->line, shell->line_position);
|
||||
|
||||
/* increase count and set current history position */
|
||||
shell->history_count ++;
|
||||
}
|
||||
}
|
||||
shell->current_history = shell->history_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RT_USING_HEAP
|
||||
struct finsh_shell _shell;
|
||||
#endif
|
||||
void finsh_thread_entry(void* parameter)
|
||||
{
|
||||
char ch;
|
||||
|
||||
/* test: for efm32 low power mode */
|
||||
emu_all_disable();
|
||||
|
||||
/* normal is echo mode */
|
||||
shell->echo_mode = 1;
|
||||
|
||||
finsh_init(&shell->parser);
|
||||
rt_kprintf(FINSH_PROMPT);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* test: for efm32 low power mode */
|
||||
emu_em2_enable();
|
||||
|
||||
/* wait receive */
|
||||
if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;
|
||||
|
||||
/* test: for efm32 low power mode */
|
||||
emu_em2_disable();
|
||||
|
||||
/* read one character from device */
|
||||
while (rt_device_read(shell->device, 0, &ch, 1) == 1)
|
||||
{
|
||||
/* handle history key */
|
||||
#ifdef FINSH_USING_HISTORY
|
||||
if (finsh_handle_history(shell, ch) == RT_TRUE) continue;
|
||||
#endif
|
||||
|
||||
/* handle CR key */
|
||||
if (ch == '\r')
|
||||
{
|
||||
char next;
|
||||
|
||||
if (rt_device_read(shell->device, 0, &next, 1) == 1)
|
||||
ch = next;
|
||||
else ch = '\r';
|
||||
}
|
||||
/* handle tab key */
|
||||
else if (ch == '\t')
|
||||
{
|
||||
/* auto complete */
|
||||
finsh_auto_complete(&shell->line[0]);
|
||||
/* re-calculate position */
|
||||
shell->line_position = strlen(shell->line);
|
||||
continue;
|
||||
}
|
||||
/* handle backspace key */
|
||||
else if (ch == 0x7f || ch == 0x08)
|
||||
{
|
||||
if (shell->line_position != 0)
|
||||
{
|
||||
rt_kprintf("%c %c", ch, ch);
|
||||
}
|
||||
if (shell->line_position <= 0) shell->line_position = 0;
|
||||
else shell->line_position --;
|
||||
shell->line[shell->line_position] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* handle end of line, break */
|
||||
if (ch == '\r' || ch == '\n')
|
||||
{
|
||||
/* change to ';' and break */
|
||||
shell->line[shell->line_position] = ';';
|
||||
|
||||
#ifdef FINSH_USING_HISTORY
|
||||
finsh_push_history(shell);
|
||||
#endif
|
||||
|
||||
if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
|
||||
else rt_kprintf("\n");
|
||||
|
||||
rt_kprintf(FINSH_PROMPT);
|
||||
memset(shell->line, 0, sizeof(shell->line));
|
||||
shell->line_position = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* it's a large line, discard it */
|
||||
if (shell->line_position >= FINSH_CMD_SIZE) shell->line_position = 0;
|
||||
|
||||
/* normal character */
|
||||
shell->line[shell->line_position] = ch; ch = 0;
|
||||
if (shell->echo_mode) rt_kprintf("%c", shell->line[shell->line_position]);
|
||||
shell->line_position ++;
|
||||
shell->use_history = 0; /* it's a new command */
|
||||
} /* end of device read */
|
||||
}
|
||||
}
|
||||
|
||||
void finsh_system_function_init(const void* begin, const void* end)
|
||||
{
|
||||
_syscall_table_begin = (struct finsh_syscall*) begin;
|
||||
_syscall_table_end = (struct finsh_syscall*) end;
|
||||
}
|
||||
|
||||
void finsh_system_var_init(const void* begin, const void* end)
|
||||
{
|
||||
_sysvar_table_begin = (struct finsh_sysvar*) begin;
|
||||
_sysvar_table_end = (struct finsh_sysvar*) end;
|
||||
}
|
||||
|
||||
#if defined(__ICCARM__) /* for IAR compiler */
|
||||
#ifdef FINSH_USING_SYMTAB
|
||||
#pragma section="FSymTab"
|
||||
#pragma section="VSymTab"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @ingroup finsh
|
||||
*
|
||||
* This function will initialize finsh shell
|
||||
*/
|
||||
int finsh_system_init(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
#ifdef FINSH_USING_SYMTAB
|
||||
#ifdef __CC_ARM /* ARM C Compiler */
|
||||
extern const int FSymTab$$Base;
|
||||
extern const int FSymTab$$Limit;
|
||||
extern const int VSymTab$$Base;
|
||||
extern const int VSymTab$$Limit;
|
||||
finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
|
||||
finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);
|
||||
#elif defined (__ICCARM__) /* for IAR Compiler */
|
||||
finsh_system_function_init(__section_begin("FSymTab"),
|
||||
__section_end("FSymTab"));
|
||||
finsh_system_var_init(__section_begin("VSymTab"),
|
||||
__section_end("VSymTab"));
|
||||
#elif defined (__GNUC__) /* GNU GCC Compiler */
|
||||
extern const int __fsymtab_start;
|
||||
extern const int __fsymtab_end;
|
||||
extern const int __vsymtab_start;
|
||||
extern const int __vsymtab_end;
|
||||
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
|
||||
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* create or set shell structure */
|
||||
#ifdef RT_USING_HEAP
|
||||
shell = (struct finsh_shell*)rt_malloc(sizeof(struct finsh_shell));
|
||||
#else
|
||||
shell = &_shell;
|
||||
#endif
|
||||
if (shell == RT_NULL)
|
||||
{
|
||||
rt_kprintf("no memory for shell\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(shell, 0, sizeof(struct finsh_shell));
|
||||
|
||||
rt_sem_init(&(shell->rx_sem), "shrx", 0, 0);
|
||||
result = rt_thread_init(&finsh_thread,
|
||||
"tshell",
|
||||
finsh_thread_entry, RT_NULL,
|
||||
&finsh_thread_stack[0], sizeof(finsh_thread_stack),
|
||||
FINSH_THREAD_PRIORITY, 10);
|
||||
|
||||
if (result == RT_EOK)
|
||||
rt_thread_startup(&finsh_thread);
|
||||
}
|
|
@ -80,10 +80,6 @@
|
|||
/* Using QEMU or SkyEye*/
|
||||
/* #define RT_USING_EMULATOR */
|
||||
|
||||
/* SECTION: a mini libc */
|
||||
/* Using mini libc library*/
|
||||
/* #define RT_USING_MINILIBC */
|
||||
|
||||
/* SECTION: C++ support */
|
||||
/* Using C++ support*/
|
||||
/* #define RT_USING_CPLUSPLUS */
|
||||
|
|
|
@ -93,7 +93,6 @@
|
|||
/* SECTION: a runtime libc library */
|
||||
/* a runtime libc library*/
|
||||
/* #define RT_USING_NEWLIB */
|
||||
#define RT_USING_MINILIBC
|
||||
|
||||
/* SECTION: C++ support */
|
||||
/* Using C++ support*/
|
||||
|
|
|
@ -72,10 +72,6 @@
|
|||
#define FINSH_USING_SYMTAB
|
||||
#define FINSH_USING_DESCRIPTION
|
||||
|
||||
/* SECTION: a mini libc */
|
||||
/* Using mini libc library*/
|
||||
/* #define RT_USING_MINILIBC */
|
||||
|
||||
/* SECTION: C++ support */
|
||||
/* Using C++ support*/
|
||||
/* #define RT_USING_CPLUSPLUS */
|
||||
|
|
|
@ -37,32 +37,6 @@ struct stm32_dac
|
|||
|
||||
static struct stm32_dac stm32_dac_obj[sizeof(dac_config) / sizeof(dac_config[0])];
|
||||
|
||||
static rt_err_t stm32_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
|
||||
{
|
||||
DAC_HandleTypeDef *stm32_dac_handler;
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
stm32_dac_handler = device->parent.user_data;
|
||||
|
||||
#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4)
|
||||
HAL_DAC_Start(stm32_dac_handler, channel);
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t stm32_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
|
||||
{
|
||||
DAC_HandleTypeDef *stm32_dac_handler;
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
stm32_dac_handler = device->parent.user_data;
|
||||
|
||||
#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4)
|
||||
HAL_DAC_Stop(stm32_dac_handler, channel);
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_uint32_t stm32_dac_get_channel(rt_uint32_t channel)
|
||||
{
|
||||
rt_uint32_t stm32_channel = 0;
|
||||
|
@ -83,6 +57,54 @@ static rt_uint32_t stm32_dac_get_channel(rt_uint32_t channel)
|
|||
return stm32_channel;
|
||||
}
|
||||
|
||||
static rt_err_t stm32_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
|
||||
{
|
||||
uint32_t dac_channel;
|
||||
DAC_HandleTypeDef *stm32_dac_handler;
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
stm32_dac_handler = device->parent.user_data;
|
||||
|
||||
#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4)
|
||||
if ((channel <= 2) && (channel > 0))
|
||||
{
|
||||
/* set stm32 dac channel */
|
||||
dac_channel = stm32_dac_get_channel(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("dac channel must be 1 or 2.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
HAL_DAC_Start(stm32_dac_handler, dac_channel);
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t stm32_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
|
||||
{
|
||||
uint32_t dac_channel;
|
||||
DAC_HandleTypeDef *stm32_dac_handler;
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
stm32_dac_handler = device->parent.user_data;
|
||||
|
||||
#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4)
|
||||
if ((channel <= 2) && (channel > 0))
|
||||
{
|
||||
/* set stm32 dac channel */
|
||||
dac_channel = stm32_dac_get_channel(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("dac channel must be 1 or 2.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
HAL_DAC_Stop(stm32_dac_handler, dac_channel);
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t stm32_set_dac_value(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
|
||||
{
|
||||
uint32_t dac_channel;
|
||||
|
|
|
@ -114,7 +114,10 @@ static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_c
|
|||
switch (cfg->data_bits)
|
||||
{
|
||||
case DATA_BITS_8:
|
||||
uart->handle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
if (cfg->parity == PARITY_ODD || cfg->parity == PARITY_EVEN)
|
||||
uart->handle.Init.WordLength = UART_WORDLENGTH_9B;
|
||||
else
|
||||
uart->handle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
break;
|
||||
case DATA_BITS_9:
|
||||
uart->handle.Init.WordLength = UART_WORDLENGTH_9B;
|
||||
|
|
|
@ -65,10 +65,6 @@
|
|||
/* Using FinSH as Shell*/
|
||||
/* #define RT_USING_FINSH */
|
||||
|
||||
/* SECTION: a mini libc */
|
||||
/* Using mini libc library*/
|
||||
/* #define RT_USING_MINILIBC */
|
||||
|
||||
/* SECTION: C++ support */
|
||||
/* Using C++ support*/
|
||||
/* #define RT_USING_CPLUSPLUS */
|
||||
|
|
|
@ -47,15 +47,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef RT_USING_MINILIBC
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned long u_long;
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
@ -63,14 +55,6 @@ typedef unsigned long long uint64_t;
|
|||
typedef int bool_t;
|
||||
typedef int enum_t;
|
||||
|
||||
#ifndef RT_USING_NEWLIB
|
||||
typedef unsigned long dev_t;
|
||||
#endif
|
||||
|
||||
#if !defined(RT_USING_NEWLIB) && !defined(RT_USING_MINILIBC)
|
||||
typedef rt_int32_t ssize_t;
|
||||
#endif
|
||||
|
||||
/* This needs to be changed to uint32_t in the future */
|
||||
typedef unsigned long rpcprog_t;
|
||||
typedef unsigned long rpcvers_t;
|
||||
|
|
|
@ -25,4 +25,10 @@ typedef long signed int ssize_t; /* Used for a count of bytes or an error
|
|||
#endif
|
||||
typedef unsigned long useconds_t; /* microseconds (unsigned) */
|
||||
|
||||
typedef unsigned long dev_t;
|
||||
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned long u_long;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* RT_USING_DFS is not defined
|
||||
* 2020-02-13 Meco Man re-implement exit() and abort()
|
||||
* 2020-02-14 Meco Man implement _sys_tmpnam()
|
||||
* 2020-02-25 Meco Man add multithreaded protection
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -41,6 +42,36 @@ const char __stdin_name[] = "STDIN";
|
|||
const char __stdout_name[] = "STDOUT";
|
||||
const char __stderr_name[] = "STDERR";
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
int _mutex_initialize(rt_mutex_t *m)
|
||||
{
|
||||
*m = rt_mutex_create("_mutex_", RT_IPC_FLAG_PRIO);
|
||||
if(*m == RT_NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void _mutex_acquire(rt_mutex_t *m)
|
||||
{
|
||||
rt_mutex_take(*m, RT_WAITING_FOREVER);
|
||||
}
|
||||
|
||||
void _mutex_release(rt_mutex_t *m)
|
||||
{
|
||||
rt_mutex_release(*m);
|
||||
}
|
||||
|
||||
void _mutex_free(rt_mutex_t *m)
|
||||
{
|
||||
rt_mutex_delete(*m);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* required by fopen() and freopen().
|
||||
*
|
||||
|
|
|
@ -10,7 +10,7 @@ CPPPATH = [cwd]
|
|||
if GetDepend('RT_USING_LIBC'):
|
||||
src += Glob('*.c')
|
||||
else:
|
||||
if GetDepend('RT_LIBC_USING_TIME') and not GetDepend('RT_USING_MINILIBC'):
|
||||
if GetDepend('RT_LIBC_USING_TIME'):
|
||||
src += ['time.c']
|
||||
|
||||
if GetDepend('RT_USING_POSIX') == False:
|
||||
|
@ -21,7 +21,7 @@ if rtconfig.CROSS_TOOL == 'keil':
|
|||
else:
|
||||
CPPDEFINES = []
|
||||
|
||||
if not GetDepend('RT_USING_MINILIBC') and (GetDepend('RT_USING_LIBC') or GetDepend('RT_LIBC_USING_TIME')):
|
||||
if GetDepend('RT_USING_LIBC') or GetDepend('RT_LIBC_USING_TIME'):
|
||||
group = DefineGroup('libc', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
|
||||
|
||||
Return('group')
|
||||
|
|
|
@ -24,4 +24,10 @@ typedef long signed int ssize_t; /* Used for a count of bytes or an error
|
|||
#endif
|
||||
typedef unsigned long useconds_t; /* microseconds (unsigned) */
|
||||
|
||||
typedef unsigned long dev_t;
|
||||
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned long u_long;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
from building import *
|
||||
Import('rtconfig')
|
||||
|
||||
src = Glob('*.c') + Glob('*.cpp')
|
||||
cwd = GetCurrentDir()
|
||||
group = []
|
||||
|
||||
CPPPATH = [cwd]
|
||||
CPPDEFINES = ['RT_USING_MINILIBC']
|
||||
|
||||
if rtconfig.PLATFORM == 'gcc' and rtconfig.ARCH != 'sim' and not GetDepend('RT_USING_LIBC') and GetDepend('RT_USING_MINILIBC'):
|
||||
group = DefineGroup('libc', src, depend = [''],
|
||||
CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
|
||||
|
||||
Return('group')
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-08-14 Bernard the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC)
|
||||
#include "ctype.h"
|
||||
|
||||
int isprint (int ch)
|
||||
{
|
||||
ch&=0x7f;
|
||||
return (ch>=32 && ch<127);
|
||||
}
|
||||
|
||||
int isalpha(int ch)
|
||||
{
|
||||
return (unsigned int)((ch | 0x20) - 'a') < 26u;
|
||||
}
|
||||
|
||||
int isdigit (int ch)
|
||||
{
|
||||
return (unsigned int)(ch - '0') < 10u;
|
||||
}
|
||||
|
||||
int isspace(int ch)
|
||||
{
|
||||
switch(ch)
|
||||
{
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\f':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\v':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-08-14 Bernard the first version
|
||||
*/
|
||||
#ifndef __CTYPE_H__
|
||||
#define __CTYPE_H__
|
||||
|
||||
int isprint(int c) __attribute__ ((__const__));
|
||||
int isalpha (int c) __attribute__ ((__const__));
|
||||
int isdigit (int ch) __attribute__ ((__const__));
|
||||
int isspace(int ch) __attribute__ ((__const__));
|
||||
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef __ERRNO_H__
|
||||
#define __ERRNO_H__
|
||||
|
||||
#include "libc/libc_errno.h"
|
||||
/* Others defined in libc/libc_errno.h */
|
||||
#define ENSRNOTFOUND 163 /* Domain name not found */
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef __INTTYPES_H__
|
||||
#define __INTTYPES_H__
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#endif
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS CRT
|
||||
* FILE: lib/crt/math/cos.c
|
||||
* PURPOSE: Generic C Implementation of cos
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
#define PRECISION 9
|
||||
|
||||
static double cos_off_tbl[] = {0.0, -M_PI/2., 0, -M_PI/2.};
|
||||
static double cos_sign_tbl[] = {1,-1,-1,1};
|
||||
|
||||
static double sin_off_tbl[] = {0.0, -M_PI/2., 0, -M_PI/2.};
|
||||
static double sin_sign_tbl[] = {1,-1,-1,1};
|
||||
|
||||
double sin(double x)
|
||||
{
|
||||
int quadrant;
|
||||
double x2, result;
|
||||
|
||||
/* Calculate the quadrant */
|
||||
quadrant = x * (2./M_PI);
|
||||
|
||||
/* Get offset inside quadrant */
|
||||
x = x - quadrant * (M_PI/2.);
|
||||
|
||||
/* Normalize quadrant to [0..3] */
|
||||
quadrant = (quadrant - 1) & 0x3;
|
||||
|
||||
/* Fixup value for the generic function */
|
||||
x += sin_off_tbl[quadrant];
|
||||
|
||||
/* Calculate the negative of the square of x */
|
||||
x2 = - (x * x);
|
||||
|
||||
/* This is an unrolled taylor series using <PRECISION> iterations
|
||||
* Example with 4 iterations:
|
||||
* result = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8!
|
||||
* To save multiplications and to keep the precision high, it's performed
|
||||
* like this:
|
||||
* result = 1 - x^2 * (1/2! - x^2 * (1/4! - x^2 * (1/6! - x^2 * (1/8!))))
|
||||
*/
|
||||
|
||||
/* Start with 0, compiler will optimize this away */
|
||||
result = 0;
|
||||
|
||||
#if (PRECISION >= 10)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 9)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 8)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 7)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 6)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 5)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10);
|
||||
result *= x2;
|
||||
#endif
|
||||
result += 1./(1.*2*3*4*5*6*7*8);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2*3*4*5*6);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2*3*4);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2);
|
||||
result *= x2;
|
||||
|
||||
result += 1;
|
||||
|
||||
/* Apply correct sign */
|
||||
result *= sin_sign_tbl[quadrant];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double cos(double x)
|
||||
{
|
||||
int quadrant;
|
||||
double x2, result;
|
||||
|
||||
/* Calculate the quadrant */
|
||||
quadrant = x * (2./M_PI);
|
||||
|
||||
/* Get offset inside quadrant */
|
||||
x = x - quadrant * (M_PI/2.);
|
||||
|
||||
/* Normalize quadrant to [0..3] */
|
||||
quadrant = quadrant & 0x3;
|
||||
|
||||
/* Fixup value for the generic function */
|
||||
x += cos_off_tbl[quadrant];
|
||||
|
||||
/* Calculate the negative of the square of x */
|
||||
x2 = - (x * x);
|
||||
|
||||
/* This is an unrolled taylor series using <PRECISION> iterations
|
||||
* Example with 4 iterations:
|
||||
* result = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8!
|
||||
* To save multiplications and to keep the precision high, it's performed
|
||||
* like this:
|
||||
* result = 1 - x^2 * (1/2! - x^2 * (1/4! - x^2 * (1/6! - x^2 * (1/8!))))
|
||||
*/
|
||||
|
||||
/* Start with 0, compiler will optimize this away */
|
||||
result = 0;
|
||||
|
||||
#if (PRECISION >= 10)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 9)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 8)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 7)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 6)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 5)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10);
|
||||
result *= x2;
|
||||
#endif
|
||||
result += 1./(1.*2*3*4*5*6*7*8);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2*3*4*5*6);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2*3*4);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2);
|
||||
result *= x2;
|
||||
|
||||
result += 1;
|
||||
|
||||
/* Apply correct sign */
|
||||
result *= cos_sign_tbl[quadrant];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef __MATH_H__
|
||||
#define __MATH_H__
|
||||
|
||||
#define M_PI 3.141592653589793238462643
|
||||
|
||||
double sin(double x);
|
||||
double cos(double x);
|
||||
|
||||
typedef float float_t;
|
||||
typedef double double_t;
|
||||
|
||||
#endif
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void exch(char* base,size_t size,size_t a,size_t b) {
|
||||
char* x=base+a*size;
|
||||
char* y=base+b*size;
|
||||
while (size) {
|
||||
char z=*x;
|
||||
*x=*y;
|
||||
*y=z;
|
||||
--size; ++x; ++y;
|
||||
}
|
||||
}
|
||||
|
||||
/* Quicksort with 3-way partitioning, ala Sedgewick */
|
||||
/* Blame him for the scary variable names */
|
||||
/* http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf */
|
||||
static void quicksort(char* base,size_t size,ssize_t l,ssize_t r,
|
||||
int (*compar)(const void*,const void*)) {
|
||||
ssize_t i=l-1, j=r, p=l-1, q=r, k;
|
||||
char* v=base+r*size;
|
||||
if (r<=l) return;
|
||||
for (;;) {
|
||||
while (++i != r && compar(base+i*size,v)<0) ;
|
||||
while (compar(v,base+(--j)*size)<0) if (j == l) break;
|
||||
if (i >= j) break;
|
||||
exch(base,size,i,j);
|
||||
if (compar(base+i*size,v)==0) exch(base,size,++p,i);
|
||||
if (compar(v,base+j*size)==0) exch(base,size,j,--q);
|
||||
}
|
||||
exch(base,size,i,r); j = i-1; ++i;
|
||||
for (k=l; k<p; k++, j--) exch(base,size,k,j);
|
||||
for (k=r-1; k>q; k--, i++) exch(base,size,i,k);
|
||||
quicksort(base,size,l,j,compar);
|
||||
quicksort(base,size,i,r,compar);
|
||||
}
|
||||
|
||||
void qsort(void* base,size_t nmemb,size_t size,int (*compar)(const void*,const void*)) {
|
||||
/* check for integer overflows */
|
||||
if (nmemb >= (((size_t)-1)>>1) ||
|
||||
size >= (((size_t)-1)>>1)) return;
|
||||
if (nmemb>1)
|
||||
quicksort(base,size,0,nmemb-1,compar);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
static unsigned int _seed=1;
|
||||
|
||||
/* Knuth's TAOCP section 3.6 */
|
||||
#define M ((1U<<31) -1)
|
||||
#define A 48271
|
||||
#define Q 44488 // M/A
|
||||
#define R 3399 // M%A; R < Q !!!
|
||||
|
||||
int rand_r(unsigned int* seed)
|
||||
{ int32_t X;
|
||||
|
||||
X = *seed;
|
||||
X = A*(X%Q) - R * (int32_t) (X/Q);
|
||||
if (X < 0)
|
||||
X += M;
|
||||
|
||||
*seed = X;
|
||||
return X;
|
||||
}
|
||||
|
||||
int rand(void) {
|
||||
return rand_r(&_seed);
|
||||
}
|
||||
|
||||
void srand(unsigned int i)
|
||||
{
|
||||
_seed=i;
|
||||
}
|
||||
|
||||
int random(void) __attribute__((alias("rand")));
|
||||
void srandom(unsigned int i) __attribute__((alias("srand")));
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-09-12 Bernard The first version
|
||||
*/
|
||||
|
||||
#ifndef SIGNAL_H__
|
||||
#define SIGNAL_H__
|
||||
|
||||
#include <libc/libc_signal.h>
|
||||
|
||||
#define SIG_DFL ((_sig_func_ptr)0) /* Default action */
|
||||
#define SIG_IGN ((_sig_func_ptr)1) /* Ignore action */
|
||||
#define SIG_ERR ((_sig_func_ptr)-1) /* Error return */
|
||||
|
||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef __STDDEF_H__
|
||||
#define __STDDEF_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
typedef signed long ptrdiff_t;
|
||||
|
||||
#endif
|
|
@ -1,266 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
/*
|
||||
* ISO C Standard: 7.18 Integer types <stdint.h>
|
||||
*/
|
||||
|
||||
#ifndef __STDINT_H__
|
||||
#define __STDINT_H__
|
||||
|
||||
/* 7.8.1.1 Exact-width integer types */
|
||||
|
||||
#ifdef __INT8_TYPE__
|
||||
typedef __INT8_TYPE__ int8_t;
|
||||
#endif
|
||||
#ifdef __INT16_TYPE__
|
||||
typedef __INT16_TYPE__ int16_t;
|
||||
#endif
|
||||
#ifdef __INT32_TYPE__
|
||||
typedef __INT32_TYPE__ int32_t;
|
||||
#endif
|
||||
#ifdef __INT64_TYPE__
|
||||
typedef __INT64_TYPE__ int64_t;
|
||||
#endif
|
||||
#ifdef __UINT8_TYPE__
|
||||
typedef __UINT8_TYPE__ uint8_t;
|
||||
#endif
|
||||
#ifdef __UINT16_TYPE__
|
||||
typedef __UINT16_TYPE__ uint16_t;
|
||||
#endif
|
||||
#ifdef __UINT32_TYPE__
|
||||
typedef __UINT32_TYPE__ uint32_t;
|
||||
#endif
|
||||
#ifdef __UINT64_TYPE__
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
#endif
|
||||
|
||||
/* 7.8.1.2 Minimum-width integer types */
|
||||
|
||||
typedef __INT_LEAST8_TYPE__ int_least8_t;
|
||||
typedef __INT_LEAST16_TYPE__ int_least16_t;
|
||||
typedef __INT_LEAST32_TYPE__ int_least32_t;
|
||||
typedef __INT_LEAST64_TYPE__ int_least64_t;
|
||||
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
|
||||
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
|
||||
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
|
||||
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
|
||||
|
||||
/* 7.8.1.3 Fastest minimum-width integer types */
|
||||
|
||||
typedef __INT_FAST8_TYPE__ int_fast8_t;
|
||||
typedef __INT_FAST16_TYPE__ int_fast16_t;
|
||||
typedef __INT_FAST32_TYPE__ int_fast32_t;
|
||||
typedef __INT_FAST64_TYPE__ int_fast64_t;
|
||||
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
|
||||
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
|
||||
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
|
||||
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
|
||||
|
||||
/* 7.8.1.4 Integer types capable of holding object pointers */
|
||||
|
||||
#ifdef __INTPTR_TYPE__
|
||||
typedef __INTPTR_TYPE__ intptr_t;
|
||||
#endif
|
||||
#ifdef __UINTPTR_TYPE__
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
#endif
|
||||
|
||||
/* 7.8.1.5 Greatest-width integer types */
|
||||
|
||||
typedef __INTMAX_TYPE__ intmax_t;
|
||||
typedef __UINTMAX_TYPE__ uintmax_t;
|
||||
|
||||
#if (!defined __cplusplus || __cplusplus >= 201103L \
|
||||
|| defined __STDC_LIMIT_MACROS)
|
||||
|
||||
/*
|
||||
* 7.18.2 Limits of specified-width integer types.
|
||||
*
|
||||
* The following object-like macros specify the minimum and maximum limits
|
||||
* of integer types corresponding to the typedef names defined above.
|
||||
*/
|
||||
|
||||
/* 7.18.2.1 Limits of exact-width integer types */
|
||||
|
||||
#ifdef __INT8_MAX__
|
||||
# undef INT8_MAX
|
||||
# define INT8_MAX __INT8_MAX__
|
||||
# undef INT8_MIN
|
||||
# define INT8_MIN (-INT8_MAX - 1)
|
||||
#endif
|
||||
#ifdef __UINT8_MAX__
|
||||
# undef UINT8_MAX
|
||||
# define UINT8_MAX __UINT8_MAX__
|
||||
#endif
|
||||
#ifdef __INT16_MAX__
|
||||
# undef INT16_MAX
|
||||
# define INT16_MAX __INT16_MAX__
|
||||
# undef INT16_MIN
|
||||
# define INT16_MIN (-INT16_MAX - 1)
|
||||
#endif
|
||||
#ifdef __UINT16_MAX__
|
||||
# undef UINT16_MAX
|
||||
# define UINT16_MAX __UINT16_MAX__
|
||||
#endif
|
||||
#ifdef __INT32_MAX__
|
||||
# undef INT32_MAX
|
||||
# define INT32_MAX __INT32_MAX__
|
||||
# undef INT32_MIN
|
||||
# define INT32_MIN (-INT32_MAX - 1)
|
||||
#endif
|
||||
#ifdef __UINT32_MAX__
|
||||
# undef UINT32_MAX
|
||||
# define UINT32_MAX __UINT32_MAX__
|
||||
#endif
|
||||
#ifdef __INT64_MAX__
|
||||
# undef INT64_MAX
|
||||
# define INT64_MAX __INT64_MAX__
|
||||
# undef INT64_MIN
|
||||
# define INT64_MIN (-INT64_MAX - 1)
|
||||
#endif
|
||||
#ifdef __UINT64_MAX__
|
||||
# undef UINT64_MAX
|
||||
# define UINT64_MAX __UINT64_MAX__
|
||||
#endif
|
||||
|
||||
#undef INT_LEAST8_MAX
|
||||
#define INT_LEAST8_MAX __INT_LEAST8_MAX__
|
||||
#undef INT_LEAST8_MIN
|
||||
#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1)
|
||||
#undef UINT_LEAST8_MAX
|
||||
#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
|
||||
#undef INT_LEAST16_MAX
|
||||
#define INT_LEAST16_MAX __INT_LEAST16_MAX__
|
||||
#undef INT_LEAST16_MIN
|
||||
#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1)
|
||||
#undef UINT_LEAST16_MAX
|
||||
#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
|
||||
#undef INT_LEAST32_MAX
|
||||
#define INT_LEAST32_MAX __INT_LEAST32_MAX__
|
||||
#undef INT_LEAST32_MIN
|
||||
#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
|
||||
#undef UINT_LEAST32_MAX
|
||||
#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
|
||||
#undef INT_LEAST64_MAX
|
||||
#define INT_LEAST64_MAX __INT_LEAST64_MAX__
|
||||
#undef INT_LEAST64_MIN
|
||||
#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1)
|
||||
#undef UINT_LEAST64_MAX
|
||||
#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
|
||||
|
||||
#undef INT_FAST8_MAX
|
||||
#define INT_FAST8_MAX __INT_FAST8_MAX__
|
||||
#undef INT_FAST8_MIN
|
||||
#define INT_FAST8_MIN (-INT_FAST8_MAX - 1)
|
||||
#undef UINT_FAST8_MAX
|
||||
#define UINT_FAST8_MAX __UINT_FAST8_MAX__
|
||||
#undef INT_FAST16_MAX
|
||||
#define INT_FAST16_MAX __INT_FAST16_MAX__
|
||||
#undef INT_FAST16_MIN
|
||||
#define INT_FAST16_MIN (-INT_FAST16_MAX - 1)
|
||||
#undef UINT_FAST16_MAX
|
||||
#define UINT_FAST16_MAX __UINT_FAST16_MAX__
|
||||
#undef INT_FAST32_MAX
|
||||
#define INT_FAST32_MAX __INT_FAST32_MAX__
|
||||
#undef INT_FAST32_MIN
|
||||
#define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
|
||||
#undef UINT_FAST32_MAX
|
||||
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
|
||||
#undef INT_FAST64_MAX
|
||||
#define INT_FAST64_MAX __INT_FAST64_MAX__
|
||||
#undef INT_FAST64_MIN
|
||||
#define INT_FAST64_MIN (-INT_FAST64_MAX - 1)
|
||||
#undef UINT_FAST64_MAX
|
||||
#define UINT_FAST64_MAX __UINT_FAST64_MAX__
|
||||
|
||||
#ifdef __INTPTR_MAX__
|
||||
# undef INTPTR_MAX
|
||||
# define INTPTR_MAX __INTPTR_MAX__
|
||||
# undef INTPTR_MIN
|
||||
# define INTPTR_MIN (-INTPTR_MAX - 1)
|
||||
#endif
|
||||
#ifdef __UINTPTR_MAX__
|
||||
# undef UINTPTR_MAX
|
||||
# define UINTPTR_MAX __UINTPTR_MAX__
|
||||
#endif
|
||||
|
||||
#undef INTMAX_MAX
|
||||
#define INTMAX_MAX __INTMAX_MAX__
|
||||
#undef INTMAX_MIN
|
||||
#define INTMAX_MIN (-INTMAX_MAX - 1)
|
||||
#undef UINTMAX_MAX
|
||||
#define UINTMAX_MAX __UINTMAX_MAX__
|
||||
|
||||
/* 7.18.3 Limits of other integer types */
|
||||
|
||||
#undef PTRDIFF_MAX
|
||||
#define PTRDIFF_MAX __PTRDIFF_MAX__
|
||||
#undef PTRDIFF_MIN
|
||||
#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
|
||||
|
||||
#undef SIG_ATOMIC_MAX
|
||||
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
|
||||
#undef SIG_ATOMIC_MIN
|
||||
#define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__
|
||||
|
||||
#undef SIZE_MAX
|
||||
#define SIZE_MAX __SIZE_MAX__
|
||||
|
||||
#undef WCHAR_MAX
|
||||
#define WCHAR_MAX __WCHAR_MAX__
|
||||
#undef WCHAR_MIN
|
||||
#define WCHAR_MIN __WCHAR_MIN__
|
||||
|
||||
#undef WINT_MAX
|
||||
#define WINT_MAX __WINT_MAX__
|
||||
#undef WINT_MIN
|
||||
#define WINT_MIN __WINT_MIN__
|
||||
|
||||
#endif /* (!defined __cplusplus || __cplusplus >= 201103L
|
||||
|| defined __STDC_LIMIT_MACROS) */
|
||||
|
||||
#if (!defined __cplusplus || __cplusplus >= 201103L \
|
||||
|| defined __STDC_CONSTANT_MACROS)
|
||||
|
||||
#undef INT8_C
|
||||
#define INT8_C(c) __INT8_C(c)
|
||||
#undef INT16_C
|
||||
#define INT16_C(c) __INT16_C(c)
|
||||
#undef INT32_C
|
||||
#define INT32_C(c) __INT32_C(c)
|
||||
#undef INT64_C
|
||||
#define INT64_C(c) __INT64_C(c)
|
||||
#undef UINT8_C
|
||||
#define UINT8_C(c) __UINT8_C(c)
|
||||
#undef UINT16_C
|
||||
#define UINT16_C(c) __UINT16_C(c)
|
||||
#undef UINT32_C
|
||||
#define UINT32_C(c) __UINT32_C(c)
|
||||
#undef UINT64_C
|
||||
#define UINT64_C(c) __UINT64_C(c)
|
||||
#undef INTMAX_C
|
||||
#define INTMAX_C(c) __INTMAX_C(c)
|
||||
#undef UINTMAX_C
|
||||
#define UINTMAX_C(c) __UINTMAX_C(c)
|
||||
|
||||
#endif /* (!defined __cplusplus || __cplusplus >= 201103L
|
||||
|| defined __STDC_CONSTANT_MACROS) */
|
||||
|
||||
#ifndef __INT_MAX__
|
||||
#define __INT_MAX__ 2147483647
|
||||
#endif
|
||||
#define INT_MIN (-1 - INT_MAX)
|
||||
#define INT_MAX (__INT_MAX__)
|
||||
#define UINT_MAX (INT_MAX * 2U + 1U)
|
||||
|
||||
#define LONG_MAX ((long)(~0UL>>1))
|
||||
#define LONG_MIN (-LONG_MAX - 1)
|
||||
#define ULONG_MAX (~0UL)
|
||||
|
||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef __STDIO_H__
|
||||
#define __STDIO_H__
|
||||
|
||||
#define BUFSIZ 128
|
||||
#define EOF (-1)
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0 /* set file offset to offset */
|
||||
#endif
|
||||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1 /* set file offset to current plus offset */
|
||||
#endif
|
||||
#ifndef SEEK_END
|
||||
#define SEEK_END 2 /* set file offset to EOF plus offset */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-08-14 Bernard the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC)
|
||||
#include "stdlib.h"
|
||||
|
||||
int atoi(const char* s)
|
||||
{
|
||||
long int v=0;
|
||||
int sign=1;
|
||||
while ( *s == ' ' || (unsigned int)(*s - 9) < 5u) s++;
|
||||
switch (*s)
|
||||
{
|
||||
case '-':
|
||||
sign=-1;
|
||||
case '+':
|
||||
++s;
|
||||
}
|
||||
while ((unsigned int) (*s - '0') < 10u)
|
||||
{
|
||||
v=v*10+*s-'0';
|
||||
++s;
|
||||
}
|
||||
return sign==-1?-v:v;
|
||||
}
|
||||
|
||||
long int atol(const char* s)
|
||||
{
|
||||
long int v=0;
|
||||
int sign=0;
|
||||
while ( *s == ' ' || (unsigned int)(*s - 9) < 5u) ++s;
|
||||
switch (*s)
|
||||
{
|
||||
case '-': sign=-1;
|
||||
case '+': ++s;
|
||||
}
|
||||
while ((unsigned int) (*s - '0') < 10u)
|
||||
{
|
||||
v=v*10+*s-'0'; ++s;
|
||||
}
|
||||
return sign?-v:v;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
void *malloc(size_t size)
|
||||
{
|
||||
return rt_malloc(size);
|
||||
}
|
||||
|
||||
void free(void *ptr)
|
||||
{
|
||||
rt_free(ptr);
|
||||
}
|
||||
|
||||
void *realloc(void *ptr, size_t size)
|
||||
{
|
||||
return rt_realloc(ptr, size);
|
||||
}
|
||||
|
||||
void *calloc(size_t nelem, size_t elsize)
|
||||
{
|
||||
return rt_calloc(nelem, elsize);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-08-14 Bernard the first version
|
||||
*/
|
||||
|
||||
#ifndef __STDLIB_H__
|
||||
#define __STDLIB_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC)
|
||||
int atoi(const char *nptr);
|
||||
long int atol(const char *nptr);
|
||||
|
||||
int rand(void);
|
||||
int rand_r(unsigned int *seed);
|
||||
void srand(unsigned int seed);
|
||||
|
||||
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
|
||||
|
||||
void *malloc(size_t size);
|
||||
void free(void *ptr);
|
||||
void *realloc(void *ptr, size_t size);
|
||||
void *calloc(size_t nelem, size_t elsize);
|
||||
void abort(void);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,630 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-08-14 Bernard the first version
|
||||
* 2010-02-15 Gary Lee add strlcpy
|
||||
* 2010-03-17 Bernard add strlcpy implementation to this file.
|
||||
* fix strlcpy declaration
|
||||
* 2010-03-24 Bernard add strchr and strtok implementation.
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC)
|
||||
#include "string.h"
|
||||
|
||||
/* there is no strcpy and strcmp implementation in RT-Thread */
|
||||
char *strcpy(char *dest, const char *src)
|
||||
{
|
||||
return (char *)rt_strncpy(dest, src, rt_strlen(src) + 1);
|
||||
}
|
||||
|
||||
char *strncpy(char *dest, const char *src, size_t siz)
|
||||
{
|
||||
return (char *)rt_strncpy(dest, src, siz);
|
||||
}
|
||||
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
register char *d = dst;
|
||||
register const char *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((*d++ = *s++) == 0) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0)
|
||||
{
|
||||
if (siz != 0) *d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++) ;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
|
||||
int strcmp (const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 && *s1 == *s2)
|
||||
s1++, s2++;
|
||||
return (*s1 - *s2);
|
||||
}
|
||||
|
||||
/**
|
||||
* strncmp - Compare two length-limited strings
|
||||
* @cs: One string
|
||||
* @ct: Another string
|
||||
* @count: The maximum number of bytes to compare
|
||||
*/
|
||||
int strncmp(const char *cs,const char *ct, size_t count)
|
||||
{
|
||||
register signed char __res = 0;
|
||||
|
||||
while (count) {
|
||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
||||
break;
|
||||
count--;
|
||||
}
|
||||
|
||||
return __res;
|
||||
}
|
||||
|
||||
char *strcat(char * dest, const char * src)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *strncat(char *dest, const char *src, size_t count)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
if (count) {
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++)) {
|
||||
if (--count == 0) {
|
||||
*dest = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *strrchr(const char *t, int c)
|
||||
{
|
||||
register char ch;
|
||||
register const char *l=0;
|
||||
|
||||
ch = c;
|
||||
for (;;)
|
||||
{
|
||||
if (*t == ch) l=t;
|
||||
if (!*t) return (char*)l;
|
||||
++t;
|
||||
}
|
||||
|
||||
return (char*)l;
|
||||
}
|
||||
|
||||
|
||||
int strncasecmp ( const char* s1, const char* s2, size_t len )
|
||||
{
|
||||
register unsigned int x2;
|
||||
register unsigned int x1;
|
||||
register const char* end = s1 + len;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((s1 >= end) )
|
||||
return 0;
|
||||
|
||||
x2 = *s2 - 'A'; if ((x2 < 26u)) x2 += 32;
|
||||
x1 = *s1 - 'A'; if ((x1 < 26u)) x1 += 32;
|
||||
s1++; s2++;
|
||||
|
||||
if (x2 != x1)
|
||||
break;
|
||||
|
||||
if (x1 == (unsigned int)-'A')
|
||||
break;
|
||||
}
|
||||
|
||||
return x1 - x2;
|
||||
}
|
||||
|
||||
/* private function */
|
||||
#define isdigit(c) ((unsigned)((c) - '0') < 10)
|
||||
|
||||
rt_inline int divide(int *n, int base)
|
||||
{
|
||||
rt_int32_t res;
|
||||
|
||||
/* optimized for processor which does not support divide instructions. */
|
||||
if (base == 10)
|
||||
{
|
||||
res = ((int)*n) % 10U;
|
||||
*n = ((int)*n) / 10U;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ((int)*n) % 16U;
|
||||
*n = ((int)*n) / 16U;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
rt_inline int skip_atoi(const char **s)
|
||||
{
|
||||
register int i=0;
|
||||
while (isdigit(**s)) i = i*10 + *((*s)++) - '0';
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned char _ctype[] = {
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
|
||||
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
|
||||
_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
|
||||
_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
|
||||
_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
|
||||
_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
|
||||
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
|
||||
_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
|
||||
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
|
||||
_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
|
||||
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
|
||||
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
|
||||
|
||||
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
|
||||
|
||||
#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
|
||||
#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
|
||||
#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
|
||||
#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
|
||||
#define islower(c) ((__ismask(c)&(_L)) != 0)
|
||||
#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
|
||||
#define ispunct(c) ((__ismask(c)&(_P)) != 0)
|
||||
#define isspace(c) ((__ismask(c)&(_S)) != 0)
|
||||
#define isupper(c) ((__ismask(c)&(_U)) != 0)
|
||||
#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
|
||||
|
||||
#define isascii(c) (((unsigned char)(c))<=0x7f)
|
||||
#define toascii(c) (((unsigned char)(c))&0x7f)
|
||||
|
||||
static inline unsigned char __tolower(unsigned char c)
|
||||
{
|
||||
if (isupper(c))
|
||||
c -= 'A'-'a';
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline unsigned char __toupper(unsigned char c)
|
||||
{
|
||||
if (islower(c))
|
||||
c -= 'a'-'A';
|
||||
return c;
|
||||
}
|
||||
|
||||
int tolower(int c)
|
||||
{
|
||||
return __tolower(c);
|
||||
}
|
||||
|
||||
int toupper(int c)
|
||||
{
|
||||
return __toupper(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* simple_strtoul - convert a string to an unsigned long
|
||||
* @cp: The start of the string
|
||||
* @endp: A pointer to the end of the parsed string will be placed here
|
||||
* @base: The number base to use
|
||||
*/
|
||||
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
|
||||
{
|
||||
unsigned long result = 0,value;
|
||||
|
||||
if (!base) {
|
||||
base = 10;
|
||||
if (*cp == '0') {
|
||||
base = 8;
|
||||
cp++;
|
||||
if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
|
||||
cp++;
|
||||
base = 16;
|
||||
}
|
||||
}
|
||||
} else if (base == 16) {
|
||||
if (cp[0] == '0' && toupper(cp[1]) == 'X')
|
||||
cp += 2;
|
||||
}
|
||||
while (isxdigit(*cp) &&
|
||||
(value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
|
||||
result = result*base + value;
|
||||
cp++;
|
||||
}
|
||||
if (endp)
|
||||
*endp = (char *)cp;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* simple_strtol - convert a string to a signed long
|
||||
* @cp: The start of the string
|
||||
* @endp: A pointer to the end of the parsed string will be placed here
|
||||
* @base: The number base to use
|
||||
*/
|
||||
long simple_strtol(const char *cp,char **endp,unsigned int base)
|
||||
{
|
||||
if(*cp=='-')
|
||||
return -simple_strtoul(cp+1,endp,base);
|
||||
return simple_strtoul(cp,endp,base);
|
||||
}
|
||||
|
||||
/**
|
||||
* simple_strtoull - convert a string to an unsigned long long
|
||||
* @cp: The start of the string
|
||||
* @endp: A pointer to the end of the parsed string will be placed here
|
||||
* @base: The number base to use
|
||||
*/
|
||||
unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
|
||||
{
|
||||
unsigned long long result = 0, value;
|
||||
|
||||
if (*cp == '0') {
|
||||
cp++;
|
||||
if ((toupper(*cp) == 'X') && isxdigit (cp[1])) {
|
||||
base = 16;
|
||||
cp++;
|
||||
}
|
||||
if (!base) {
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
if (!base) {
|
||||
base = 10;
|
||||
}
|
||||
while (isxdigit (*cp) && (value = isdigit (*cp)
|
||||
? *cp - '0'
|
||||
: (islower (*cp) ? toupper (*cp) : *cp) - 'A' + 10) < base) {
|
||||
result = result * base + value;
|
||||
cp++;
|
||||
}
|
||||
if (endp)
|
||||
*endp = (char *) cp;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* simple_strtoll - convert a string to a signed long long
|
||||
* @cp: The start of the string
|
||||
* @endp: A pointer to the end of the parsed string will be placed here
|
||||
* @base: The number base to use
|
||||
*/
|
||||
long long simple_strtoll(const char *cp,char **endp,unsigned int base)
|
||||
{
|
||||
if(*cp=='-')
|
||||
return -simple_strtoull(cp+1,endp,base);
|
||||
return simple_strtoull(cp,endp,base);
|
||||
}
|
||||
|
||||
/**
|
||||
* vsscanf - Unformat a buffer into a list of arguments
|
||||
* @buf: input buffer
|
||||
* @fmt: format of buffer
|
||||
* @args: arguments
|
||||
*/
|
||||
int vsscanf(const char * buf, const char * fmt, va_list args)
|
||||
{
|
||||
const char *str = buf;
|
||||
char *next;
|
||||
int num = 0;
|
||||
int qualifier;
|
||||
int base;
|
||||
int field_width = -1;
|
||||
int is_sign = 0;
|
||||
|
||||
while(*fmt && *str) {
|
||||
/* skip any white space in format */
|
||||
/* white space in format matchs any amount of
|
||||
* white space, including none, in the input.
|
||||
*/
|
||||
if (isspace(*fmt)) {
|
||||
while (isspace(*fmt))
|
||||
++fmt;
|
||||
while (isspace(*str))
|
||||
++str;
|
||||
}
|
||||
|
||||
/* anything that is not a conversion must match exactly */
|
||||
if (*fmt != '%' && *fmt) {
|
||||
if (*fmt++ != *str++)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!*fmt)
|
||||
break;
|
||||
++fmt;
|
||||
|
||||
/* skip this conversion.
|
||||
* advance both strings to next white space
|
||||
*/
|
||||
if (*fmt == '*') {
|
||||
while (!isspace(*fmt) && *fmt)
|
||||
fmt++;
|
||||
while (!isspace(*str) && *str)
|
||||
str++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get field width */
|
||||
if (isdigit(*fmt))
|
||||
field_width = skip_atoi(&fmt);
|
||||
|
||||
/* get conversion qualifier */
|
||||
qualifier = -1;
|
||||
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') {
|
||||
qualifier = *fmt;
|
||||
fmt++;
|
||||
}
|
||||
base = 10;
|
||||
is_sign = 0;
|
||||
|
||||
if (!*fmt || !*str)
|
||||
break;
|
||||
|
||||
switch(*fmt++) {
|
||||
case 'c':
|
||||
{
|
||||
char *s = (char *) va_arg(args,char*);
|
||||
if (field_width == -1)
|
||||
field_width = 1;
|
||||
do {
|
||||
*s++ = *str++;
|
||||
} while(field_width-- > 0 && *str);
|
||||
num++;
|
||||
}
|
||||
continue;
|
||||
case 's':
|
||||
{
|
||||
char *s = (char *) va_arg(args, char *);
|
||||
if(field_width == -1)
|
||||
field_width = INT_MAX;
|
||||
/* first, skip leading white space in buffer */
|
||||
while (isspace(*str))
|
||||
str++;
|
||||
|
||||
/* now copy until next white space */
|
||||
while (*str && !isspace(*str) && field_width--) {
|
||||
*s++ = *str++;
|
||||
}
|
||||
*s = '\0';
|
||||
num++;
|
||||
}
|
||||
continue;
|
||||
case 'n':
|
||||
/* return number of characters read so far */
|
||||
{
|
||||
int *i = (int *)va_arg(args,int*);
|
||||
*i = str - buf;
|
||||
}
|
||||
continue;
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
base = 16;
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
is_sign = 1;
|
||||
case 'u':
|
||||
break;
|
||||
case '%':
|
||||
/* looking for '%' in str */
|
||||
if (*str++ != '%')
|
||||
return num;
|
||||
continue;
|
||||
default:
|
||||
/* invalid format; stop here */
|
||||
return num;
|
||||
}
|
||||
|
||||
/* have some sort of integer conversion.
|
||||
* first, skip white space in buffer.
|
||||
*/
|
||||
while (isspace(*str))
|
||||
str++;
|
||||
|
||||
if (!*str || !isdigit(*str))
|
||||
break;
|
||||
|
||||
switch(qualifier) {
|
||||
case 'h':
|
||||
if (is_sign) {
|
||||
short *s = (short *) va_arg(args,short *);
|
||||
*s = (short) simple_strtol(str,&next,base);
|
||||
} else {
|
||||
unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
|
||||
*s = (unsigned short) simple_strtoul(str, &next, base);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (is_sign) {
|
||||
long *l = (long *) va_arg(args,long *);
|
||||
*l = simple_strtol(str,&next,base);
|
||||
} else {
|
||||
unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
|
||||
*l = simple_strtoul(str,&next,base);
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
if (is_sign) {
|
||||
long long *l = (long long*) va_arg(args,long long *);
|
||||
*l = simple_strtoll(str,&next,base);
|
||||
} else {
|
||||
unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
|
||||
*l = simple_strtoull(str,&next,base);
|
||||
}
|
||||
break;
|
||||
case 'Z':
|
||||
{
|
||||
unsigned long *s = (unsigned long*) va_arg(args,unsigned long*);
|
||||
*s = (unsigned long) simple_strtoul(str,&next,base);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (is_sign) {
|
||||
int *i = (int *) va_arg(args, int*);
|
||||
*i = (int) simple_strtol(str,&next,base);
|
||||
} else {
|
||||
unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
|
||||
*i = (unsigned int) simple_strtoul(str,&next,base);
|
||||
}
|
||||
break;
|
||||
}
|
||||
num++;
|
||||
|
||||
if (!next)
|
||||
break;
|
||||
str = next;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* sscanf - Unformat a buffer into a list of arguments
|
||||
* @buf: input buffer
|
||||
* @fmt: formatting of buffer
|
||||
* @...: resulting arguments
|
||||
*/
|
||||
int sscanf(const char * buf, const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args,fmt);
|
||||
i = vsscanf(buf,fmt,args);
|
||||
va_end(args);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
size_t strspn(const char *s, const char *accept)
|
||||
{
|
||||
size_t l=0;
|
||||
int a=1,i, al=strlen(accept);
|
||||
|
||||
while((a)&&(*s))
|
||||
{
|
||||
for(a=i=0;(!a)&&(i<al);i++)
|
||||
if (*s==accept[i]) a=1;
|
||||
if (a) l++;
|
||||
s++;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
size_t strcspn(const char *s, const char *reject)
|
||||
{
|
||||
size_t l=0;
|
||||
int a=1,i,al=strlen(reject);
|
||||
|
||||
while((a)&&(*s))
|
||||
{
|
||||
for(i=0;(a)&&(i<al);i++)
|
||||
if (*s==reject[i]) a=0;
|
||||
if (a) l++;
|
||||
s++;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
char*strtok_r(char*s,const char*delim,char**ptrptr)
|
||||
{
|
||||
char*tmp=0;
|
||||
|
||||
if (s==0) s=*ptrptr;
|
||||
s += strspn(s,delim); /* overread leading delimiter */
|
||||
if (*s)
|
||||
{
|
||||
tmp=s;
|
||||
s+=strcspn(s,delim);
|
||||
|
||||
if (*s) *s++=0; /* not the end ? => terminate it */
|
||||
}
|
||||
*ptrptr=s;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *strtok(char *s, const char *delim)
|
||||
{
|
||||
static char *strtok_pos;
|
||||
return strtok_r(s,delim,&strtok_pos);
|
||||
}
|
||||
|
||||
char *strchr(const char *s1, int i)
|
||||
{
|
||||
const unsigned char *s = (const unsigned char *)s1;
|
||||
unsigned char c = (unsigned int)i;
|
||||
|
||||
while (*s && *s != c)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s != c)
|
||||
{
|
||||
s = NULL;
|
||||
}
|
||||
|
||||
return (char *) s;
|
||||
}
|
||||
|
||||
long strtol(const char *str, char **endptr, int base)
|
||||
{
|
||||
return simple_strtol(str, endptr, base);
|
||||
}
|
||||
|
||||
long long strtoll(const char *str, char **endptr, int base)
|
||||
{
|
||||
return simple_strtoll(str, endptr, base);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-08-14 Bernard the first version
|
||||
*/
|
||||
#ifndef __STRING_H__
|
||||
#define __STRING_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* replace for standard string library */
|
||||
#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC)
|
||||
|
||||
#define ZEROPAD (1 << 0) /* pad with zero */
|
||||
#define SIGN (1 << 1) /* unsigned/signed long */
|
||||
#define PLUS (1 << 2) /* show plus */
|
||||
#define SPACE (1 << 3) /* space if plus */
|
||||
#define LEFT (1 << 4) /* left justified */
|
||||
#define SPECIAL (1 << 5) /* 0x */
|
||||
#define LARGE (1 << 6) /* use 'ABCDEF' instead of 'abcdef' */
|
||||
|
||||
#define _U 0x01 /* upper */
|
||||
#define _L 0x02 /* lower */
|
||||
#define _D 0x04 /* digit */
|
||||
#define _C 0x08 /* cntrl */
|
||||
#define _P 0x10 /* punct */
|
||||
#define _S 0x20 /* white space (space/lf/tab) */
|
||||
#define _X 0x40 /* hex digit */
|
||||
#define _SP 0x80 /* hard space (0x20) */
|
||||
|
||||
void* memset(void *s, int c, size_t n);
|
||||
void* memcpy(void *dest, const void *src, size_t n);
|
||||
void* memmove(void *dest, const void *src, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
|
||||
int tolower(int c);
|
||||
int toupper(int c);
|
||||
|
||||
int strcmp (const char *s1, const char *s2);
|
||||
int strncmp(const char *cs,const char *ct, size_t count);
|
||||
int strcasecmp(const char *a, const char *b);
|
||||
int strncasecmp(const char *cs, const char *ct, size_t count);
|
||||
int sscanf(const char * buf, const char * fmt, ...);
|
||||
size_t strlen(const char *s);
|
||||
char *strstr(const char * s1,const char * s2);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strncpy(char *dest, const char *src, size_t n);
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
char *strncat(char *dest, const char *src, size_t count);
|
||||
char *strcat(char * dest, const char * src);
|
||||
char *strchr(const char *s1, int i);
|
||||
char *strrchr(const char *t, int c);
|
||||
char *strdup(const char *s);
|
||||
char *strtok(char *s, const char *delim);
|
||||
char*strtok_r(char*s, const char*delim, char**ptrptr);
|
||||
|
||||
size_t strcspn(const char *s, const char *reject);
|
||||
size_t strspn (const char *s, const char *accept);
|
||||
|
||||
long strtol(const char *str, char **endptr, int base);
|
||||
long long strtoll(const char *str, char **endptr, int base);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017/11/30 Bernard The first version.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MMAN_H
|
||||
#define _SYS_MMAN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
|
||||
#define MAP_SHARED 0x01
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_TYPE 0x0f
|
||||
#define MAP_FIXED 0x10
|
||||
#define MAP_ANON 0x20
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#define MAP_NORESERVE 0x4000
|
||||
#define MAP_GROWSDOWN 0x0100
|
||||
#define MAP_DENYWRITE 0x0800
|
||||
#define MAP_EXECUTABLE 0x1000
|
||||
#define MAP_LOCKED 0x2000
|
||||
#define MAP_POPULATE 0x8000
|
||||
#define MAP_NONBLOCK 0x10000
|
||||
#define MAP_STACK 0x20000
|
||||
#define MAP_HUGETLB 0x40000
|
||||
#define MAP_FILE 0
|
||||
|
||||
#define PROT_NONE 0
|
||||
#define PROT_READ 1
|
||||
#define PROT_WRITE 2
|
||||
#define PROT_EXEC 4
|
||||
#define PROT_GROWSDOWN 0x01000000
|
||||
#define PROT_GROWSUP 0x02000000
|
||||
|
||||
#define MS_ASYNC 1
|
||||
#define MS_INVALIDATE 2
|
||||
#define MS_SYNC 4
|
||||
|
||||
#define MCL_CURRENT 1
|
||||
#define MCL_FUTURE 2
|
||||
#define MCL_ONFAULT 4
|
||||
|
||||
void *mmap (void *start, size_t len, int prot, int flags, int fd, off_t off);
|
||||
int munmap (void *start, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef __STAT_H__
|
||||
#define __STAT_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef RT_USING_DFS
|
||||
#include <dfs_posix.h>
|
||||
#else
|
||||
#define _FREAD 0x0001 /* read enabled */
|
||||
#define _FWRITE 0x0002 /* write enabled */
|
||||
#define _FAPPEND 0x0008 /* append (writes guaranteed at the end) */
|
||||
#define _FMARK 0x0010 /* internal; mark during gc() */
|
||||
#define _FDEFER 0x0020 /* internal; defer for next gc pass */
|
||||
#define _FASYNC 0x0040 /* signal pgrp when data ready */
|
||||
#define _FSHLOCK 0x0080 /* BSD flock() shared lock present */
|
||||
#define _FEXLOCK 0x0100 /* BSD flock() exclusive lock present */
|
||||
#define _FCREAT 0x0200 /* open with file create */
|
||||
#define _FTRUNC 0x0400 /* open with truncation */
|
||||
#define _FEXCL 0x0800 /* error on open if file exists */
|
||||
#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */
|
||||
#define _FSYNC 0x2000 /* do all writes synchronously */
|
||||
#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */
|
||||
#define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style) */
|
||||
#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */
|
||||
|
||||
#define O_RDONLY 0 /* +1 == FREAD */
|
||||
#define O_WRONLY 1 /* +1 == FWRITE */
|
||||
#define O_RDWR 2 /* +1 == FREAD|FWRITE */
|
||||
#define O_APPEND _FAPPEND
|
||||
#define O_CREAT _FCREAT
|
||||
#define O_TRUNC _FTRUNC
|
||||
#define O_EXCL _FEXCL
|
||||
#define O_SYNC _FSYNC
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef _SYS_TIME_H_
|
||||
#define _SYS_TIME_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
typedef long time_t;
|
||||
|
||||
/*
|
||||
* Structure returned by gettimeofday(2) system call,
|
||||
* and used in other calls.
|
||||
*/
|
||||
struct timeval {
|
||||
long tv_sec; /* seconds */
|
||||
long tv_usec; /* and microseconds */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure defined by POSIX.1b to be like a timeval.
|
||||
*/
|
||||
struct timespec {
|
||||
time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* and nanoseconds */
|
||||
};
|
||||
|
||||
struct timezone {
|
||||
int tz_minuteswest; /* minutes west of Greenwich */
|
||||
int tz_dsttime; /* type of dst correction */
|
||||
};
|
||||
|
||||
struct tm {
|
||||
int tm_sec; /* Seconds. [0-60] (1 leap second) */
|
||||
int tm_min; /* Minutes. [0-59] */
|
||||
int tm_hour; /* Hours. [0-23] */
|
||||
int tm_mday; /* Day. [1-31] */
|
||||
int tm_mon; /* Month. [0-11] */
|
||||
int tm_year; /* Year - 1900. */
|
||||
int tm_wday; /* Day of week. [0-6] */
|
||||
int tm_yday; /* Days in year.[0-365] */
|
||||
int tm_isdst; /* DST. [-1/0/1]*/
|
||||
|
||||
long int tm_gmtoff; /* Seconds east of UTC. */
|
||||
const char *tm_zone; /* Timezone abbreviation. */
|
||||
};
|
||||
|
||||
int gettimeofday(struct timeval *tp, void *ignore);
|
||||
|
||||
#endif
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
#include <rtconfig.h>
|
||||
|
||||
typedef long off_t;
|
||||
|
||||
#ifndef ARCH_CPU_64BIT
|
||||
typedef unsigned int size_t;
|
||||
typedef signed int ssize_t; /* Used for a count of bytes or an error indication. */
|
||||
#else
|
||||
typedef long unsigned int size_t;
|
||||
typedef long signed int ssize_t; /* Used for a count of bytes or an error indication. */
|
||||
#endif
|
||||
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned short u_short;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned long u_long;
|
||||
|
||||
typedef unsigned long clockid_t;
|
||||
typedef int pid_t;
|
||||
|
||||
typedef int gid_t;
|
||||
typedef int uid_t;
|
||||
typedef int dev_t;
|
||||
typedef int ino_t;
|
||||
typedef int mode_t;
|
||||
typedef int caddr_t;
|
||||
|
||||
typedef unsigned int wint_t;
|
||||
typedef unsigned long useconds_t;
|
||||
|
||||
typedef unsigned long clock_t; /* clock() */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL (0)
|
||||
#endif
|
||||
|
||||
#define __u_char_defined
|
||||
|
||||
#endif
|
||||
|
|
@ -1,287 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#include <time.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
/* days per month -- nonleap! */
|
||||
const short __spm[13] =
|
||||
{ 0,
|
||||
(31),
|
||||
(31 + 28),
|
||||
(31 + 28 + 31),
|
||||
(31 + 28 + 31 + 30),
|
||||
(31 + 28 + 31 + 30 + 31),
|
||||
(31 + 28 + 31 + 30 + 31 + 30),
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31),
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31),
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30),
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31),
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30),
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31),
|
||||
};
|
||||
static long int timezone;
|
||||
static const char days[] = "Sun Mon Tue Wed Thu Fri Sat ";
|
||||
static const char months[] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";
|
||||
|
||||
/* seconds per day */
|
||||
#define SPD 24*60*60
|
||||
|
||||
int __isleap(int year)
|
||||
{
|
||||
/* every fourth year is a leap year except for century years that are
|
||||
* not divisible by 400. */
|
||||
/* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
|
||||
return (!(year % 4) && ((year % 100) || !(year % 400)));
|
||||
}
|
||||
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *r)
|
||||
{
|
||||
time_t i;
|
||||
register time_t work = *timep % (SPD);
|
||||
r->tm_sec = work % 60;
|
||||
work /= 60;
|
||||
r->tm_min = work % 60;
|
||||
r->tm_hour = work / 60;
|
||||
work = *timep / (SPD);
|
||||
r->tm_wday = (4 + work) % 7;
|
||||
for (i = 1970;; ++i)
|
||||
{
|
||||
register time_t k = __isleap(i) ? 366 : 365;
|
||||
if (work >= k)
|
||||
work -= k;
|
||||
else
|
||||
break;
|
||||
}
|
||||
r->tm_year = i - 1900;
|
||||
r->tm_yday = work;
|
||||
|
||||
r->tm_mday = 1;
|
||||
if (__isleap(i) && (work > 58))
|
||||
{
|
||||
if (work == 59)
|
||||
r->tm_mday = 2; /* 29.2. */
|
||||
work -= 1;
|
||||
}
|
||||
|
||||
for (i = 11; i && (__spm[i] > work); --i)
|
||||
;
|
||||
r->tm_mon = i;
|
||||
r->tm_mday += work - __spm[i];
|
||||
return r;
|
||||
}
|
||||
|
||||
struct tm* localtime_r(const time_t* t, struct tm* r)
|
||||
{
|
||||
time_t tmp;
|
||||
struct timezone tz = {0};
|
||||
gettimeofday(0, &tz);
|
||||
timezone = tz.tz_minuteswest * 60L;
|
||||
tmp = *t + timezone;
|
||||
return gmtime_r(&tmp, r);
|
||||
}
|
||||
|
||||
struct tm* localtime(const time_t* t)
|
||||
{
|
||||
static struct tm tmp;
|
||||
return localtime_r(t, &tmp);
|
||||
}
|
||||
|
||||
time_t mktime(struct tm * const t)
|
||||
{
|
||||
register time_t day;
|
||||
register time_t i;
|
||||
register time_t years = t->tm_year - 70;
|
||||
|
||||
if (t->tm_sec > 60)
|
||||
{
|
||||
t->tm_min += t->tm_sec / 60;
|
||||
t->tm_sec %= 60;
|
||||
}
|
||||
if (t->tm_min > 60)
|
||||
{
|
||||
t->tm_hour += t->tm_min / 60;
|
||||
t->tm_min %= 60;
|
||||
}
|
||||
if (t->tm_hour > 24)
|
||||
{
|
||||
t->tm_mday += t->tm_hour / 24;
|
||||
t->tm_hour %= 24;
|
||||
}
|
||||
if (t->tm_mon > 12)
|
||||
{
|
||||
t->tm_year += t->tm_mon / 12;
|
||||
t->tm_mon %= 12;
|
||||
}
|
||||
while (t->tm_mday > __spm[1 + t->tm_mon])
|
||||
{
|
||||
if (t->tm_mon == 1 && __isleap(t->tm_year + 1900))
|
||||
{
|
||||
--t->tm_mday;
|
||||
}
|
||||
t->tm_mday -= __spm[t->tm_mon];
|
||||
++t->tm_mon;
|
||||
if (t->tm_mon > 11)
|
||||
{
|
||||
t->tm_mon = 0;
|
||||
++t->tm_year;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->tm_year < 70)
|
||||
return (time_t) - 1;
|
||||
|
||||
/* Days since 1970 is 365 * number of years + number of leap years since 1970 */
|
||||
day = years * 365 + (years + 1) / 4;
|
||||
|
||||
/* After 2100 we have to substract 3 leap years for every 400 years
|
||||
This is not intuitive. Most mktime implementations do not support
|
||||
dates after 2059, anyway, so we might leave this out for it's
|
||||
bloat. */
|
||||
if (years >= 131)
|
||||
{
|
||||
years -= 131;
|
||||
years /= 100;
|
||||
day -= (years >> 2) * 3 + 1;
|
||||
if ((years &= 3) == 3)
|
||||
years--;
|
||||
day -= years;
|
||||
}
|
||||
|
||||
day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 +
|
||||
(__isleap(t->tm_year + 1900) & (t->tm_mon > 1));
|
||||
|
||||
/* day is now the number of days since 'Jan 1 1970' */
|
||||
i = 7;
|
||||
t->tm_wday = (day + 4) % i; /* Sunday=0, Monday=1, ..., Saturday=6 */
|
||||
|
||||
i = 24;
|
||||
day *= i;
|
||||
i = 60;
|
||||
return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec;
|
||||
}
|
||||
|
||||
static void num2str(char *c, int i)
|
||||
{
|
||||
c[0] = i / 10 + '0';
|
||||
c[1] = i % 10 + '0';
|
||||
}
|
||||
|
||||
char *asctime_r(const struct tm *t, char *buf)
|
||||
{
|
||||
/* "Wed Jun 30 21:49:08 1993\n" */
|
||||
*(int*) buf = *(int*) (days + (t->tm_wday << 2));
|
||||
*(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2));
|
||||
num2str(buf + 8, t->tm_mday);
|
||||
if (buf[8] == '0')
|
||||
buf[8] = ' ';
|
||||
buf[10] = ' ';
|
||||
num2str(buf + 11, t->tm_hour);
|
||||
buf[13] = ':';
|
||||
num2str(buf + 14, t->tm_min);
|
||||
buf[16] = ':';
|
||||
num2str(buf + 17, t->tm_sec);
|
||||
buf[19] = ' ';
|
||||
num2str(buf + 20, (t->tm_year + 1900) / 100);
|
||||
num2str(buf + 22, (t->tm_year + 1900) % 100);
|
||||
buf[24] = '\n';
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *asctime(const struct tm *timeptr)
|
||||
{
|
||||
static char buf[25];
|
||||
return asctime_r(timeptr, buf);
|
||||
}
|
||||
|
||||
char *ctime(const time_t *timep)
|
||||
{
|
||||
return asctime(localtime(timep));
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE
|
||||
int gettimeofday(struct timeval *tp, void *ignore)
|
||||
{
|
||||
time_t time;
|
||||
rt_device_t device;
|
||||
|
||||
device = rt_device_find("rtc");
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
|
||||
if (tp != RT_NULL)
|
||||
{
|
||||
tp->tv_sec = time;
|
||||
tp->tv_usec = 0;
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _gettimeofday
|
||||
/* Dummy function when hardware do not have RTC */
|
||||
int _gettimeofday( struct timeval *tv, void *ignore)
|
||||
{
|
||||
tv->tv_sec = 0; // convert to seconds
|
||||
tv->tv_usec = 0; // get remaining microseconds
|
||||
return 0; // return non-zero for error
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the current time.
|
||||
*
|
||||
* @param time_t * t the timestamp pointer, if not used, keep NULL.
|
||||
*
|
||||
* @return time_t return timestamp current.
|
||||
*
|
||||
*/
|
||||
/* for IAR 6.2 later Compiler */
|
||||
#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000
|
||||
#pragma module_name = "?time"
|
||||
time_t (__time32)(time_t *t) /* Only supports 32-bit timestamp */
|
||||
#else
|
||||
time_t time(time_t *t)
|
||||
#endif
|
||||
{
|
||||
time_t time_now = 0;
|
||||
|
||||
#ifdef RT_USING_RTC
|
||||
static rt_device_t device = RT_NULL;
|
||||
|
||||
/* optimization: find rtc device only first. */
|
||||
if (device == RT_NULL)
|
||||
{
|
||||
device = rt_device_find("rtc");
|
||||
}
|
||||
|
||||
/* read timestamp from RTC device. */
|
||||
if (device != RT_NULL)
|
||||
{
|
||||
if (rt_device_open(device, 0) == RT_EOK)
|
||||
{
|
||||
rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now);
|
||||
rt_device_close(device);
|
||||
}
|
||||
}
|
||||
#endif /* RT_USING_RTC */
|
||||
|
||||
/* if t is not NULL, write timestamp to *t */
|
||||
if (t != RT_NULL)
|
||||
{
|
||||
*t = time_now;
|
||||
}
|
||||
|
||||
return time_now;
|
||||
}
|
||||
|
||||
RT_WEAK clock_t clock(void)
|
||||
{
|
||||
return rt_tick_get();
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#ifndef __TIME_H__
|
||||
#define __TIME_H__
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
time_t mktime(struct tm * const t);
|
||||
|
||||
char *asctime(const struct tm *timeptr);
|
||||
char *ctime(const time_t *timep);
|
||||
struct tm* localtime(const time_t* t);
|
||||
|
||||
char *asctime_r(const struct tm *t, char *buf);
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *r);
|
||||
struct tm* localtime_r(const time_t* t, struct tm* r);
|
||||
|
||||
#endif
|
|
@ -1,21 +1,30 @@
|
|||
from building import *
|
||||
Import('rtconfig')
|
||||
|
||||
src = Glob('*.c')
|
||||
src = []
|
||||
cwd = GetCurrentDir()
|
||||
group = []
|
||||
|
||||
CPPPATH = [cwd]
|
||||
CPPDEFINES = ['RT_USING_NEWLIB']
|
||||
|
||||
# link with libc and libm:
|
||||
# libm is a frequently used lib. Newlib is compiled with -ffunction-sections in
|
||||
# recent GCC tool chains. The linker would just link in the functions that have
|
||||
# been referenced. So setting this won't result in bigger text size.
|
||||
LIBS = ['c', 'm']
|
||||
|
||||
if rtconfig.PLATFORM == 'gcc':
|
||||
group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'],
|
||||
CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES, LIBS = LIBS)
|
||||
if GetDepend('RT_USING_LIBC'):
|
||||
CPPDEFINES = ['RT_USING_NEWLIB']
|
||||
# link with libc and libm:
|
||||
# libm is a frequently used lib. Newlib is compiled with -ffunction-sections in
|
||||
# recent GCC tool chains. The linker would just link in the functions that have
|
||||
# been referenced. So setting this won't result in bigger text size.
|
||||
LIBS = ['c', 'm']
|
||||
|
||||
src += Glob('*.c')
|
||||
SrcRemove(src, ['minilib.c'])
|
||||
if GetDepend('RT_USING_MODULE') == False:
|
||||
SrcRemove(src, ['libc_syms.c'])
|
||||
else:
|
||||
src += ['minilib.c']
|
||||
CPPDEFINES = []
|
||||
LIBS = []
|
||||
|
||||
group = DefineGroup('libc', src, depend = [], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES, LIBS = LIBS)
|
||||
|
||||
Return('group')
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-02-23 Meco Man first version
|
||||
*/
|
||||
|
||||
#include <reent.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
void * _sbrk_r(struct _reent *ptr, ptrdiff_t incr)
|
||||
{
|
||||
/* no use this routine to get memory */
|
||||
return RT_NULL;
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
* 2021-02-11 Meco Man remove _gettimeofday_r() and _times_r()
|
||||
* 2020-02-13 Meco Man re-implement exit() and abort()
|
||||
* 2020-02-21 Meco Man improve and beautify syscalls
|
||||
* 2020-02-24 Meco Man fix bug of _isatty_r()
|
||||
*/
|
||||
|
||||
#include <reent.h>
|
||||
|
@ -89,12 +90,14 @@ int
|
|||
_isatty_r(struct _reent *ptr, int fd)
|
||||
{
|
||||
if (fd >=0 && fd < 3)
|
||||
{
|
||||
return 1;
|
||||
|
||||
ptr->_errno = ENOTTY ;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_kill_r(struct _reent *ptr, int pid, int sig)
|
||||
{
|
||||
|
|
|
@ -66,7 +66,7 @@ typedef uintptr_t mem_ptr_t;
|
|||
#endif /* __CC_ARM/__IAR_SYSTEMS_ICC__ */
|
||||
#endif
|
||||
|
||||
#if defined(RT_USING_LIBC) || defined(RT_USING_MINILIBC) || defined(RT_LIBC_USING_TIME) || (defined( __GNUC__ ) && !defined(__ARMCC_VERSION))
|
||||
#if defined(RT_USING_LIBC) || defined(RT_LIBC_USING_TIME) || (defined( __GNUC__ ) && !defined(__ARMCC_VERSION))
|
||||
#include <sys/time.h>
|
||||
#define LWIP_TIMEVAL_PRIVATE 0
|
||||
#else
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#define S32_F "ld"
|
||||
#define X32_F "lx"
|
||||
|
||||
#if defined(RT_USING_LIBC) || defined(RT_USING_MINILIBC) || defined(RT_LIBC_USING_TIME) || (defined( __GNUC__ ) && !defined(__ARMCC_VERSION))
|
||||
#if defined(RT_USING_LIBC) || defined(RT_LIBC_USING_TIME) || (defined( __GNUC__ ) && !defined(__ARMCC_VERSION))
|
||||
#include <sys/time.h>
|
||||
#define LWIP_TIMEVAL_PRIVATE 0
|
||||
#else
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#endif /* __CC_ARM/__IAR_SYSTEMS_ICC__ */
|
||||
#endif /* RT_USING_LIBC */
|
||||
|
||||
#if defined(RT_USING_LIBC) || defined(RT_USING_MINILIBC) || defined(RT_LIBC_USING_TIME) || (defined( __GNUC__ ) && !defined(__ARMCC_VERSION))
|
||||
#if defined(RT_USING_LIBC) || defined(RT_LIBC_USING_TIME) || (defined( __GNUC__ ) && !defined(__ARMCC_VERSION))
|
||||
#include <sys/time.h>
|
||||
#define LWIP_TIMEVAL_PRIVATE 0
|
||||
#else
|
||||
|
|
|
@ -77,6 +77,14 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data)
|
|||
netdev->status_callback = RT_NULL;
|
||||
netdev->addr_callback = RT_NULL;
|
||||
|
||||
if(rt_strlen(name) > RT_NAME_MAX)
|
||||
{
|
||||
char netdev_name[RT_NAME_MAX + 1] = {0};
|
||||
|
||||
rt_strncpy(netdev_name, name, RT_NAME_MAX);
|
||||
LOG_E("netdev name[%s] length is so long that have been cut into [%s].", name, netdev_name);
|
||||
}
|
||||
|
||||
/* fill network interface device */
|
||||
rt_strncpy(netdev->name, name, RT_NAME_MAX);
|
||||
netdev->user_data = user_data;
|
||||
|
@ -260,7 +268,7 @@ struct netdev *netdev_get_by_name(const char *name)
|
|||
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
|
||||
{
|
||||
netdev = rt_slist_entry(node, struct netdev, list);
|
||||
if (netdev && (rt_strncmp(netdev->name, name, RT_NAME_MAX) == 0))
|
||||
if (netdev && (rt_strncmp(netdev->name, name, rt_strlen(netdev->name) < RT_NAME_MAX ? rt_strlen(netdev->name) : RT_NAME_MAX) == 0))
|
||||
{
|
||||
rt_hw_interrupt_enable(level);
|
||||
return netdev;
|
||||
|
|
|
@ -1386,26 +1386,4 @@ void rt_assert_handler(const char *ex_string, const char *func, rt_size_t line)
|
|||
RTM_EXPORT(rt_assert_handler);
|
||||
#endif /* RT_DEBUG */
|
||||
|
||||
#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) && defined (__GNUC__)
|
||||
#include <sys/types.h>
|
||||
void *memcpy(void *dest, const void *src, size_t n) __attribute__((weak, alias("rt_memcpy")));
|
||||
void *memset(void *s, int c, size_t n) __attribute__((weak, alias("rt_memset")));
|
||||
void *memmove(void *dest, const void *src, size_t n) __attribute__((weak, alias("rt_memmove")));
|
||||
int memcmp(const void *s1, const void *s2, size_t n) __attribute__((weak, alias("rt_memcmp")));
|
||||
|
||||
size_t strlen(const char *s) __attribute__((weak, alias("rt_strlen")));
|
||||
char *strstr(const char *s1, const char *s2) __attribute__((weak, alias("rt_strstr")));
|
||||
int strcasecmp(const char *a, const char *b) __attribute__((weak, alias("rt_strcasecmp")));
|
||||
char *strncpy(char *dest, const char *src, size_t n) __attribute__((weak, alias("rt_strncpy")));
|
||||
int strncmp(const char *cs, const char *ct, size_t count) __attribute__((weak, alias("rt_strncmp")));
|
||||
#ifdef RT_USING_HEAP
|
||||
char *strdup(const char *s) __attribute__((weak, alias("rt_strdup")));
|
||||
#endif
|
||||
|
||||
int sprintf(char *buf, const char *format, ...) __attribute__((weak, alias("rt_sprintf")));
|
||||
int snprintf(char *buf, rt_size_t size, const char *fmt, ...) __attribute__((weak, alias("rt_snprintf")));
|
||||
int vsprintf(char *buf, const char *format, va_list arg_ptr) __attribute__((weak, alias("rt_vsprintf")));
|
||||
|
||||
#endif
|
||||
|
||||
/**@}*/
|
||||
|
|
15
src/thread.c
15
src/thread.c
|
@ -382,19 +382,8 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
|
|||
/* change stat */
|
||||
thread->stat = RT_THREAD_CLOSE;
|
||||
|
||||
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
|
||||
{
|
||||
rt_object_detach((rt_object_t)thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* disable interrupt */
|
||||
lock = rt_hw_interrupt_disable();
|
||||
/* insert to defunct thread list */
|
||||
rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(lock);
|
||||
}
|
||||
/* detach thread object */
|
||||
rt_object_detach((rt_object_t)thread);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ rt_err_t rt_timer_detach(rt_timer_t timer)
|
|||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
rt_object_detach((rt_object_t)timer);
|
||||
rt_object_detach(&(timer->parent));
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue