Răsfoiți Sursa

update components & lwp. (#7888)

geniusgogo 2 ani în urmă
părinte
comite
4d20416b2f

+ 225 - 0
components/drivers/sdio/block_dev.c

@@ -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

+ 8 - 0
components/finsh/cmd.c

@@ -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);

+ 29 - 0
components/finsh/msh_file.c

@@ -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);
 

+ 7 - 26
components/libc/posix/io/stdio/libc.c

@@ -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)
 

+ 14 - 0
components/lwp/lwp.c

@@ -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;
+}

+ 4 - 0
components/lwp/lwp.h

@@ -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 */

+ 1 - 0
components/lwp/lwp_ipc.c

@@ -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;

+ 5 - 0
components/lwp/lwp_pid.c

@@ -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)

+ 39 - 0
components/lwp/lwp_sys_socket.h

@@ -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__ */

+ 168 - 15
components/lwp/lwp_syscall.c

@@ -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);
+            }
         }
     }
 

+ 2 - 1
components/net/lwip/lwip-2.1.2/src/core/netif.c

@@ -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 &&

+ 3 - 1
components/net/sal/socket/net_sockets.c

@@ -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;

+ 281 - 30
components/net/sal/src/sal_socket.c

@@ -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;
+            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;
         }

+ 2 - 0
include/rtdef.h

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

+ 124 - 7
libcpu/aarch64/common/backtrace.c

@@ -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);

+ 6 - 0
libcpu/aarch64/common/backtrace.h

@@ -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__*/

+ 30 - 0
libcpu/aarch64/common/context_gcc.S

@@ -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 .

+ 13 - 0
libcpu/aarch64/common/trap.c

@@ -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();
 }

+ 7 - 0
src/kservice.c

@@ -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",