recan
recan
http://yyds.recan-li.cn 一个专注于嵌入式软件架构设计的新生代农名工

注册于 7 months ago

回答
356
文章
7
关注者
12

有几个问题可以确认下:
1.开发板使用的是什么通讯方式?(Wi-Fi?4G? 还是以太网?)
2.确认下云服务器的69号端口是否对外映射了?
可以使用tftpd64的客户端界面验证下;
我这边帮你验证了,tftp服务是正常开启的:
image.png
你的tftp服务器目录应该可以看到一个test-file.txt的文件;
3.如果是这样的情况,建议你重点排查下你的开发板到你的云服务的网络拓扑了,因为我的测试电脑是可以到达你的tftp服务器的。

查看kconfig配置文件components/libc/Kconfig
可以看到:
image.png
也就是说打开了这个宏,那么系统就可以支持dlopen、dlclose接口去操作动态库(so);
这种dlopen操作在linux下编程是一种很常见的操作,可以参考下:linux使用范例
因为我没在rt-thread上使用过这个dlopen,仅凭经验来了解,仅供参考。

image.png
从你的图中发现当前目录下这个Makefile指定的交叉编译工具链是arm-eabi-gcc而不是arm-none-eabi-gcc;一般在makefile里面是用CC来指定的。
如果你本地用的arm-none-eabi-gcc,那就会报找不到arm-eabi-gcc
先确认下是否真正的是要用arm-eabi-gcc;
如果不是,可以修改MakefileCC配置,再试试看;
如果是,那只能再重新安装下arm-eabi-gcc交叉工具链。

这个问题的根源是一个语法问题:rt_device结构体中没有定义read/write/close等成员变量(函数指针)。
struct rt_device结构体定义在include/rtdef.h中:

/**
 * Device structure
 */
struct rt_device
{
    struct rt_object          parent;                   /**< inherit from rt_object */

    enum rt_device_class_type type;                     /**< device type */
    rt_uint16_t               flag;                     /**< device flag */
    rt_uint16_t               open_flag;                /**< device open flag */

    rt_uint8_t                ref_count;                /**< reference count */
    rt_uint8_t                device_id;                /**< 0 - 255 */

    /* device call back */
    rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
    rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);

#ifdef RT_USING_DEVICE_OPS
    const struct rt_device_ops *ops;
#else
    /* common device interface */
    rt_err_t  (*init)   (rt_device_t dev);
    rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
    rt_err_t  (*close)  (rt_device_t dev);
    rt_size_t (*read)   (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
    rt_size_t (*write)  (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
    rt_err_t  (*control)(rt_device_t dev, int cmd, void *args);
#endif

#if defined(RT_USING_POSIX)
    const struct dfs_file_ops *fops;
    struct rt_wqueue wait_queue;
#endif

    void                     *user_data;                /**< device private data */
};

我们可以看到中间是有定义open/read/write/close/control的,但是它上面是被一个宏RT_USING_DEVICE_OPS控制起来;
当没有定义这个宏定义的时候,这几个函数指针才会参与编译;否则就不参与编译,这个时候就会报找不到这几个成员变量;就如同你的报错信息一样。
所以我猜测你的工程里面,已经定义了RT_USING_DEVICE_OPS宏,
这个宏一般是在rtconfig.h里面定义的,
你可以查一下你的工程环境。
image.png

使用man memset查看接口的帮助信息:

NAME
       memset - fill memory with a constant byte
SYNOPSIS
       #include <string.h>
       void *memset(void *s, int c, size_t n);
DESCRIPTION
       The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
RETURN VALUE
       The memset() function returns a pointer to the memory area s.

注意描述那一段,memset是按字节数来操作的;
而你定义的u16 num[50];这里不是50字节啊,
这里是sizeof(u16) x 50 = 100字节啊!
所以修改成

memset(num, 0, 100); //注意是100字节
或者
memset(num, 0, sizeof(num)); //用sizeof自己去计算字节数,调用者不用去填多少个字节,移植性也较好

这样就能解除你的疑惑了。

谢邀!

找到一个scons 中关于CCCOM, CXXCOM,LINKCOM等说明:

CCCOM:编译C文件的命令行表示,需要时可以改写此字段的值,达到自定义控制文件编译的目的

例如:env.Replace(CCCOM='$CC $CPPPATH $CPPDEFINES -c $SOURCE -O $TARGET')

CCCOMSTR:当C文件编译时,显示到控制台中的字符串(主要用来显示,方便使用者查看)

CXXCOM:编译C++文件时的命令行

CXXCOMSTR: 编译C++文件时显示到控制台的字符串

其他的例如ASCOM,ASCOMSTR,LINKCOM,LINKCOMSTR用法基本类似,不再赘述。

您好,新鲜出炉,见文分析:
--specs=xxx.specs分析
有用的话,点个小赞,谢谢。

必须在boardlinker_scriptslink.ids中添加如下代码才能编译通过:

/* section information for modules */
. = ALIGN(4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
但是这句话为什么原始的bsp中没有,为什么要加,加了会有什么效果呢?

针对这个问题,我的猜想:
应该就是新的版本引入了对__rtmsymtab_start与__rtmsymtab_end的引用;
这两个变量在链接脚本里面定义的,本质就是定义了两个地址变量,可以理解成uint32_t __rtmsymtab_start, __rtmsymtab_end; ;
但他们有点不同的是,他是带了确定的值的,这个取决于它写在链接脚本的什么位置;

__rtmsymtab_start = .;  //当前的地址值,赋值给__rtmsymtab_start
KEEP(*(RTMSymTab)) //中间一堆的section
__rtmsymtab_end = .; //当前的地址值(已经累上去了,值变了),赋值给__rtmsymtab_end

这块知识需要对链接脚本的语法有点了解才行。

至于为何旧版本不用写在链接脚本里面,应该是旧版本就没有引用过这两个变量;自然就不会报他们没定义。

找不到名为"FAL_EF_PART_NAME(宏定义)"的分区?

注意关注下栈空间使用的问题:
软定时器使用的栈空间是系统定时器线程(timer线程)的栈空间;
而自己创建的线程有自己独立的栈空间。
如果你需要执行的功能代码占用栈空间较大,那就要考虑自行创建线程了。
还有一点就是楼上朋友提及的代码执行时间的问题,如果你执行的功能代码是一个耗时操作,那么也是要考虑自行创建线程,否则可能就会影响其他定时任务的实时性。

需不需要转义,取决于 收你数据的那边的处理;
对于MQTT publish而已,你的数据是透明的,
没有说它publish什么样的数据,它只认byte数组(字节流)。

谢邀。
想确认下这个channel转换有没有问题:

/* Converts the channel number to the channel number of Hal library */
rt_uint32_t channel = 0x04 * (configuration->channel - 1);

另外,代码里有好几个PWM相关的宏配置,能不能把明确知道不跑的宏定义去掉,
较少干扰项,代码清晰些。
目前观察PWM有无输出,只是用led来确认吗?是否可以上示波器或逻辑分析仪,看下输出管脚是什么情况。

data段超出了11492 bytes;
简单来说就是腾讯云的包中使用的RAM太大了;
超出了你的链接脚本规划的RAM空间;
这种代码体现主要是包里面的全局变量/结构体占用的空间太大。
参考下文档

回到
顶部

发布
问题

投诉
建议