出出啊
出出啊
It is Not the Mountain We Conquer, but Ourselves

注册于 6 months ago

回答
863
文章
18
关注者
53

疑问挺多哈,一个个说,

问题一

中断处理复杂,是不合理的,无论是裸机还是在系统里,中断处理尽最大化简化。

问题二

这里的局部指针变量,下一句就初始化了,其实fifo是在初始化的设备对象管理的。

struct rt_serial_rx_fifo* rx_fifo;

/* interrupt mode receive */
rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;

问题三

rt_device_read是从前边的 fifo 里面取出数据,放到这个新的 buffer 指针指向的缓冲区的。也就是说,驱动层有缓存,应用层也要有自己的数据存放内存区域。
问题四,串口是数据流设备,不保证一次接收多少个字节,但是通过多次调用 rt_device_read 是可以获取多个字节的,至于这四个字节顺序,要看发送方是高字节先发还是低字节先发。

昨天一个问题,我贴的一段代码,怎么处理一个完整串口数据包的。应该对你有帮助。
https://club.rt-thread.org/ask/question/432479.html

https://blog.csdn.net/weixin_45204243/article/details/105744323
看这个教程,你的也是因为没有修改调试器的烧写算法吧。
同一个问题为啥问两次呢。

换 FPGA 吧,就算用单片机裸机完成这么多次采样压力也不小,采样也不均匀。高时序要求还是用fpga靠谱。

https://blog.csdn.net/weixin_45204243/article/details/105744323
看这个教程,你的也是因为没有修改调试器的烧写算法吧。

不错,方案很完整。
不过,如果使用 eth ,128k 够吗?我的代码量上256去了。

缺少头文件,需要添加头文件包含路径,首先需要你知道相关头文件路径。然后通过如下方法添加。
右键项目,属性,在弹出的属性框中找到如图中位置。
添加头文件路径
image.png

我看你上面说先一直写文件,等 flash 满了以后才停止写?
然后才进行读操作?
如果不写满 flash 能读回来文件内容吗?

上面你提供的代码是读的部分,因为open已经失败了,所以这部分代码没有参考价值。
可以看一下你写的部分吗?

image.png
右键项目新建文件,然后弹窗中填写这几个地方

目测,你先执行 dfs_mount ,后执行 fal_flash_init 了,初始化在后,肯定挂载失败的

可以的话,把你调用 dfs_mount 和 fal_flash_init 的地方的代码贴出来,谈谈初始化执行顺序的问题。

用代码说话,项目中用的,有包头包尾,数据长度,数据类型,数据域等等,数据完整性判断

    rt_uint8_t *recvbuf = RT_NULL;
    static struct serial_configure uart_conf = RT_SERIAL_CONFIG_USER;
    rt_uint8_t *datbuf = RT_NULL;
    rt_size_t rcv_off = 0, recv_sz = 1024, tmp = 0;
    rt_size_t dat_off = 0, dat_len = 0, i;
    rt_tick_t _speed_ctrl = 0;

    recvbuf = rt_malloc(128);
    rt_memset(recvbuf, 0, 128);
    datbuf = rt_malloc(32);
    rt_memset(datbuf, 0, 32);

    busif_speed_ctrl = rt_tick_get();

    rt_sem_init(&rx_sem, "bifrx", 0, 0);
    dev_busif = rt_device_find("uart1");
    if (dev_busif == RT_NULL)
    {
        rt_kprintf("Can not find device: %s\n", "uart1");
        return;
    }
    if (rt_device_open(dev_busif, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | \
                       RT_DEVICE_FLAG_STREAM) == RT_EOK)
    {
        rt_device_set_rx_indicate(dev_busif, busif_rx_ind);
    }
    rt_device_control(dev_busif, RT_DEVICE_CTRL_CONFIG, &uart_conf);

    while(1) {
        rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
        recv_sz = rt_device_read(dev_busif, -1, &recvbuf[rcv_off], 128-rcv_off);
        if (recv_sz > 0) {
            rt_kprintf("data: %d\n", recv_sz);
            if (rcv_off == 0) {
                i = 0;
                while ((recvbuf[i] != 0x1A) && (i < recv_sz)) i++;          // find header
                if (i == 0) {
                    rcv_off = recv_sz;
                } else if (i < recv_sz) {
                    rcv_off = recv_sz-i;
                    rt_memcpy(recvbuf, &recvbuf[i], recv_sz-i);
                } else {                                                    // no header
                    rcv_off = 0;
                    continue;
                }
            } else {
                rcv_off += recv_sz;
            }
            if (rcv_off < 2) {                                              // data not enough
                continue;
            }
            dat_len = recvbuf[1];
            if (dat_len > 16) {                                             // error length
                rcv_off = 0;
                dat_len = 0;
                continue;
            }
            if (rcv_off >= (dat_len + 3)) {                                 // len enough
                float val = 0;
                AdcVal adc_val;

                if (recvbuf[9+2] != 0x1B) {                                 // find tailer error
                    dat_len = 0;
                    rcv_off = 0;
                    continue;
                }
                tmp = rcv_off-(dat_len + 3);
                _speed_ctrl = rt_tick_get();
                if (/*busif_busy > 0 || */(_speed_ctrl - busif_speed_ctrl < 100)) {
                    busif_busy--;
                    if (tmp > 0) {
                        rt_memcpy(recvbuf, &recvbuf[dat_len + 3], tmp);
                        rcv_off = tmp;
                    } else {
                        rcv_off = 0;
                    }
                    dat_len = 0;
                    continue;
                }
                switch(recvbuf[2]){                                         // map function type id
                case 1:
                    adc_val.type = FUNC_DCV;
                break;
                case 2:
                    adc_val.type = FUNC_DCI;
                break;
                default:                                                    // unsupport type id
                    if (tmp > 0) {
                        rt_memcpy(recvbuf, &recvbuf[dat_len + 3], tmp);
                        rcv_off = tmp;
                    } else {
                        rcv_off = 0;
                    }
                    dat_len = 0;
                    rt_kprintf("error type: %d\n", adc_val.type);
                    continue;
                break;
                }
                rt_memcpy(datbuf, recvbuf+4, 7);                            // change str 2 float
                datbuf[7] = 0;
                rt_kprintf("%s\n", datbuf);        // 数据域 ,可以是字符串,可以是十六进制数据
                // 其它数据处理
                ....
                // prepare next package 准备下一包
                if (tmp > 0) {
                    rt_memcpy(recvbuf, &recvbuf[dat_len + 3], tmp);
                    rcv_off = tmp;
                } else {
                    rcv_off = 0;
                }
                dat_len = 0;
            }
        }
    }

先看大佬的文章
https://club.rt-thread.org/ask/article/2864.html

RT-Thread Studio插件使用详解
目前该插件尚不支持新建工程,我们先用RT-Studio新建工程,这里小飞哥直接使用falling-star board配套的例程

大佬也说不支持新建

在某台下载的软件包,不会添加到 rt-thread 的仓库的,它们都是单独的仓库。

所以,我更推荐使用 env ,本地的仓库可以随便拷贝到其它电脑上,然后 env 不限制你的仓库位置。拷贝到其它电脑上一样使用。

stutio 太多不方便。

是你给了个超过 0x7FFFFFFF 的定时时间

或者就是个随机数。

贴一下启动定时器部分的代码吧。

串口接收丢失数据的提问论坛上有很多,请参考我写的系列文章以及我回答的几个提问。

这里回答里,通过降波特率解决了丢数的问题。
https://club.rt-thread.org/ask/question/432449.html

在我写的文章里也提到了几种方案,比如不用信号量和消息队列,使用原子类型的 flag 等等。
减少关中断可能是个比较系统级的了,但是我还是那个观点,关中断优化是势在必行的。

回到
顶部

发布
问题

投诉
建议