This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC3235SF:为何无法使用 malloc?应用内存

Guru**** 2558250 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1052301/cc3235sf-why-do-i-fail-to-apply-for-memory-with-malloc

器件型号:CC3235SF

当我申请一个具有 malloc 函数的存储器时、我发现它总是不成功。 为什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是否有人知道如何解决这个问题?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yaowu、

    您在 CCS 中看到了什么错误? EMG_SEND_DATA_pack 的大小是否与 temp 相同

    谢谢、
    Jacob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我使用 malloc 应用了内存、但返回了0。似乎没有给出 malloc 内存。 需要修改哪些内容?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    为什么 malloc 失败? 我是否需要将其修改为 malloc?请帮助我。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yaowu、

    您能否  memcpy()之前发布 EMG_SEND_DATA_pack 内容的图片?  

    另一个需要检查的问题是、您的程序分配了堆内存。 您可以通过查看.cmd 中的 heap_size 变量来确保这种情况。

    例如:

    这张图片显示了我的示例 未分配堆。  

    谢谢、
    Jacob  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    是的、在我将它设置为阻塞模式后、它仍然不起作用。 在我进入 for ()循环之前,一切都正常,但当我输入 for ()并使用 IIC 读取数据时,它不起作用。 程序卡在 IIC 中。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yaowu、

    我认为您在上面发布的回复与此问题无关。 您能否  在  memcpy() heap_size 变量之前发布 EMG_SEND_DATA_pack 图片?

    谢谢、
    Jacob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    EMG_SEND_DATA_pack 图片

    和 heap_size

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yaowu、

    malloc 实际上是成功的。 上面随 temp 提供的屏幕截图显示了分配了 temp 的存储器地址和 该地址的值。  

    我已为 char* a 分配256个字节

    然后在 memcpy 之后:

    malloc 成功;我建议在 CCS 中使用"Memory Browser"视图来观察在 temp 地址分配的内容。

    谢谢、
    Jacob  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的。谢谢 Jacob。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    为什么不能在中断中执行 malloc 存储器?

    当我运行到 malloc 时,程序会卡住并在 vportenttercritical ()函数中停止。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yaowu、

    我将在下周跟进。

    谢谢、
    Jacob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jacob、

    您知道为什么我不能在中断中对存储器进行 malloc?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yaowu、

    很抱歉、上周我忘记更新我的外出状态。 我将在本周跟进。

    谢谢、
    Jacob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yaowu、  

    很抱歉耽误你的时间。 您真的需要在中断中进行 malloc 调用吗? 我不建议在中断中调用 malloc。 malloc 访问 程序使用的全局内存池。 如果您从两  个未同步的位置调用 malloc、则内存池会受到负面影响。 如果您绝对需要在中断中调用 malloc 并且正在其他地方调用 malloc、则需要确保将 malloc 调用打包以确保中断安全。  

    相反、我建议在中断中设置一个标志、以便在主程序中调用 malloc。  

    谢谢、
    Jacob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jacob、

    我需要在中断中申请存储器、然后在使用后将其释放、但当我在中断中调用 malloc 函数时、程序会卡在这里。 是否有任何方法可以解决或替换此问题?

    请帮助我解决 proplem 问题。

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Wu、

    我将在本周晚些时候跟进。

    谢谢、
    Jacob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jacob、

    我需要在每个中断中分配一个新的存储器、然后在中断中使用它、然后释放它以确保数据的完整性。

    请尽快提供解决方案。

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Wu、

    中断时需要多大的存储器? 您是否需要将该存储器内的值从 ISR 中发送出去? 为什么不增加 ISR 的堆栈并使用堆栈中的存储器?

    在 ISR 中使用 malloc 并不是一个好主意。 这种做法违反了所有建议。 在互联网上、您会发现很多人在讨论它是多么糟糕。

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jan、

    在每次中断期间、我需要分配一个48字节的内存、然后将读取的数据复制到这个内存中、 然后将该存储器放入任务读取队列中、以确保每个中断生成的数据完整且连续、因为如果使用了数组、数据将被覆盖、因此我需要在中断中添加 malloc 存储器。

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    这是一个可怕的想法,我并不惊讶它不起作用。 如何保护 ISR 中的 malloc 不被重新输入? 为什么不在 ISR 外部为消息队列分配内存? 为什么不使用内存池之类更高效的资源?

    malloc 所需的资源非常广泛。 您需要意识到、您使用的是80MHz MCU、而不是使用具有 GHz CPU 和大量 RAM 的计算机。

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jan、

    由于指针在消息队列中传递、如果使用数组传递数据、则很容易在从队列中读取数据之前覆盖数据。 或者、您是否有任何好的建议来替换中断 malloc 内存的这种方法?

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    也许 ISR 中的代码看起来是 malloc()简单而干净的,但这是地狱般的。 您似乎没有意识到有多少 CPU 周期花费了您简单的 malloc()调用,而您会惊讶于它如何破坏应用程序的时间行为。

    我看不出为什么在 ISR 外部分配的队列使用内存与覆盖未处理数据相关的任何原因。 当 malloc()在堆或内存中没有足够的空间用于消息队列已满时没有区别。

    内存池对象是更快分配内存的方法之一。 但最好还是避免在 ISR 内部进行动态内存分配。

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jan、

    如何分配除 ISR 之外的队列内存? 我在 interrupt_ Send()中使用了 MQ,将读取数据发送到队列。
    您可以说、您在中断中设置了标志位、然后在任务中执行数据读取和发送、但如何确保当中断中设置了标志位时、您转到任务来执行数据读取和发送? 任务调度的时间不确定、这可能导致数据读取和发送中断数次。

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    很抱歉我不明白。 在使用 ISR 之前、哪些因素会阻止您为消息队列分配内存? 个人而言、我在许多不同的项目中不使用 FreeRTOS、而是使用 TI-RTOS 和 ThreadX。 我通过这种精确的方式将队列与 ISR 一起使用。

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    int mq_send (mqd_t mqdes、const char * msg_ptr、size_t msg_len、unsigned int msg_prio);

    MQ_ Send ()仅将存储数据的第一个地址发送到队列,并非所有数据都逐个发送到队列。 我如何确保队列中的数据在每次被消耗之前不会被修改?

    如何确保发送到队列的数据的第一个地址是消耗数据之前的新空间?

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您是如何仅为指针创建队列的? 为什么不适用于整个48B。 请参阅用于 Queue 的 FreeRTOS 文档。

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    这是我根据例程创建的队列,MQ_SEND ()函数是否将数据直接复制到队列中,还是仅复制数据存储在队列中的第一个地址?

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    它复制您提供的内容。 TI-RTOS 或 FreeRTOS 可以使用消息队列和"任意"大小的消息、但例如 ThreadX 限制为16B。

    int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
            unsigned int msg_prio)
    {
        MQueueDesc *mqd = (MQueueDesc *)mqdes;
        MQueueObj  *msgQueue = mqd->msgQueue;
        BaseType_t  status;
        TickType_t  timeout;
    
        if (msg_len > (size_t)(msgQueue->attrs.mq_msgsize)) {
            if (!HwiP_inISR()) {
                errno = EMSGSIZE;
            }
            return (-1);
        }
    
        /*
         *  If O_NONBLOCK is not set, block until space is available in the
         *  queue.  Otherwise, return -1 if no space is available.
         */
        if (mqd->flags & O_NONBLOCK) {
            timeout = 0;
        }
        else {
            timeout = portMAX_DELAY;
        }
    
        if (HwiP_inISR()) {
            status = xQueueSendFromISR(msgQueue->queue, msg_ptr, NULL);
        }
        else {
            status = xQueueSend(msgQueue->queue, msg_ptr, timeout);
        }
    
        if (status != pdTRUE) {
            if (!HwiP_inISR()) {
                errno = EAGAIN;
            }
            return (-1);
        }
    
        return (0);
    }

    1月