- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用stm32+rtos实现一个基于spi flash的文件系统。对于freertos,我采用了heap_1实现。这就是我创建任务的方式。
osThreadDef(Task_Embedded, Task_VATEmbedded, osPriorityNormal, 0, 2500);
VATEmbeddedTaskHandle = osThreadCreate(osThread(Task_Embedded), NULL);
我为该线程分配了 10000 字节的内存。
并且在这个线程中。我尝试将数据写入闪存。在前几个电话中,它工作得很成功。但不知何故,当我尝试更多的写入时间时,它崩溃了。
VATAPI_RESULT STM32SPIWriteSector(void *writebuf, uint8_t* SectorAddr, uint32_t buff_size){
if(STM32SPIEraseSector(SectorAddr) == VAT_SUCCESS){
DBGSTR("ERASE SECTOR - 0x%2x %2x %2x", SectorAddr[0], SectorAddr[1], SectorAddr[2]);
}else return VAT_UNKNOWN;
if(STM32SPIProgram_multiPage(writebuf, SectorAddr, buff_size) == VAT_SUCCESS){
DBGSTR("WRTIE SECTOR SUCCESSFUL");
return VAT_SUCCESS;
}else return VAT_UNKNOWN;
return VAT_UNKNOWN;
}
.
VATAPI_RESULT STM32SPIProgram_multiPage(uint8_t *writebuf, uint8_t *writeAddr, uint32_t buff_size){
VATAPI_RESULT nres;
uint8_t tmpaddr[3] = {writeAddr[0], writeAddr[1], writeAddr[2]};
uint8_t* sectorBuf = malloc(4096 * sizeof(uint8_t));
uint8_t* pagebuf = malloc(255* sizeof(uint8_t));
memset(§orBuf[0],0,4096);
memset(&pagebuf[0],0,255);
uint32_t i = 0, tmp_convert1, times = 0;
if(buff_size < Page_bufferSize)
times = 1;
else{
times = buff_size / (Page_bufferSize-1);
if((times%(Page_bufferSize-1))!=0)
times++;
}
/* Note : According to winbond flash feature, the last bytes of every 256 bytes should be 0, so we need to plus one byte on every 256 bytes*/
i = 0;
while(i < times){
memset(&pagebuf[0], 0, Page_bufferSize - 1);
memcpy(&pagebuf[0], &writebuf[i*255], Page_bufferSize - 1);
memcpy(§orBuf[i*Page_bufferSize], &pagebuf[0], Page_bufferSize - 1);
sectorBuf[((i+1)*Page_bufferSize)-1] = 0;
i++;
}
i = 0;
while(i < times){
if((nres=STM32SPIPageProgram(§orBuf[Page_bufferSize*i], &tmpaddr[0], Page_bufferSize)) != VAT_SUCCESS){
DBGSTR("STM32SPIProgram_allData write data fail on %d times!",i);
free(sectorBuf);
free(pagebuf);
return nres;
}
tmp_convert1 = (tmpaddr[0]<<16 | tmpaddr[1]<<8 | tmpaddr[2]) + Page_bufferSize;
tmpaddr[0] = (tmp_convert1&0xFF0000) >> 16;
tmpaddr[1] = (tmp_convert1&0xFF00) >>8;
tmpaddr[2] = 0x00;
i++;
}
free(sectorBuf);
free(pagebuf);
return nres;
}
我打开调试器,当我在函数“STM32SPIProgram_multiPage”中分配“sectorbuf”时,它似乎崩溃了,令我困惑的是我在“malloc”之后释放了内存。有人知道吗?
arm-none-eabi-size "RTOS.elf"
text data bss dec hex filename
77564 988 100756 179308 2bc6c RTOS.elf
最佳答案
阅读the man
Memory Management
[...]
If RTOS objects are created dynamically then the standard C library malloc() and free() functions can sometimes be used for the purpose, but ...
they are not always available on embedded systems, they take up valuable code space, they are not thread safe, and they are not deterministic (the amount of time taken to execute the function will differ from call to call) ... so more often than not an alternative memory allocation implementation is required. One embedded / real time system can have very different RAM and timing requirements to another - so a single RAM allocation algorithm will only ever be appropriate for a subset of applications.
To get around this problem, FreeRTOS keeps the memory allocation API in its portable layer. The portable layer is outside of the source files that implement the core RTOS functionality, allowing an application specific implementation appropriate for the real time system being developed to be provided. When the RTOS kernel requires RAM, instead of calling malloc(), it instead calls pvPortMalloc(). When RAM is being freed, instead of calling free(), the RTOS kernel calls vPortFree().
[...]
(强调我的。)
所以意思是,如果直接使用malloc
,FreeRTOS
无法处理系统函数消耗的堆。如果您选择作为简单的 malloc
包装器的 heap_3
管理,则相同。
另请注意,您选择的内存管理没有免费功能。
heap_1.c
This is the simplest implementation of all. It does not permit memory to be freed once it has been allocated. Despite this, heap_1.c is appropriate for a large number of embedded applications. This is because many small and deeply embedded applications create all the tasks, queues, semaphores, etc. required when the system boots, and then use all of these objects for the lifetime of program (until the application is switched off again, or is rebooted). Nothing ever gets deleted. The implementation simply subdivides a single array into smaller blocks as RAM is requested. The total size of the array (the total size of the heap) is set by configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h. The configAPPLICATION_ALLOCATED_HEAP FreeRTOSConfig.h configuration constant is provided to allow the heap to be placed at a specific address in memory.
The xPortGetFreeHeapSize() API function returns the total amount of heap space that remains unallocated, allowing the configTOTAL_HEAP_SIZE setting to be optimised.
The heap_1 implementation:
Can be used if your application never deletes a task, queue, semaphore, mutex, etc. (which actually covers the majority of applications in which FreeRTOS gets used). Is always deterministic (always takes the same amount of time to execute) and cannot result in memory fragmentation. Is very simple and allocated memory from a statically allocated array, meaning it is often suitable for use in applications that do not permit true dynamic memory allocation.
(强调我的。)
附注:您必须始终检查malloc
返回值!= NULL
。
关于c - Freertos + STM32 - malloc 线程内存溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38782389/
我正在对 JVM 上的 STM 技术进行一些研究。阅读了一些文档后,我对 Multiverse 的实现有些困惑。 根据 the Multiverse FAQ , Multiverse 不支持检测。然而
我想知道 Clojure 怎么可能已经实现了软件事务内存并且没有发现任何问题,而微软没有完成它的 C# 工作并注意到一些问题使得实现这里描述的 STM 不切实际: http://www.bluebyt
最后,我有以下设置 C:>哪里玩 C:\apps\play-2.2.0\play C:\apps\play-2.2.0\play.bat C:> 哪里 scala C:\apps\scala\bin\
我试图找出 Clojure 所称的 STM 与 Haskell 中实现的 STM 之间的区别。撇开实际的语言语义差异不谈,正如 Rich Hickey 在他的演讲中所说,Clojure 的 STM 实
阅读 Bartosz Milewski 的精彩作品 blog post在 STM 上,我很兴奋地阅读了以下内容: But take into account an important fact: ST
大家好, 在某些时候,我认为这些 stm 实现(我使用过一点点的多元宇宙......),被过度宣传了。因为在某些时候他们使用 CAS 来为他们提供操作的原子性。如果我直接使用 CAS 而不是使用这些实
haskell 的 stm 库中有一个函数,其类型签名如下: alwaysSucceeds :: STM a -> STM () 根据我对 Haskell 中 STM 的了解,在执行 STM 计算时,
在 Clojure 中,我们使用 STM 来实现并发。 我的问题是STM使用数据的时间点值,这是否会带来歧义? 我们如何知道访问了什么值? 最佳答案 Clojure 中的 STM 提供了(通过 ref
我需要有关用作原子更改日志的数据结构的建议。 我正在尝试实现以下算法。有流量传入更改更新内存中的映射。在类似 Haskell 的伪代码中它是 update :: DataSet -> Some
我正在尝试对这两个(软件事务内存和原子操作,我想两者不一样)进行一些基准测试,尽管我没有使用STM做太多事情(它似乎很难使用),但我成功地尝试了对基准测试进行计数,即所有线程将共享计数器递增 5000
我能够使用 STM 初始化状态并将其打印出来: module Main where import Control.Concurrent.STM data State = State {name ::
我读过两个关于 STM 如何实现的完全不同的描述。也许两者都是正确的,或者一个是错误的,我希望有人能阐明这一点。 Take 1(维基百科):允许所有线程修改共享内存,但事务中的每次读写都会被记录下来。
我知道将具有副作用的函数放在 STM 事务中通常是不好的做法,因为它们可能会被重试和调用多次。 然而,在我看来,您可以使用代理来确保只有在事务成功完成后才会执行副作用。 例如 (dosync //
我正在编写一个程序,其中大量代理监听事件并对其使用react。由于Control.Concurrent.Chan.dupChan已弃用我决定使用 TChan 的广告。 TChan 的表现比我预想的差很
我正在研究 Clojure 中的并发编程。 http://clojure.org/concurrent_programming 我了解到atom、ref和agent形式是用来维护程序状态的。 仅ref
你好,我正在阅读《clojure 的乐趣》这本书,在关于 STM 的部分中,他们有一个 2 个事务的图像,其中 A 最初从引用中检索与 B 相同的值,然后事务 A 和 B 都进行计算但 A 首先完成并
我熟悉Database transactions ,并花费了大量的时间调整isolation levels 。我从未在代码中实现过自己的事务模型。 我已通读 the source code对于 Clo
我有一个事务由于某种原因无限期失败,我想在内部使用跟踪指令。例如,要在执行此片段中的事务之前打印 MVar 的状态: data_out do putTMVar
当我们运行 STM 表达式时,它命中了 retry,线程被阻塞,如果条目被修改,事务将再次运行。 但我想知道: 如果我们读取一个 STM 变量,但在导致重试的特定分支中实际未使用该变量,更新它是否会尝
我正在研究 Clojure 中的并发编程。 http://clojure.org/concurrent_programming 我了解到atom、ref 和agent 表单用于维护程序状态。 只有 r
我是一名优秀的程序员,十分优秀!