update components & lwp. (#7888)

This commit is contained in:
geniusgogo 2023-08-08 00:22:14 +08:00 committed by GitHub
parent 7e7b303dd4
commit 4d20416b2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 969 additions and 81 deletions

View File

@ -10,6 +10,7 @@
#include <rtthread.h>
#include <dfs_fs.h>
#include <dfs_file.h>
#include <drivers/mmcsd_core.h>
#include <drivers/gpt.h>
@ -25,6 +26,8 @@
static rt_list_t blk_devices = RT_LIST_OBJECT_INIT(blk_devices);
#define BLK_MIN(a, b) ((a) < (b) ? (a) : (b))
#define RT_DEVICE_CTRL_BLK_SSIZEGET 0x1268 /**< get number of bytes per sector */
#define RT_DEVICE_CTRL_ALL_BLK_SSIZEGET 0x80081272 /**< get number of bytes per sector * sector counts*/
struct mmcsd_blk_device
{
@ -267,6 +270,7 @@ static rt_err_t rt_mmcsd_close(rt_device_t dev)
static rt_err_t rt_mmcsd_control(rt_device_t dev, int cmd, void *args)
{
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_BLK_GETGEOME:
@ -274,6 +278,16 @@ static rt_err_t rt_mmcsd_control(rt_device_t dev, int cmd, void *args)
break;
case RT_DEVICE_CTRL_BLK_PARTITION:
rt_memcpy(args, &blk_dev->part, sizeof(struct dfs_partition));
break;
case RT_DEVICE_CTRL_BLK_SSIZEGET:
rt_memcpy(args, &blk_dev->geometry.bytes_per_sector, sizeof(rt_uint32_t));
break;
case RT_DEVICE_CTRL_ALL_BLK_SSIZEGET:
{
rt_uint64_t count_mul_per = blk_dev->geometry.bytes_per_sector * blk_dev->geometry.sector_count;
rt_memcpy(args, &count_mul_per, sizeof(rt_uint64_t));
}
break;
default:
break;
}
@ -414,6 +428,207 @@ const static struct rt_device_ops mmcsd_blk_ops =
};
#endif
#ifdef RT_USING_DFS_V2
static ssize_t rt_mmcsd_fops_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
{
int result = 0;
rt_device_t dev = (rt_device_t)file->vnode->data;
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
int bytes_per_sector = blk_dev->geometry.bytes_per_sector;
int blk_pos = *pos / bytes_per_sector;
int first_offs = *pos % bytes_per_sector;
char *rbuf;
int rsize = 0;
rbuf = rt_malloc(bytes_per_sector);
if (!rbuf)
{
return 0;
}
/*
** #1: read first unalign block size.
*/
result = rt_mmcsd_read(dev, blk_pos, rbuf, 1);
if (result != 1)
{
rt_free(rbuf);
return 0;
}
if (count > bytes_per_sector - first_offs)
{
rsize = bytes_per_sector - first_offs;
}
else
{
rsize = count;
}
rt_memcpy(buf, rbuf + first_offs, rsize);
blk_pos++;
/*
** #2: read continuous block size.
*/
while (rsize < count)
{
result = rt_mmcsd_read(dev, blk_pos++, rbuf, 1);
if (result != 1)
{
break;
}
if (count - rsize >= bytes_per_sector)
{
rt_memcpy(buf + rsize, rbuf, bytes_per_sector);
rsize += bytes_per_sector;
}
else
{
rt_memcpy(buf + rsize, rbuf, count - rsize);
rsize = count;
}
}
rt_free(rbuf);
*pos += rsize;
return rsize;
}
static int rt_mmcsd_fops_ioctl(struct dfs_file *file, int cmd, void *arg)
{
rt_device_t dev = (rt_device_t)file->vnode->data;
return rt_mmcsd_control(dev,cmd,arg);
}
static int rt_mmcsd_fops_open(struct dfs_file *file)
{
rt_device_t dev = (rt_device_t)file->vnode->data;
rt_mmcsd_control(dev, RT_DEVICE_CTRL_ALL_BLK_SSIZEGET, &file->vnode->size);
return RT_EOK;
}
static int rt_mmcsd_fops_close(struct dfs_file *file)
{
return RT_EOK;
}
static ssize_t rt_mmcsd_fops_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
{
int result = 0;
rt_device_t dev = (rt_device_t)file->vnode->data;
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
int bytes_per_sector = blk_dev->geometry.bytes_per_sector;
int blk_pos = *pos / bytes_per_sector;
int first_offs = *pos % bytes_per_sector;
char *rbuf = 0;
int wsize = 0;
/*
** #1: write first unalign block size.
*/
if (first_offs != 0)
{
if (count > bytes_per_sector - first_offs)
{
wsize = bytes_per_sector - first_offs;
}
else
{
wsize = count;
}
rbuf = rt_malloc(bytes_per_sector);
if (!rbuf)
{
return 0;
}
result = rt_mmcsd_read(dev, blk_pos, rbuf, 1);
if (result != 1)
{
rt_free(rbuf);
return 0;
}
rt_memcpy(rbuf + first_offs, buf, wsize);
result = rt_mmcsd_write(dev, blk_pos, rbuf, 1);
if (result != 1)
{
rt_free(rbuf);
return 0;
}
rt_free(rbuf);
blk_pos += 1;
}
/*
** #2: write continuous block size.
*/
if ((count - wsize) / bytes_per_sector != 0)
{
result = rt_mmcsd_write(dev, blk_pos, buf + wsize, (count - wsize) / bytes_per_sector);
wsize += result * bytes_per_sector;
blk_pos += result;
if (result != (count - wsize) / bytes_per_sector)
{
*pos += wsize;
return wsize;
}
}
/*
** # 3: write last unalign block size.
*/
if ((count - wsize) != 0)
{
rbuf = rt_malloc(bytes_per_sector);
if (rbuf != RT_NULL)
{
result = rt_mmcsd_read(dev, blk_pos, rbuf, 1);
if (result == 1)
{
rt_memcpy(rbuf, buf + wsize, count - wsize);
result = rt_mmcsd_write(dev, blk_pos, rbuf, 1);
if (result == 1)
{
wsize += count - wsize;
}
}
rt_free(rbuf);
}
}
*pos += wsize;
return wsize;
}
static int rt_mmcsd_fops_poll(struct dfs_file *file, struct rt_pollreq *req)
{
int mask = 0;
return mask;
}
const static struct dfs_file_ops mmcsd_blk_fops =
{
rt_mmcsd_fops_open,
rt_mmcsd_fops_close,
rt_mmcsd_fops_ioctl,
rt_mmcsd_fops_read,
rt_mmcsd_fops_write,
RT_NULL,
generic_dfs_lseek,
RT_NULL,
RT_NULL,
rt_mmcsd_fops_poll
};
#endif
rt_int32_t gpt_device_probe(struct rt_mmcsd_card *card)
{
rt_int32_t err = RT_EOK;
@ -460,6 +675,11 @@ rt_int32_t gpt_device_probe(struct rt_mmcsd_card *card)
rt_device_register(&(blk_dev->dev), card->host->name,
RT_DEVICE_FLAG_RDWR);
#ifdef RT_USING_POSIX_DEVIO
#ifdef RT_USING_DFS_V2
blk_dev->dev.fops = &mmcsd_blk_fops;
#endif
#endif
rt_list_insert_after(&blk_devices, &blk_dev->list);
for (i = 0; i < RT_GPT_PARTITION_MAX; i++)
@ -505,6 +725,11 @@ rt_int32_t gpt_device_probe(struct rt_mmcsd_card *card)
rt_device_register(&(blk_dev->dev), dname,
RT_DEVICE_FLAG_RDWR);
#ifdef RT_USING_POSIX_DEVIO
#ifdef RT_USING_DFS_V2
blk_dev->dev.fops = &mmcsd_blk_fops;
#endif
#endif
rt_list_insert_after(&blk_devices, &blk_dev->list);
}
else

View File

@ -159,18 +159,25 @@ long list_thread(void)
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t *)RT_NULL;
const char *item_title = "thread";
const size_t tcb_strlen = sizeof(void *) * 2 + 2;
int maxlen;
list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.*s ", tcb_strlen, tcb_strlen, "rt_thread_t");
#ifdef RT_USING_SMP
rt_kprintf("%-*.*s cpu bind pri status sp stack size max used left tick error\n", maxlen, maxlen, item_title);
object_split(tcb_strlen);
rt_kprintf(" ");
object_split(maxlen);
rt_kprintf(" --- ---- --- ------- ---------- ---------- ------ ---------- ---\n");
#else
rt_kprintf("%-*.*s pri status sp stack size max used left tick error\n", maxlen, maxlen, item_title);
object_split(tcb_strlen);
rt_kprintf(" ");
object_split(maxlen);
rt_kprintf(" --- ------- ---------- ---------- ------ ---------- ---\n");
#endif /*RT_USING_SMP*/
@ -202,6 +209,7 @@ long list_thread(void)
rt_uint8_t stat;
rt_uint8_t *ptr;
rt_kprintf("%p ", thread);
#ifdef RT_USING_SMP
if (thread->oncpu != RT_CPU_DETACHED)
rt_kprintf("%-*.*s %3d %3d %4d ", maxlen, RT_NAME_MAX, thread->parent.name, thread->oncpu, thread->bind_cpu, thread->current_priority);

View File

@ -618,6 +618,7 @@ MSH_CMD_EXPORT_ALIAS(cmd_mount, mount, mount <device> <mountpoint> <fstype>);
/* unmount the filesystem from the specified mountpoint */
static int cmd_umount(int argc, char **argv)
{
#ifndef RT_USING_DFS_V2
char *path = argv[1];
if (argc != 2)
@ -637,6 +638,34 @@ static int cmd_umount(int argc, char **argv)
rt_kprintf("succeed!\n");
return 0;
}
#else
int flags = 0;
char *path = argv[1];
if (argc < 2)
{
rt_kprintf("Usage: unmount [-f] <mountpoint>.\n");
return -1;
}
if (argc > 2)
{
flags = strcmp(argv[1], "-f") == 0 ? MNT_FORCE : 0;
path = argv[2];
}
rt_kprintf("unmount %s ... ", path);
if (dfs_umount(path, flags) < 0)
{
rt_kprintf("failed!\n");
return -1;
}
else
{
rt_kprintf("succeed!\n");
return 0;
}
#endif
}
MSH_CMD_EXPORT_ALIAS(cmd_umount, umount, Unmount the mountpoint);

View File

@ -30,39 +30,20 @@ int libc_system_init(void)
dev_console = rt_console_get_device();
if (dev_console)
{
int fd, ret;
char name[STDIO_DEVICE_NAME_MAX];
rt_snprintf(name, sizeof(name) - 1, "/dev/%s", dev_console->parent.name);
name[STDIO_DEVICE_NAME_MAX - 1] = '\0';
fd = open(name, O_RDWR);
if (fd >= 0)
{
/* set fd (0, 1, 2) */
ret = sys_dup2(fd, 0);
if (ret != fd)
{
close(fd);
}
sys_dup2(ret, 1);
sys_dup2(ret, 2);
ret = libc_stdio_set_console(dev_console->parent.name, O_RDWR);
if (ret < 0)
{
return -1;
}
}
else
int fd = libc_stdio_set_console(dev_console->parent.name, O_RDWR);
if (fd < 0)
{
return -1;
}
/* set fd (0, 1, 2) */
sys_dup2(fd, 0);
sys_dup2(fd, 1);
sys_dup2(fd, 2);
}
#endif /* RT_USING_POSIX_STDIO */
return 0;
}
INIT_APP_EXPORT(libc_system_init);
INIT_ENV_EXPORT(libc_system_init);
#if defined(RT_USING_POSIX_STDIO) && defined(RT_USING_NEWLIBC)

View File

@ -1403,3 +1403,17 @@ void lwp_user_setting_restore(rt_thread_t thread)
}
}
#endif /* ARCH_MM_MMU */
void lwp_uthread_ctx_save(void *ctx)
{
rt_thread_t thread;
thread = rt_thread_self();
thread->user_ctx.ctx = ctx;
}
void lwp_uthread_ctx_restore(void)
{
rt_thread_t thread;
thread = rt_thread_self();
thread->user_ctx.ctx = RT_NULL;
}

View File

@ -164,6 +164,10 @@ void lwp_aspace_switch(struct rt_thread *thread);
#endif
void lwp_user_setting_save(rt_thread_t thread);
void lwp_user_setting_restore(rt_thread_t thread);
void lwp_uthread_ctx_save(void *ctx);
void lwp_uthread_ctx_restore(void);
int lwp_setaffinity(pid_t pid, int cpu);
/* ctime lwp API */

View File

@ -980,6 +980,7 @@ int lwp_channel_open(int fdt_type, const char *name, int flags)
{
/* initialize vnode */
dfs_vnode_init(d->vnode, FT_USER, &channel_fops);
d->flags = O_RDWR; /* set flags as read and write */
/* set socket to the data of dfs_file */
d->vnode->data = (void *)ch;

View File

@ -106,6 +106,11 @@ static void lwp_pid_put(pid_t pid)
rt_base_t level;
struct lwp_avl_struct *p;
if (pid == 0)
{
return;
}
level = rt_hw_interrupt_disable();
p = lwp_avl_find(pid, lwp_pid_root);
if (p)

View File

@ -94,4 +94,43 @@
#define INTF_IPV6_V6ONLY 26
#define IMPL_IPV6_V6ONLY 27
struct musl_sockaddr
{
uint16_t sa_family;
char sa_data[14];
};
struct musl_ifmap {
unsigned long int mem_start;
unsigned long int mem_end;
unsigned short int base_addr;
unsigned char irq;
unsigned char dma;
unsigned char port;
};
struct musl_ifreq
{
union
{
#define IFNAMSIZ 16
char ifrn_name[IFNAMSIZ];
} ifr_ifrn;
union
{
struct musl_sockaddr ifru_addr;
struct musl_sockaddr ifru_dstaddr;
struct musl_sockaddr ifru_broadaddr;
struct musl_sockaddr ifru_netmask;
struct musl_sockaddr ifru_hwaddr;
short int ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct musl_ifmap ifru_map;
char ifru_slave[IFNAMSIZ];
char ifru_newname[IFNAMSIZ];
char *ifru_data;
} ifr_ifru;
};
#endif /* __LWP_SYS_SOCKET_H__ */

View File

@ -103,12 +103,6 @@
#error "No definition RT_USING_POSIX_CLOCK"
#endif /* RT_USING_POSIX_CLOCK */
struct musl_sockaddr
{
uint16_t sa_family;
char sa_data[14];
};
void lwp_cleanup(struct rt_thread *tid);
#ifdef ARCH_MM_MMU
@ -551,7 +545,7 @@ sysret_t sys_open(const char *name, int flag, ...)
#endif
}
/* syscall: "open" ret: "int" args: "const char *" "mode_t" "mode" */
/* syscall: "openat" ret: "int" args: "const char *" "mode_t" "mode" */
sysret_t sys_openat(int dirfd, const char *name, int flag, mode_t mode)
{
#ifdef ARCH_MM_MMU
@ -4684,6 +4678,12 @@ sysret_t sys_sched_setparam(pid_t pid, void *param)
return ret;
}
sysret_t sys_sched_yield(void)
{
rt_thread_yield();
return 0;
}
sysret_t sys_sched_getparam(pid_t pid, void *param)
{
struct sched_param *sched_param = (struct sched_param *)param;
@ -5378,7 +5378,154 @@ sysret_t sys_epoll_pwait(int fd,
return (ret < 0 ? GET_ERRNO() : ret);
}
static const struct rt_syscall_def func_table[] =
sysret_t sys_chmod(const char *fileName, mode_t mode)
{
char *copy_fileName;
size_t len_fileName, copy_len_fileName;
int err_fileName;
#ifdef RT_USING_DFS_V2
struct dfs_attr attr;
attr.st_mode = mode;
#endif
int ret = 0;
len_fileName = lwp_user_strlen(fileName, &err_fileName);
if (err_fileName)
{
return -EFAULT;
}
copy_fileName = (char*)rt_malloc(len_fileName + 1);
if (!copy_fileName)
{
return -ENOMEM;
}
copy_len_fileName = lwp_get_from_user(copy_fileName, (void *)fileName, len_fileName);
copy_fileName[copy_len_fileName] = '\0';
#ifdef RT_USING_DFS_V2
ret = dfs_file_setattr(copy_fileName, &attr);
#else
SET_ERRNO(EFAULT);
#endif
rt_free(copy_fileName);
return (ret < 0 ? GET_ERRNO() : ret);
}
sysret_t sys_reboot(int magic)
{
rt_hw_cpu_reset();
return 0;
}
ssize_t sys_pread64(int fd, void *buf, int size, off_t offset)
#ifdef RT_USING_DFS_V2
{
ssize_t pread(int fd, void *buf, size_t len, off_t offset);
#ifdef ARCH_MM_MMU
ssize_t ret = -1;
void *kmem = RT_NULL;
if (!size)
{
return -EINVAL;
}
if (!lwp_user_accessable((void *)buf, size))
{
return -EFAULT;
}
kmem = kmem_get(size);
if (!kmem)
{
return -ENOMEM;
}
ret = pread(fd, kmem, size, offset);
if (ret > 0)
{
lwp_put_to_user(buf, kmem, ret);
}
if (ret < 0)
{
ret = GET_ERRNO();
}
kmem_put(kmem);
return ret;
#else
if (!lwp_user_accessable((void *)buf, size))
{
return -EFAULT;
}
ssize_t ret = pread(fd, kmem, size, offset);
return (ret < 0 ? GET_ERRNO() : ret);
#endif
}
#else
{
ssize_t ret = -ENOSYS;
return (ret < 0 ? GET_ERRNO() : ret);
}
#endif
ssize_t sys_pwrite64(int fd, void *buf, int size, off_t offset)
#ifdef RT_USING_DFS_V2
{
ssize_t pwrite(int fd, const void *buf, size_t len, off_t offset);
#ifdef ARCH_MM_MMU
ssize_t ret = -1;
void *kmem = RT_NULL;
if (!size)
{
return -EINVAL;
}
if (!lwp_user_accessable((void *)buf, size))
{
return -EFAULT;
}
kmem = kmem_get(size);
if (!kmem)
{
return -ENOMEM;
}
lwp_get_from_user(kmem, (void *)buf, size);
ret = pwrite(fd, kmem, size, offset);
if (ret < 0)
{
ret = GET_ERRNO();
}
kmem_put(kmem);
return ret;
#else
if (!lwp_user_accessable((void *)buf, size))
{
return -EFAULT;
}
ssize_t ret = pwrite(fd, kmem, size, offset);
return (ret < 0 ? GET_ERRNO() : ret);
#endif
}
#else
{
ssize_t ret = -ENOSYS;
return (ret < 0 ? GET_ERRNO() : ret);
}
#endif
const static struct rt_syscall_def func_table[] =
{
SYSCALL_SIGN(sys_exit), /* 01 */
SYSCALL_SIGN(sys_read),
@ -5600,11 +5747,11 @@ static const struct rt_syscall_def func_table[] =
SYSCALL_SIGN(sys_symlink),
SYSCALL_SIGN(sys_getaffinity), /* 180 */
SYSCALL_SIGN(sys_sysinfo),
SYSCALL_SIGN(sys_notimpl),
SYSCALL_SIGN(sys_notimpl),
SYSCALL_SIGN(sys_notimpl),
SYSCALL_SIGN(sys_notimpl), /* 185 */
SYSCALL_SIGN(sys_notimpl),
SYSCALL_SIGN(sys_chmod),
SYSCALL_SIGN(sys_reboot),
SYSCALL_SIGN(sys_sched_yield),
SYSCALL_SIGN(sys_pread64), /* 185 */
SYSCALL_SIGN(sys_pwrite64),
SYSCALL_SIGN(sys_sigpending),
SYSCALL_SIGN(sys_sigtimedwait),
SYSCALL_SIGN(sys_notimpl),
@ -5632,7 +5779,10 @@ const void *lwp_get_sys_api(rt_uint32_t number)
}
else
{
LOG_I("Unimplement syscall %d", number);
if (__sys_log_enable)
{
LOG_I("Unimplement syscall %d", number);
}
}
}
@ -5656,7 +5806,10 @@ const char *lwp_get_syscall_name(rt_uint32_t number)
}
else
{
LOG_I("Unimplement syscall %d", number);
if (__sys_log_enable)
{
LOG_I("Unimplement syscall %d", number);
}
}
}

View File

@ -1763,7 +1763,8 @@ netif_find(const char *name)
return NULL;
}
num = (u8_t)atoi(&name[2]);
/* Out netif's name is e0, e1... */
num = (u8_t)atoi(&name[1]);
NETIF_FOREACH(netif) {
if (num == netif->num &&

View File

@ -52,8 +52,9 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
rt_set_errno(-ENOMEM);
return -1;
}
rt_memset(d->vnode, 0, sizeof(struct dfs_vnode));
dfs_vnode_init(d->vnode, FT_SOCKET, dfs_net_get_fops());
d->flags = O_RDWR; /* set flags as read and write */
/* set socket to the data of dfs_file */
d->vnode->data = (void *)(size_t)new_socket;
@ -258,6 +259,7 @@ int socket(int domain, int type, int protocol)
if (socket >= 0)
{
dfs_vnode_init(d->vnode, FT_SOCKET, dfs_net_get_fops());
d->flags = O_RDWR; /* set flags as read and write */
/* set socket to the data of dfs_file */
d->vnode->data = (void *)(size_t)socket;

View File

@ -26,6 +26,10 @@
#include <ipc/workqueue.h>
#endif
#ifdef RT_USING_LWP
#include <lwp_sys_socket.h>
#endif
/* check system workqueue stack size */
#if defined(SAL_INTERNET_CHECK) && RT_SYSTEM_WORKQUEUE_STACKSIZE < 1536
#error "The system workqueue stack size must more than 1536 bytes"
@ -51,6 +55,16 @@ struct sal_netdev_res_table
struct netdev *netdev;
};
struct ifconf
{
int ifc_len; /* Size of buffer. */
union
{
char* ifcu_buf;
struct sal_ifreq *ifcu_req;
} ifc_ifcu;
};
#ifdef SAL_USING_TLS
/* The global TLS protocol options */
static struct sal_proto_tls *proto_tls;
@ -1028,8 +1042,17 @@ int sal_closesocket(int socket)
return error;
}
#define ARPHRD_ETHER 1 /* Ethernet 10/100Mbps. */
#define ARPHRD_LOOPBACK 772 /* Loopback device. */
#define IFF_UP 0x1
#define IFF_RUNNING 0x40
#define IFF_NOARP 0x80
int sal_ioctlsocket(int socket, long cmd, void *arg)
{
rt_slist_t *node = RT_NULL;
struct netdev *netdev = RT_NULL;
struct netdev *cur_netdev_list = netdev_list;
struct sal_socket *sock;
struct sal_proto_family *pf;
struct sockaddr_in *addr_in = RT_NULL;
@ -1048,48 +1071,276 @@ int sal_ioctlsocket(int socket, long cmd, void *arg)
switch (cmd)
{
case SIOCGIFADDR:
addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr);
#if NETDEV_IPV4 && NETDEV_IPV6
addr_in->sin_addr.s_addr = sock->netdev->ip_addr.u_addr.ip4.addr;
#elif NETDEV_IPV4
addr_in->sin_addr.s_addr = sock->netdev->ip_addr.addr;
#elif NETDEV_IPV6
#error "not only support IPV6"
#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
return 0;
if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
{
addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr);
#if NETDEV_IPV4 && NETDEV_IPV6
addr_in->sin_addr.s_addr = sock->netdev->ip_addr.u_addr.ip4.addr;
#elif NETDEV_IPV4
addr_in->sin_addr.s_addr = sock->netdev->ip_addr.addr;
#elif NETDEV_IPV6
#error "not only support IPV6"
#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
return 0;
}
else
{
if (cur_netdev_list == RT_NULL)
{
LOG_E("ifconfig: network interface device list error.\n");
return -1;
}
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
{
addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr);
addr_in->sin_addr.s_addr = netdev->ip_addr.addr;
return 0;
}
}
return -1;
}
case SIOCSIFADDR:
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_addr);
sal_sockaddr_to_ipaddr(addr,&input_ipaddr);
netdev_set_ipaddr(sock->netdev,&input_ipaddr);
return 0;
if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
{
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_addr);
sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
netdev_set_ipaddr(sock->netdev, &input_ipaddr);
return 0;
}
else
{
if (cur_netdev_list == RT_NULL)
{
LOG_E("ifconfig: network interface device list error.\n");
return -1;
}
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
{
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_addr);
sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
netdev_set_ipaddr(netdev, &input_ipaddr);
return 0;
}
}
return -1;
}
case SIOCGIFNETMASK:
addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask);
#if NETDEV_IPV4 && NETDEV_IPV6
addr_in->sin_addr.s_addr = sock->netdev->netmask.u_addr.ip4.addr;
#elif NETDEV_IPV4
addr_in->sin_addr.s_addr = sock->netdev->netmask.addr;
#elif NETDEV_IPV6
#error "not only support IPV6"
#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
return 0;
if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
{
addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask);
#if NETDEV_IPV4 && NETDEV_IPV6
addr_in->sin_addr.s_addr = sock->netdev->netmask.u_addr.ip4.addr;
#elif NETDEV_IPV4
addr_in->sin_addr.s_addr = sock->netdev->netmask.addr;
#elif NETDEV_IPV6
#error "not only support IPV6"
#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
return 0;
}
else
{
if (cur_netdev_list == RT_NULL)
{
LOG_E("ifconfig: network interface device list error.\n");
return -1;
}
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
{
addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask);
#if NETDEV_IPV4 && NETDEV_IPV6
addr_in->sin_addr.s_addr = netdev->netmask.u_addr.ip4.addr;
#elif NETDEV_IPV4
addr_in->sin_addr.s_addr = netdev->netmask.addr;
#elif NETDEV_IPV6
#error "not only support IPV6"
#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
return 0;
}
}
return -1;
}
case SIOCSIFNETMASK:
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_netmask);
sal_sockaddr_to_ipaddr(addr,&input_ipaddr);
netdev_set_netmask(sock->netdev,&input_ipaddr);
return 0;
if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
{
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_netmask);
sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
netdev_set_netmask(sock->netdev, &input_ipaddr);
return 0;
}
else
{
if (cur_netdev_list == RT_NULL)
{
LOG_E("ifconfig: network interface device list error.\n");
return -1;
}
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
{
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_netmask);
sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
netdev_set_netmask(netdev, &input_ipaddr);
return 0;
}
}
return -1;
}
case SIOCGIFHWADDR:
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr);
rt_memcpy(addr->sa_data,sock->netdev->hwaddr,sock->netdev->hwaddr_len);
return 0;
if (!strcmp(ifr->ifr_ifrn.ifrn_name,sock->netdev->name))
{
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr);
#ifdef RT_USING_LWP
if (!strcmp("lo", sock->netdev->name))
{
struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_LOOPBACK;
}
else
{
struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
}
#endif
rt_memcpy(addr->sa_data, sock->netdev->hwaddr, sock->netdev->hwaddr_len);
return 0;
}
else
{
if (cur_netdev_list == RT_NULL)
{
LOG_E("ifconfig: network interface device list error.\n");
return -1;
}
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
{
addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr);
#ifdef RT_USING_LWP
if (!strcmp("lo", netdev->name))
{
struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_LOOPBACK;
}
else
{
struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
}
#endif
rt_memcpy(addr->sa_data, netdev->hwaddr, netdev->hwaddr_len);
return 0;
}
}
return -1;
}
case SIOCGIFMTU:
ifr->ifr_ifru.ifru_mtu = sock->netdev->mtu;
return 0;
if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
{
ifr->ifr_ifru.ifru_mtu = sock->netdev->mtu;
return 0;
}
else
{
if (cur_netdev_list == RT_NULL)
{
LOG_E("ifconfig: network interface device list error.\n");
return -1;
}
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
{
ifr->ifr_ifru.ifru_mtu = netdev->mtu;
return 0;
}
}
return -1;
}
case SIOCGIFFLAGS:
if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
{
uint16_t flags_tmp = 0;
if (sock->netdev->flags & NETDEV_FLAG_UP)
flags_tmp = flags_tmp | IFF_UP;
if (!(sock->netdev->flags & NETDEV_FLAG_ETHARP))
flags_tmp = flags_tmp | IFF_NOARP;
flags_tmp = flags_tmp | IFF_RUNNING;
ifr->ifr_ifru.ifru_flags = flags_tmp;
return 0;
}
else
{
if (cur_netdev_list == RT_NULL)
{
LOG_E("ifconfig: network interface device list error.\n");
return -1;
}
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
{
uint16_t flags_tmp = 0;
if (sock->netdev->flags & NETDEV_FLAG_UP)
flags_tmp = flags_tmp | IFF_UP;
if (!(sock->netdev->flags & NETDEV_FLAG_ETHARP))
flags_tmp = flags_tmp | IFF_NOARP;
ifr->ifr_ifru.ifru_flags = flags_tmp;
return 0;
}
}
return -1;
}
case SIOCSIFFLAGS:
sock->netdev->flags = ifr->ifr_ifru.ifru_flags;
return 0;
case SIOCGIFCONF:
{
struct ifconf *ifconf_tmp;
ifconf_tmp = (struct ifconf *)arg;
int count_size = 0;
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
struct sal_ifreq sal_ifreq_temp;
count_size++;
netdev = rt_list_entry(node, struct netdev, list);
rt_strcpy(sal_ifreq_temp.ifr_ifrn.ifrn_name, netdev->name);
rt_memcpy(ifconf_tmp->ifc_ifcu.ifcu_buf, &sal_ifreq_temp, sizeof(struct sal_ifreq));
ifconf_tmp->ifc_ifcu.ifcu_buf += sizeof(struct sal_ifreq);
}
ifconf_tmp->ifc_len = sizeof(struct sal_ifreq) * count_size;
ifconf_tmp->ifc_ifcu.ifcu_buf = ifconf_tmp->ifc_ifcu.ifcu_buf - sizeof(struct sal_ifreq) * count_size;
return 0;
}
default:
break;
}

View File

@ -807,6 +807,8 @@ struct rt_user_context
void *sp;
void *pc;
void *flag;
void *ctx;
};
#endif

View File

@ -6,10 +6,15 @@
* Change Logs:
* Date Author Notes
* 2022-06-02 Jesven the first version
* 2023-06-24 WangXiaoyao Support backtrace for non-active thread
*/
#include "mm_aspace.h"
#include "mmu.h"
#include <rtthread.h>
#include <backtrace.h>
#include <stdlib.h>
#define BT_NESTING_MAX 100
@ -19,7 +24,7 @@ static int unwind_frame(struct bt_frame *frame)
if ((fp & 0x7)
#ifdef RT_USING_LWP
|| fp < KERNEL_VADDR_START
|| (rt_kmem_v2p((void *)fp) == ARCH_MAP_FAILED)
#endif
)
{
@ -27,16 +32,18 @@ static int unwind_frame(struct bt_frame *frame)
}
frame->fp = *(unsigned long *)fp;
frame->pc = *(unsigned long *)(fp + 8);
if ((rt_kmem_v2p((void *)frame->pc) == ARCH_MAP_FAILED))
return 1;
return 0;
}
static void walk_unwind(unsigned long pc, unsigned long fp)
{
struct bt_frame frame;
struct bt_frame frame = {fp, 1};
unsigned long lr = pc;
int nesting = 0;
frame.fp = fp;
while (nesting < BT_NESTING_MAX)
{
rt_kprintf(" %p", (void *)lr);
@ -51,18 +58,128 @@ static void walk_unwind(unsigned long pc, unsigned long fp)
void backtrace(unsigned long pc, unsigned long lr, unsigned long fp)
{
rt_kprintf("please use: addr2line -e rtthread.elf -a -f %p", (void *)pc);
walk_unwind(lr, fp);
rt_kprintf("please use: addr2line -e rtthread.elf -a -f");
if (pc)
rt_kprintf(" %p", (void *)pc);
if (lr && fp)
walk_unwind(lr, fp);
rt_kprintf("\n");
}
int rt_backtrace(void)
{
unsigned long pc = (unsigned long)backtrace;
unsigned long ra = (unsigned long)__builtin_return_address(0U);
unsigned long fr = (unsigned long)__builtin_frame_address(0U);
backtrace(pc, ra, fr);
backtrace(0, ra, fr);
return 0;
}
MSH_CMD_EXPORT_ALIAS(rt_backtrace, bt_test, backtrace test);
#define ARCH_CONTEXT_FETCH(pctx, id) (*(((unsigned long *)pctx) + (id)))
int rt_backtrace_thread(rt_thread_t thread)
{
unsigned long lr;
unsigned long fp;
if (thread == rt_thread_self())
{
return -RT_EINVAL;
}
else
{
lr = ARCH_CONTEXT_FETCH(thread->sp, 3);
fp = ARCH_CONTEXT_FETCH(thread->sp, 7);
backtrace(0, lr, fp);
return 0;
}
}
#ifdef RT_USING_SMART
int rt_backtrace_user_thread(rt_thread_t thread)
{
unsigned long pc;
unsigned long lr;
unsigned long fp;
unsigned long ctx = (unsigned long)thread->user_ctx.ctx;
if (ctx > (unsigned long)thread->stack_addr
&& ctx < (unsigned long)thread->stack_addr + thread->stack_size)
{
pc = ARCH_CONTEXT_FETCH(thread->user_ctx.ctx, 0);
lr = ARCH_CONTEXT_FETCH(thread->user_ctx.ctx, 3);
fp = ARCH_CONTEXT_FETCH(thread->user_ctx.ctx, 7);
backtrace(pc, lr, fp);
return 0;
}
else
return -1;
}
#endif /* RT_USING_SMART */
static long custom_hex_to_long(const char* hex)
{
long result = 0;
int i = 0;
// Skip the "0x" prefix
if (hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X'))
{
i = 2;
}
// Convert each hex digit to its decimal value
for (; hex[i] != '\0'; i++)
{
char digit = hex[i];
if (digit >= '0' && digit <= '9')
{
result = result * 16 + (digit - '0');
}
else if (digit >= 'a' && digit <= 'f')
{
result = result * 16 + (digit - 'a' + 10);
}
else if (digit >= 'A' && digit <= 'F')
{
result = result * 16 + (digit - 'A' + 10);
}
else
{
// Invalid hex digit
return 0;
}
}
return result;
}
static void cmd_backtrace(int argc, char** argv)
{
long pid;
if (argc < 2)
{
rt_kprintf("please use: backtrace pid\n");
return;
}
if (strncmp(argv[1], "0x", 2) == 0)
{
pid = custom_hex_to_long(argv[1]);
}
else
{
pid = atol(argv[1]);
}
if (pid)
{
rt_kprintf("backtrace %s(0x%lx), from %s\n", ((rt_thread_t)pid)->parent.name, pid, argv[1]);
rt_backtrace_thread((rt_thread_t)pid);
}
}
MSH_CMD_EXPORT_ALIAS(cmd_backtrace, backtrace, print backtrace of a thread);

View File

@ -6,11 +6,14 @@
* Change Logs:
* Date Author Notes
* 2022-06-02 Jesven the first version
* 2023-06-24 WangXiaoyao Support backtrace for non-active thread
*/
#ifndef __BACKTRACE_H__
#define __BACKTRACE_H__
#include <rtthread.h>
struct bt_frame
{
unsigned long fp;
@ -20,4 +23,7 @@ struct bt_frame
void backtrace(unsigned long pc, unsigned long lr, unsigned long fp);
int rt_backtrace(void);
int rt_backtrace_user_thread(rt_thread_t thread);
int rt_backtrace_thread(rt_thread_t thread);
#endif /*__BACKTRACE_H__*/

View File

@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2021-05-18 Jesven the first version
* 2023-06-24 WangXiaoyao Support backtrace for user thread
*/
#include "rtconfig.h"
@ -375,13 +376,31 @@ rt_hw_context_switch_interrupt:
vector_fiq:
B .
.macro SAVE_USER_CTX
MRS X1, SPSR_EL1
AND X1, X1, 0xf
CMP X1, XZR
BNE 1f
BL lwp_uthread_ctx_save
LDP X0, X1, [SP]
1:
.endm
.globl vector_irq
vector_irq:
SAVE_CONTEXT
STP X0, X1, [SP, #-0x10]! /* X0 is thread sp */
BL rt_interrupt_enter
LDP X0, X1, [SP]
#ifdef RT_USING_LWP
SAVE_USER_CTX
#endif
BL rt_hw_trap_irq
#ifdef RT_USING_LWP
BL lwp_uthread_ctx_restore
#endif
BL rt_interrupt_leave
LDP X0, X1, [SP], #0x10
@ -515,7 +534,15 @@ vector_irq_exit:
START_POINT(vector_exception)
SAVE_CONTEXT
STP X0, X1, [SP, #-0x10]!
#ifdef RT_USING_LWP
SAVE_USER_CTX
#endif
BL rt_hw_trap_exception
#ifdef RT_USING_LWP
BL lwp_uthread_ctx_restore
#endif
LDP X0, X1, [SP], #0x10
MOV SP, X0
RESTORE_CONTEXT_WITHOUT_MMU_SWITCH
@ -523,6 +550,9 @@ START_POINT_END(vector_exception)
START_POINT(vector_serror)
SAVE_CONTEXT
#ifdef RT_USING_LWP
SAVE_USER_CTX
#endif
STP X0, X1, [SP, #-0x10]!
BL rt_hw_trap_serror
b .

View File

@ -296,6 +296,19 @@ void rt_hw_trap_exception(struct rt_hw_exp_stack *regs)
#ifdef RT_USING_FINSH
list_thread();
#endif
#ifdef RT_USING_LWP
{
rt_thread_t th;
th = rt_thread_self();
if (th && th->lwp)
{
rt_backtrace_user_thread(th);
}
}
#endif
backtrace((unsigned long)regs->pc, (unsigned long)regs->x30, (unsigned long)regs->x29);
rt_hw_cpu_shutdown();
}

View File

@ -75,6 +75,13 @@ rt_weak const char *rt_hw_cpu_arch(void)
return "unknown";
}
rt_weak void rt_hw_cpu_reset(void)
{
LOG_D("rt_hw_cpu_reset() doesn't support for this board."
"Please consider implementing rt_hw_cpu_reset() in another file.");
return ;
}
static const char* rt_errno_strs[] =
{
"OK",