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

注册于 5 months ago

回答
212
文章
2
关注者
3

“KEIL工程是可以正常运行和使用的”
-》 KEIL环境是不是配置了不使用标准C库?
如果是,使用gcc编译环境,可以在LDFLAGS 加上 -nostdlib 试试看?
看你的编译log,虽然你上次没有显式依赖libc(-lc),但是最后还是去链接了标准c库。

gcc编译环境的话,有个链接选项叫-gc-sections,它是负责最后链接阶段进行段回收的,
也就是没有使用的段就会删除掉。

gcc里面还有比较有趣的选项,叫-print-gc-sections,它可以打印出链接阶段回收的那些段。
你可以尝试在LDFLAGS里面添加相关的选项:--verbose -Wl,--print-gc-sections
这样最后链接时就会有类似的信息输出:
image.png

还有一个gcc的编译优化选项,有时候也会决定“段”是否会被回收,
比如开O0优化跟O3优化,显然有些段就被干掉了。

这些可以自己去写一些demo小实验验证下,加深理解和记忆。

还是命令行环境开发 最轻量级,不过就是没有IDE那么直观。

根据RRT对rt_sem_take接口的介绍
image.png
以及源码里面的注释介绍:

/**
 * @brief    This function will take a semaphore, if the semaphore is unavailable, the thread shall wait for
 *           the semaphore up to a specified time.
 *
 * @note     When this function is called, the count value of the sem->value will decrease 1 until it is equal to 0.
 *           When the sem->value is 0, it means that the semaphore is unavailable. At this time, it will suspend the
 *           thread preparing to take the semaphore.
 *           On the contrary, the rt_sem_release() function will increase the count value of sem->value by 1 each time.
 *
 * @see      rt_sem_trytake()
 *
 * @param    sem is a pointer to a semaphore object.
 *
 * @param    time is a timeout period (unit: an OS tick). If the semaphore is unavailable, the thread will wait for
 *           the semaphore up to the amount of time specified by the argument.
 *           NOTE: Generally, we use the macro RT_WAITING_FOREVER to set this parameter, which means that when the
 *           semaphore is unavailable, the thread will be waitting forever.
 *
 * @return   Return the operation status. ONLY When the return value is RT_EOK, the operation is successful.
 *           If the return value is any other values, it means that the semaphore take failed.
 *
 * @warning  This function can ONLY be called in the thread context. It MUST NOT BE called in interrupt context.
 */
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time)

image.png

我猜测你这种情况是一个接口返回error了,而不是ok,你可以使用int变量接收下这个接口的返回值。
还有一定,看你打印的brew_sem.value值为0,证明信号量此时是空的(大于0表示有信号量)。
还有办法,你可以把RT_DEBUG_IPC宏打开(rtdebug.h),调试下这个接口,我看到都有关键的log打印。

有几个问题需要确认下:
1.bootloader能起来吗?还是说bootloader就没起来?看你的问题像是bootloader跳转到app,起不来?
2.如果bootloader没有起来,建议还原使用原来的bootloader,同意一楼的说法;
3.如果app起不来,有个方法可以确认下app的运行地址是否正确。
在linux环境下,使用readelf -h app.elf (app.elf根据你自己的名字来修改)
参考如图:
image.png
图中圈起来的就是elf的启动地址,也就是你的bin要烧录的地址。
这个地址一般是在link.lds里面配置的。
4.如果启动地址没有问题,建议再排查下中断向量表有没有问题。
提供点思路,希望能帮助到你。

其他IDE有类似的问题吗?
感觉像是电脑环境的问题?
再一个,有没有试过,万能的“重启”大法?
😂

如楼上回复,打包成.a是一种方法;
当.o文件比较多时,一般的做法都是打包成.a。
如果仅仅是一个.o文件,可以尝试在链接列表那种,把.o文件添加进去;
注意一定是在链接列表那里,因为.o文件已经编译好了,不需要再编译了。

你说的是

Warning: The OS tick(100) is less than 1000. So the flash write will take more time.

这句警告吗?
说下我的理解:
1.tick100,意味着1秒钟会有100次时钟中断,就是1秒种会被打断100次;
2.flash读的速度,应该影响不大,因为通常来说flash读操作都是非耗时操作;
3.flash的写和擦除动作,影响比较大,一般在执行flash擦写操作时,都是高占用cpu的,尤其是擦除,擦除的基础单位是flash块,这种硬件操作行为,如果频繁被打断,势必会影响效率;
4.我没有具体的实验佐证以上观点,仅凭自己之前对flash擦除、读写的了解,得出的理解,仅供参考。

查看了下ps的实现源码,题中所说的error,应该就是struct rt_thread结构体中的err变量,如下:
image.png
结合头文件的定义,可以找到错误码-2的含义,如下:
image.png
后续如果看到有其他相关的错误码,也可以参考下这里的定义。

看样子是编译报错,报错的原因是某个依赖的头文件没有包含,
导致struct rt_delayed_work结构体和rt_delayed_wor_xxx相关的函数也没找到申明。
建议找下这些结构体和函数的申明头文件,加入进去看看。

或许你可以了解下rt_sem_init()和rt_sem_create()的区别。

/**@{*/
/**
 * @brief    This function will initialize a static semaphore object.
 *
 * @note     For the static semaphore object, its memory space is allocated by the compiler during compiling,
 *           and shall placed on the read-write data segment or on the uninitialized data segment.
 *           By contrast, the rt_sem_create() function will allocate memory space automatically and initialize
 *           the semaphore.
 *
 * @see      rt_sem_create()
 *
 * @param    sem is a pointer to the semaphore to initialize. It is assumed that storage for the semaphore will be
 *           allocated in your application.
 *
 * @param    name is a pointer to the name you would like to give the semaphore.
 *
 * @param    value is the initial value for the semaphore.
 *           If used to share resources, you should initialize the value as the number of available resources.
 *           If used to signal the occurrence of an event, you should initialize the value as 0.
 *
 * @param    flag is the semaphore flag, which determines the queuing way of how multiple threads wait
 *           when the semaphore is not available.
 *           The semaphore flag can be ONE of the following values:
 *
 *               RT_IPC_FLAG_PRIO          The pending threads will queue in order of priority.
 *
 *               RT_IPC_FLAG_FIFO          The pending threads will queue in the first-in-first-out method
 *                                         (also known as first-come-first-served (FCFS) scheduling strategy).
 *
 *               NOTE: RT_IPC_FLAG_FIFO is a non-real-time scheduling mode. It is strongly recommended to
 *               use RT_IPC_FLAG_PRIO to ensure the thread is real-time UNLESS your applications concern about
 *               the first-in-first-out principle, and you clearly understand that all threads involved in
 *               this semaphore will become non-real-time threads.
 *
 * @return   Return the operation status. When the return value is RT_EOK, the initialization is successful.
 *           If the return value is any other values, it represents the initialization failed.
 *
 * @warning  This function can ONLY be called from threads.
 */
rt_err_t rt_sem_init(rt_sem_t    sem,
                     const char *name,
                     rt_uint32_t value,
                     rt_uint8_t  flag)
/**
 * @brief    Creating a semaphore object.
 *
 * @note     For the semaphore object, its memory space is allocated automatically.
 *           By contrast, the rt_sem_init() function will initialize a static semaphore object.
 *
 * @see      rt_sem_init()
 *
 * @param    name is a pointer to the name you would like to give the semaphore.
 *
 * @param    value is the initial value for the semaphore.
 *           If used to share resources, you should initialize the value as the number of available resources.
 *           If used to signal the occurrence of an event, you should initialize the value as 0.
 *
 * @param    flag is the semaphore flag, which determines the queuing way of how multiple threads wait
 *           when the semaphore is not available.
 *           The semaphore flag can be ONE of the following values:
 *
 *               RT_IPC_FLAG_PRIO          The pending threads will queue in order of priority.
 *
 *               RT_IPC_FLAG_FIFO          The pending threads will queue in the first-in-first-out method
 *                                         (also known as first-come-first-served (FCFS) scheduling strategy).
 *
 *               NOTE: RT_IPC_FLAG_FIFO is a non-real-time scheduling mode. It is strongly recommended to
 *               use RT_IPC_FLAG_PRIO to ensure the thread is real-time UNLESS your applications concern about
 *               the first-in-first-out principle, and you clearly understand that all threads involved in
 *               this semaphore will become non-real-time threads.
 *
 * @return   Return a pointer to the semaphore object. When the return value is RT_NULL, it means the creation failed.
 *
 * @warning  This function can NOT be called in interrupt context. You can use macor RT_DEBUG_NOT_IN_INTERRUPT to check it.
 */
rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag)

感谢楼主提出这个DHCP的问题。

windows这么多串口调试工具,换个其他工具看看?
对于这种交互式的串口调试(有输入命令,有输出内容),我是建议使用secureCRT调试工具。
类似这样的:
image.png

是不是有什么自动通过网络更新版本,导致的?
一个小小的插件把上行网络拉满,有点恐怖啊!
建议使用“控制变量”排除法,排查下。

因为楼主没有把你对map文件的意图说清楚,
我猜你是想通过map文件分析一些内存地址映射的东西,
这篇文章,可以参考下,对map文件讲到了一些内容。

回到
顶部

发布
问题

投诉
建议