吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

memheap死機問題的分析與解決

冬至子 ? 來源:張世爭 ? 作者:張世爭 ? 2023-06-07 14:56 ? 次閱讀

驗證環(huán)境

NUCLEO-L476RG 開發(fā)板,板載 STM32L476RGT6(96K SARM1 + 32K SRAM2)

Win10 64 位

Keil MDK 5.36

RT-Thread 5.0.1 版本(2023-05-28 master 主線)

bsp : bsp\\stm32\\stm32l476-st-nucleo

功能描述

最近在研究 RT-Thread 內(nèi)存的管理,熟悉了一下 memheap 的功能實現(xiàn),并且了解到 memheap 支持多塊內(nèi)存(物理地址不連續(xù))的管理,當(dāng)開啟 memheap 后,rt_malloc 可以遍歷所有注冊過的 memheap 內(nèi)存塊,并且進行 內(nèi)存的申請與釋放。

當(dāng)前 STM32L476RGT6 支持兩塊 SRAM,其中 SRAM1 96KB,還有一塊 SRAM2 32KB,SRAM2 默認沒有使用,嘗試開啟 SRAM2

環(huán)境搭建

stm32l476-st-nucleo 開啟 memheap 的方法

1.jpg

stm32l476-st-nucleo 開啟 SRAM2 的方法

#define HEAP_SRAM2_BEGIN (0x10000000)

#define HEAP_SRAM2_SIZE (32 * 1024)

static struct rt_memheap memheap_sram2;

int system_sram2_init(void)

{

return rt_memheap_init(&memheap_sram2, "sram2", (void *)HEAP_SRAM2_BEGIN, (rt_size_t)HEAP_SRAM2_SIZE);

}

INIT_BOARD_EXPORT(system_sram2_init);

功能測試

寫兩個測試命令:一直申請內(nèi)存直到無法申請內(nèi)存,一直釋放所以申請的內(nèi)存,確認 rt_malloc 會自動到新增加的 memheap SRAM2 中申請內(nèi)存

功能驗證通過,但是遇到死機問題

測試的函數(shù)

void *user_alloc(rt_size_t size)

{

return rt_memheap_alloc(&memheap_sram2, size);

}

void user_free(void *ptr)

{

rt_memheap_free(ptr);

}

void user_alloc_test(void)

{

for (int i = 0; i < MEMHEAP_BLOCK_NUM; i++)

{

user_ptr[i] = user_alloc(500);

if (!user_ptr[i])

{

rt_kprintf("malloc failed, index = %d\\n", i);

return;

}

else

{

rt_kprintf("[%d] : 0x%08x\\n", i, user_ptr[i]);

}

}

}

MSH_CMD_EXPORT(user_alloc_test, user_alloc_test);

void user_free_test(void)

{

for (int i = 0; i < MEMHEAP_BLOCK_NUM; i++)

{

if (user_ptr[i])

{

rt_kprintf("[%d] : 0x%08x\\n", i, user_ptr[i]);

user_free(user_ptr[i]);

}

}

}

MSH_CMD_EXPORT(user_free_test, user_free_test);

死機的信息

1.jpg

死機后,打印線程,發(fā)現(xiàn) idle 線程棧異常

1.jpg

開啟 CmBacktrace 組件后,發(fā)現(xiàn)死機的問題不是固定的,申請申請一個小內(nèi)存,都會觸發(fā)異常

問題分析

idle 線程的結(jié)構(gòu)數(shù)據(jù)被破壞了,這就說明,內(nèi)存越界了,但是測試例程只調(diào)用了 RT-Thread memheap 的 內(nèi)存申請與釋放 API,并沒有其他的操作

手動申請一塊內(nèi)存,沒有觸發(fā)死機, list thread 發(fā)現(xiàn),idle 線程的棧數(shù)據(jù),依舊是異常的!

1.jpg

由于 開發(fā)板可以 單步調(diào)試,所以經(jīng)過單步調(diào)試,加上分析,確認內(nèi)存的范圍,各個線程棧的內(nèi)存范圍,發(fā)現(xiàn)了一個奇怪的問題: 申請的內(nèi)存偶爾會與線程棧的【靜態(tài)內(nèi)存】重疊

由于死機問題并不是必現(xiàn),但是 idle 線程棧數(shù)據(jù)異常是必現(xiàn)的。當(dāng)前懷疑 memheap 的內(nèi)存范圍設(shè)置存在問題,通過對比其他開發(fā)板的 bsp,發(fā)現(xiàn)了問題所在。

原來 bsp stm32l476-st-nucleo 系統(tǒng)的內(nèi)存 HEAP_BEGIN 設(shè)置有問題,直接設(shè)置的 第一塊內(nèi)存的起始地址:

#define STM32_SRAM1_START (0x20000000)

#define HEAP_BEGIN STM32_SRAM1_START

初步看上去好像沒有問題,其實RT-Thread 開機后,靜態(tài)的內(nèi)存數(shù)據(jù)、線程棧,依舊會占用一些內(nèi)存,也就是其實內(nèi)存地址,不能設(shè)置為 STM32_SRAM1_START,而是 【剩余內(nèi)存】

【剩余內(nèi)存】或者叫【空閑內(nèi)存】的獲取方法如下:

#if defined(__ARMCC_VERSION)

extern int Image$$

RW_IRAM1

ZI

Limit;

#define HEAP_BEGIN ((void *)&Image

RW_IRAM1

ZI

Limit)
#elif ICCARM
#pragma section="CSTACK"
#define HEAP_BEGIN (__segment_end("CSTACK"))
#else
extern int __bss_end;
#define HEAP_BEGIN ((void *)&__bss_end)
#endif
如在 Keil MDK5 上,是 #define HEAP_BEGIN ((void *)&Image

RW_IRAM1

ZI$$Limit), 也就是 SRAM1 的 剩余內(nèi)存作為系統(tǒng) 堆內(nèi)存使用,而不是 SRAM1 的全部內(nèi)存作為 堆內(nèi)存使用

解決方法

如上,重新設(shè)置 HEAP_BEGIN 即可

編譯發(fā)現(xiàn) RW_IRAM1 不存在,需要修改鏈接文件:bsp\\stm32\\stm32l476-st-nucleo\\board\\linker_scripts\\link.sct,增加 RW_IRAM1 的定義

1.jpg

RW_IRAM1 0x20000000 0x00018000 { ; RW data

.ANY (+RW +ZI)

}

以上修改后,memheap 內(nèi)存測試通過,不再觸發(fā)死機

小結(jié)

memheap 使用起來還是比較的簡單,可以通過設(shè)置 開啟 RT_USING_MEMHEAP_AUTO_BINDING,也就是 勾選 [*] Use all of memheap objects as heap,決定新增加的 memheap 的內(nèi)存是否參與系統(tǒng)常規(guī)的內(nèi)存管理,如 rt_malloc、rt_free

用戶可以單獨的實現(xiàn)自己的 memheap 內(nèi)存塊 alloc、free 函數(shù),這樣只操作特定的 memheap。

當(dāng)前的一個小缺點:如果 memheap 內(nèi)存塊較多,超過2個,如 RAM1、RAM2、RAM3,并且開啟了 [*] Use all of memheap objects as heap,想實現(xiàn) RAM1與 RAM2 作為系統(tǒng)通用內(nèi)存管理,RAM3 用戶專用內(nèi)存管理,那么當(dāng)前的 memheap 機制做不到,因為 rt_malloc 依舊會在 RAM1、RAM2 不能申請內(nèi)存時,去 RAM3 申請內(nèi)存。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • RAM
    RAM
    +關(guān)注

    關(guān)注

    8

    文章

    1369

    瀏覽量

    115025
  • SRAM芯片
    +關(guān)注

    關(guān)注

    0

    文章

    65

    瀏覽量

    12162
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1305

    瀏覽量

    40391
  • STM32L476
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    3811
收藏 人收藏

    評論

    相關(guān)推薦

    求解,rtthread內(nèi)存管理部分memheap使用問題討論

    rtthread中源碼這部分memheap我看官方文檔中都說的很模糊,也沒有做過多的解釋說明,這個對于新手去使用這部分功能十分不友好,這里我有幾點看法和大家交流下,也先挖個坑占個位置。1.內(nèi)存連續(xù)
    發(fā)表于 04-19 09:34

    講解使用memheap內(nèi)存管理算法對內(nèi)部RAM和片外的SDRAM進行管理的方法

    if (ptr != RT_NULL) break;} } ... ... // 省去分析無關(guān)代碼 return ptr;}??分析上述源碼我們可以看到首先調(diào)用了 rt_memheap
    發(fā)表于 05-11 14:45

    請問rt_memheap_free引起的死機該如何解決呢?

    我使用了rtthread v4.0.4版本的內(nèi)核,并且開啟了RT_USING_MEMHEAP和RT_USING_MEMHEAP_AS_HEAP本來是將內(nèi)部ram和sdram合并成一個大的ram空間
    發(fā)表于 02-08 11:16

    rt_memheap_init初始化外部sram死機是何原因呢?

    的 //rt_memheap_init(&Strucmem,"memexram", rt_heap_exram,打開,即只要一初始化片外sram 就會死機,我該如何查呢 ?其中,片外sram 使用的fsmc 驅(qū)動
    發(fā)表于 02-20 15:09

    路由器死機掉線問題原因分析

    路由器死機掉線問題原因分析 今天,作者就對寬帶路由器死機掉線問題進行客觀分析,看看到底是什么原因造成了這些問題。
    發(fā)表于 10-20 09:21 ?1127次閱讀

    手機死機的原因有哪些?

    手機死機的原因有哪些? 我們對電腦的死機藍屏都習(xí)以為常,死機以后無非就是熱啟或者是RESET,但是我們對手機的死機常常抱怨,
    發(fā)表于 10-26 16:32 ?4072次閱讀

    筆記本重啟/死機 五項分析以及對策

    筆記本重啟/死機 五項分析以及對策 電腦包括筆記本電腦重啟和死機故障,都是電腦維修過程中的熱點問題,其中牽涉到的問題也
    發(fā)表于 01-19 11:00 ?360次閱讀

    路由器死機的原因分析

      本文主要給大家總結(jié)了路由器死機的四大類主要原因,并且就針對不同的問題給出了不同的解答,相信看過此文會對你以后解決死機問題有所幫助。   路由器死機
    發(fā)表于 08-19 11:53 ?484次閱讀

    電腦死機問題分析

      從電腦出現(xiàn)至今就一直被死機伴隨著,幾乎沒有誰的電腦從不遭遇死機。在使用過程中,偶爾一次死機應(yīng)該算是正常現(xiàn)象,如果經(jīng)常死機,電腦就存在一定的問題了。那么,
    發(fā)表于 08-19 14:51 ?623次閱讀

    Linux系統(tǒng)死機的軟硬件問題分析

      系統(tǒng)出現(xiàn)死機,一般分為兩種情況:一是硬件問題;二是軟件問題。   一、硬件問題   可以考慮分析以下幾點:   1、不要超頻CPU,如果已經(jīng)超
    發(fā)表于 09-25 10:57 ?2238次閱讀

    工控機死機現(xiàn)象分析

    死機是工控機故障中較為常見的一種,同時它也是最令人頭疼的一種。因為其故障點可大可小,而且產(chǎn)生死機的原因有很多種,另外其故障現(xiàn)象也是多種多樣的,我們可以把故障現(xiàn)象總的歸為兩大類一一規(guī)律性死機和隨機性
    發(fā)表于 10-23 14:10 ?11次下載

    PLC死機的軟件或硬件原因分析

    plc運行時可能會出現(xiàn)死機的情況,這給工業(yè)生產(chǎn)造成不可預(yù)估的損失,因此,首先要了解PLC死機的原因,針對原因進行排查,軟件或硬件錯誤都有可能導(dǎo)致PLC死機
    發(fā)表于 03-24 09:12 ?3054次閱讀

    RT-Thread 學(xué)習(xí)筆記:memheap 死機問題的分析與解決

    memheap 的功能實現(xiàn),并且了解到 memheap 支持多塊內(nèi)存(物理地址不連續(xù))的管理,當(dāng)開啟 memheap 后,rt_malloc 可以遍歷所有注冊過的 memheap 內(nèi)
    的頭像 發(fā)表于 05-29 18:05 ?1957次閱讀
    RT-Thread 學(xué)習(xí)筆記:<b class='flag-5'>memheap</b> <b class='flag-5'>死機</b>問題的<b class='flag-5'>分析</b>與解決

    變量位置不同會死機?郭天祥老師視頻的遺留問題分析答案

    在郭天祥老師視頻里有一個問題分享,是EXMC初始化里的一個變量定義和初始化位置不同會導(dǎo)致程序死機,最終定位到程序是進入hardfault死機,但暫時沒有后續(xù)分析了,這里我們來繼續(xù)分析
    的頭像 發(fā)表于 02-26 09:12 ?405次閱讀
    變量位置不同會<b class='flag-5'>死機</b>?郭天祥老師視頻的遺留問題<b class='flag-5'>分析</b>答案

    Air780E/Air780EP/Air780EQ/Air201模塊遇到內(nèi)存死機如何分析

    Air780E/Air780EP/Air780EQ/Air201模塊遇到內(nèi)存死機如何分析簡介本文檔適用于合宙Air780E、Air780EP、Air780EQ、Air201關(guān)聯(lián)文檔和使用工具:移芯
    的頭像 發(fā)表于 07-19 16:07 ?602次閱讀
    Air780E/Air780EP/Air780EQ/Air201模塊遇到內(nèi)存<b class='flag-5'>死機</b>如何<b class='flag-5'>分析</b>
    百家乐客户端软件| 澳门百家乐官网然后赢| 大发888注册奖金| 百家乐官网技巧技巧| 盈丰国际平台| 钱隆百家乐破解版| 免费百家乐官网的玩法技巧和规则| 澳门百家乐必胜| 贝博百家乐的玩法技巧和规则| 七匹狼百家乐官网的玩法技巧和规则| 拉斯维加斯娱乐| 娱乐百家乐下载| 百家乐接线玩法| 百家乐官网客户端软件| 六合彩公式| 赌场百家乐打法| 24向山九宫格图| 百家乐官网赢家| 屯门区| 大发888账号注册| 百家乐是否能赢| 黄金百家乐官网的玩法技巧和规则| 灵宝市| 大发888代理佣金| 在线百家乐合作| 墓地附近做生意风水| 百家乐官网投注程式| 澳门美高梅娱乐| 威尼斯人娱乐城评价| 足球百家乐网上投注| 大上海百家乐官网的玩法技巧和规则| 百家乐官网哪家有优惠| 天空娱乐城| 大发888娱乐城开户| 百家乐桌码合| 澳门百家乐打缆| 皇冠百家乐官网在线游戏| 百家乐官网是不是有假| 菲律宾太阳网| 大发888在线投注| 威尼斯人娱乐城 老品牌值得您信赖|