whj467467222
whj467467222 - 认证专家

注册于 3 years ago

回答
282
文章
9
关注者
4

485 是半双工的通讯机制,也就决定了收发不能同时进行,这也就是为什么 232 你测试正常的原因。
一般来说,485 在使用的时候都是默认设置为接收模式,等到需要发送数据的时候来切换到发送模式,发送完成之后立马切换到接收模式。
如何判断接收完毕呢?
实际项目中使用 485 的时候都会引入协议的概念。

  1. 常用的协议 MODBUS-RTU ,通过标准协议规定的超时时间来切换到发送状态。
  2. 自定义协议,自行判断何时数据接收完毕,比如收到某个数据,或者收到多少个字节数据,或者多长时间都不在收到数据,接收完毕后切换到发送状态。

码字不易,帮到你了请点个采纳。

这里用到了 双链表的知识,可以看我的文章。RT-Thread 隐藏的宝藏之双链表

先看一下线程控制块结构体(有删减)

struct rt_thread
{
    /* rt object */
    char        name[RT_NAME_MAX];                      /**< the name of thread */
    rt_uint8_t  type;                                   /**< type of object */
    rt_uint8_t  flags;                                  /**< thread's flags */

    rt_list_t   list;                                   /**< the object list */
    rt_list_t   tlist;                                  /**< the thread list */

    /* stack point and entry */
    void       *sp;                                     /**< stack point */
    void       *entry;                                  /**< entry */
    void       *parameter;                              /**< parameter */
    void       *stack_addr;                             /**< stack address */
    rt_uint32_t stack_size;                             /**< stack size */

    /* error code */
    rt_err_t    error;                                  /**< error code */

    rt_uint8_t  stat;                                   /**< thread status */

    /* priority */
    rt_uint8_t  current_priority;                       /**< current priority */
    rt_uint8_t  init_priority;                          /**< initialized priority */
    rt_uint32_t number_mask;

    rt_ubase_t  init_tick;                              /**< thread's initialized tick */
    rt_ubase_t  remaining_tick;                         /**< remaining tick */

    struct rt_timer thread_timer;                       /**< built-in thread timer */

    void (*cleanup)(struct rt_thread *tid);             /**< cleanup function when thread exit */

    rt_uint32_t user_data;                             /**< private user data beyond this thread */
};

通过循环链表的操作肯定能找到 tlist 的地址,通过

rt_list_entry(node(节点), type(结构体类型), 链表所在结构体成员的名字)

这个宏是关键,他可以查找到 tlist 的地址,通过这个地址能推导出 struct rt_thread 的首地址。首地址找到了,结构体你也有了,不就顺理成章的找到了所有的线程块里面的所有信息了嘛?

这里是来判断栈顶地址是否合法。

MDK 为例来解释。
link.sct 的文件中有下面的描述

  RW_IRAM1 0x24000000 0x00080000  {  ; AXI SRAM 512K
   .ANY (+RW +ZI)

这里的意思是: 从地址 0x24000000 开始,长度为 0x00080000 的内存作为系统的 heap,也就是你代码编译完成后查看 map 文件能查看到你定义的变量,都是在这个地址段内。

在来说一下地址段的问题:
STM32H7 系列与用的最多的 F系列 有一个很大的不同就是 RAM 的区别。
F系列的起始地址都是从 0x20000000 这也就是你在网上看到的例程都是判断这个地址。
image.png
这个图是 H7 的内存分布情况,
大家常写在 link.sct 文件的地址一般是 0x20000000 或者 0x24000000
很多情况下都是用的 0x24000000 为什么呢?
主要是内存能访问外设的原因,我的博客 有详细的说明。

另外你可以查看你编译好的 bin 文件也是能看到栈顶。

所以在STM32H7 是判断 0x20000000 还是 0x24000000 根据你实际的工程配置。当然你也可以用或的方式来判断,这里是 H7 的特殊的一点。这个做法可以参考

这么说不知道你明白了没有.

如果帮到你了,请点个采纳哦。

出现这个问题有我的原因。
具体可以看我合并代码的说明。PR说明

4,board.h 中增加宏定义LSI_VALUE,CUBEMX 的 bug 导致生成的 stm32h7xx_hal_conf.h 没有LSI_VALUE 的定义,待 ST 修复这个 BUG 后可删除,不然 drv_dwt.c 会报错

建议你参考一下这个.

帮到你的话,请帮忙点个采纳。

可以用的,我是用过串口与网络。

但是串口用起来没有网络用起来舒服,可以看这个 issue

不过社区的小伙伴们正在着手去解决这个问题了,顺利的话这个月就会提交修正后的串口框架。

如果我的回答帮到你的话,点个采纳哦。

这是一个老生常谈的问题了。

正点原子探索者 STM32F407 上手指南

这里有写到 :

image.png

为什么会导致这个问题呢? 原因与解决办法

还有一个办法就是每次板子上电之后再接串口的那个 USB 的线。

我的回答帮到你的话,请点个采纳。

会不会是波特率不对,我在 ART-Pi 上测试 CANFD 是没问题的

你这是警告啊。

你用 sf 的命令去测试一下,应该是能操作 flash

nano 没有设备框架,也就是没有网络抽象层了,MQTT 的软件包都使用了网络抽象层的 API,所以 nano 要使用 MQTT 就无法使用软件了,这就需要你自己去实现了。

看样子你是想对 FLASH 进行分区,然后挂载文件系统。
这个代码在 ART-Pi 的 SDK 拷贝出来的,验证通过的,你可以自己去下载一份看看其他的配置。

参考一下这个的实现吧.

/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author        Notes
 * 2018-12-13     balanceTWK    add sdcard port file
 * 2019-06-11     WillianChan   Add SD card hot plug detection
 */

#include <rtthread.h>

#ifdef BSP_USING_FS
#if DFS_FILESYSTEMS_MAX < 4
#error "Please define DFS_FILESYSTEMS_MAX more than 4"
#endif
#if DFS_FILESYSTEM_TYPES_MAX < 4
#error "Please define DFS_FILESYSTEM_TYPES_MAX more than 4"
#endif

#ifdef BSP_USING_SPI_FLASH_FS
#include "fal.h"
#endif

#include <dfs_fs.h>
#include "dfs_romfs.h"
#include "drv_sdio.h"

#define DBG_TAG "app.filesystem"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

static const struct romfs_dirent _romfs_root[] = {
    {ROMFS_DIRENT_DIR, "flash", RT_NULL, 0},
    {ROMFS_DIRENT_DIR, "sdcard", RT_NULL, 0}};

const struct romfs_dirent romfs_root = {
    ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_romfs_root, sizeof(_romfs_root) / sizeof(_romfs_root[0])};

#ifdef BSP_USING_SDCARD_FS

/* SD Card hot plug detection pin */
#define SD_CHECK_PIN GET_PIN(D, 5)

static void _sdcard_mount(void)
{
    rt_device_t device;

    device = rt_device_find("sd0");
    if (device == NULL)
    {
        mmcsd_wait_cd_changed(0);
        sdcard_change();
        mmcsd_wait_cd_changed(RT_WAITING_FOREVER);
        device = rt_device_find("sd0");
    }
    if (device != RT_NULL)
    {
        if (dfs_mount("sd0", "/sdcard", "elm", 0, 0) == RT_EOK)
        {
            LOG_I("sd card mount to '/sdcard'");
        }
        else
        {
            LOG_W("sd card mount to '/sdcard' failed!");
        }
    }
}

static void _sdcard_unmount(void)
{
    rt_thread_mdelay(200);
    dfs_unmount("/sdcard");
    LOG_I("Unmount \"/sdcard\"");

    mmcsd_wait_cd_changed(0);
    sdcard_change();
    mmcsd_wait_cd_changed(RT_WAITING_FOREVER);
}

static void sd_mount(void *parameter)
{
    rt_uint8_t re_sd_check_pin = 1;
    rt_thread_mdelay(200);
    if (rt_pin_read(SD_CHECK_PIN))
    {
        _sdcard_mount();
    }
    while (1)
    {
        rt_thread_mdelay(200);
        if (!re_sd_check_pin && (re_sd_check_pin = rt_pin_read(SD_CHECK_PIN)) != 0)
        {
            _sdcard_mount();
        }

        if (re_sd_check_pin && (re_sd_check_pin = rt_pin_read(SD_CHECK_PIN)) == 0)
        {
            _sdcard_unmount();
        }
    }
}

#endif /* BSP_USING_SDCARD_FS */

int mount_init(void)
{
    if (dfs_mount(RT_NULL, "/", "rom", 0, &(romfs_root)) != 0)
    {
        LOG_E("rom mount to '/' failed!");
    }
#ifdef BSP_USING_SPI_FLASH_FS
    struct rt_device *flash_dev = RT_NULL;

#ifndef RT_USING_WIFI
    fal_init();
#endif

    flash_dev = fal_mtd_nor_device_create("filesystem");

    if (flash_dev)
    {
        //mount filesystem
        if (dfs_mount(flash_dev->parent.name, "/flash", "lfs", 0, 0) != 0)
        {
            LOG_W("mount to '/flash' failed! try to mkfs %s", flash_dev->parent.name);
            dfs_mkfs("lfs", flash_dev->parent.name);
            if (dfs_mount(flash_dev->parent.name, "/flash", "lfs", 0, 0) == 0)
            {
                LOG_I("mount to '/flash' success!");
            }
        }
        else
        {
            LOG_I("mount to '/flash' success!");
        }
    }
    else
    {
        LOG_E("Can't create  block device  filesystem or bt_image partition.");
    }

#endif

#ifdef BSP_USING_SDCARD_FS
    rt_thread_t tid;

    rt_pin_mode(SD_CHECK_PIN, PIN_MODE_INPUT_PULLUP);

    tid = rt_thread_create("sd_mount", sd_mount, RT_NULL,
                           2048, RT_THREAD_PRIORITY_MAX - 2, 20);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }
    else
    {
        LOG_E("create sd_mount thread err!");
    }
#endif
    return RT_EOK;
}
INIT_APP_EXPORT(mount_init);

#endif /* BSP_USING_FS */

你这个问题和 micropython 没有关系。

你的问题是 [E/DFS] Device (W25Q128) was not found 说明你的 W25Q128 是一个未被注册的设备。

你应该去检查一下你的 W25Q128 是在哪里注册的。

你可以先去了解一下文件系统如何挂载。

路径错了。
举个栗子:

rt_thread_master\bsp\stm32\stm32f103-blue-pill

你应该在更下一级目录去执行 scons --target=mdk5

也就是你自己制作的 BSP 的目录下

image.png

在 README 中的注意事项写到了 :

使用UART2 DMA模式时,HEAP的CACHE策略设置了WT模式,所以在使用rt_device_read读取数据之前必须调用用SCB_InvalidateDCache_by_Addr或者SCB_InvalidateDCache,已确保读取到数据的正确性。

如果帮到你了,记得点一下采纳哦。

发布
问题