陈斌
陈斌
This guy hasn't written anything yet

注册于 2 years ago

回答
23
文章
0
关注者
2

每个芯片的ddr都不一样,rtt怎么可能做到都兼容。一般ddr初始化都是bootloader做好了吧,rtt在运行的时候程序已经在ddr内了

在LWIP 2.1.2版本的源码下
rt-thread/components/net/lwip-2.1.2/src/api/sockets.c
找到了函数

ssize_t
lwip_recvmsg(int s, struct msghdr *message, int flags)

不知道是否可以直接跳过SAL调用这个函数

用libmodbus吧,freemodbus跟freertos一样,代码复杂得很(乱)

我自问自答了
scons脚本中,每个Environment之前添加一个
DefaultEnvironment(tools=[])

这个问题就消失了,好奇怪的操作

这个安全不一定要说加密传输保证吧,
你也可以做好一系列的认证,不让不合法的设备进入到你的网络中,
也可以用开发的协议,但是协议内容是可变得

中断发送的问题我修改了代码,实现了中断发送,效果并不理想,发送的时候有时候被高优先级的线程抢占了cpu,下一个字节没有写到寄存器去,发生断帧现象

https://club.rt-thread.org/ask/question/427309.html

所以并不是很看好中断发送,还是用轮询发送或者DMA好一些
而且由于中断优先级和线程优先级的问题,轮询发送时最好关闭调度器

rt_enter_critical();
if(config->rts_set)config->rts_set(1);
rt_device_write(config->dev, 0, data, length);
if(config->rts_set)config->rts_set(0);
rt_exit_critical();

DMA发送还没有测试,因为不好处理收发引脚的问题,

但是接收是用DMA接收并且屏蔽了DMNA半满和全满中断只用IDLE空闲中断

可以改成下面这样


    /* UART in mode Receiver -------------------------------------------------*/
    if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) &&
            (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET))
    {
        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }
#ifdef RT_SERIAL_USING_DMA
    else if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET)
             && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET))
    {
        level = rt_hw_interrupt_disable();
        recv_total_index = serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma_rx.handle));
        recv_len = recv_total_index - uart->dma_rx.last_index;
        uart->dma_rx.last_index = recv_total_index;
        rt_hw_interrupt_enable(level);

        if (recv_len)
        {
            rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
        }
        __HAL_UART_CLEAR_IDLEFLAG(&uart->handle);
    }
#endif
    else if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) &&
            (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_TC) != RESET))
    {
#ifdef RT_SERIAL_USING_DMA
        if ((serial->parent.open_flag & RT_DEVICE_FLAG_DMA_TX) != 0)
        {
            HAL_UART_IRQHandler(&(uart->handle));
        }
#endif
                if ((serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX) != 0)
        {
            rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
        }
        UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC);
    }
    else .....

可以尝试用官方的做法加个接收线程,然后再传给用户线程

也可以尝试吧半满中断关掉,只有空闲中断触发

我重新编译后,运行了同样的程序,还是会过段时间就死机,然后我查了每次死机后的PC指针的范围

psr: 0x21000000
r00: 0x002008be
r01: 0x08103e08
r02: 0x00000002
r03: 0x00000002
r04: 0x00000002
r05: 0x200013dc
r06: 0x08103e08
r07: 0x20001200
r08: 0x20000c20
r09: 0x20023434
r10: 0x00000000
r11: 0x000007e0
r12: 0x00000190
 lr: 0x080e3c21
 pc: 0x080ddb18
hard fault on thread: thread1

thread   pri  status      sp     stack size max used left tick  error
-------- ---  ------- ---------- ----------  ------  ---------- ---
rttapp2   31  suspend 0x00000108 0x00000800    21%   0x00000003 000
tshell    12  suspend 0x00000184 0x00001000    23%   0x00000009 000
tidle0    31  ready   0x0000007c 0x00000400    13%   0x00000005 000
timer     10  suspend 0x00000080 0x00000400    17%   0x0000000a 000
main      10  suspend 0x00000148 0x00000800    60%   0x00000011 000
bus fault:
SCB_CFSR_BFSR:0x82 PRECISERR SCB->BFAR:002008BE

因为这个固件重新编译了,所以死机的PC跟上面发生了变化,但是大体上可以锁定了一个确定的位置,就是在这些库函数里面

QQ图片20201022104928.png

newlibc库应该有pow这个函数的实现,
你需要确定有没有头文件

include"math.h"

回到
顶部

发布
问题

投诉
建议