9.FreeRTOS内存管理简易分析

FreeRTOS Heap简易分析

  • 架构:Cortex-M3
  • 版本:FreeRTOS V9.0.0
  • 前言:队列、任务、信号量等都是需要内存来保存的,FreeRTOS提供了五种分配内存的方式。

1.Heap1.c

直接找到heap1.c来分析

可以看到,代码并不多,至少能说明heap1的分配内存方式应该是很简单的。

从代码中可以看出,heap1只有分配,没有释放。

那么我们具体看分配函数pvPortMalloc

void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn = NULL;
static uint8_t *pucAlignedHeap = NULL;

	/* Ensure that blocks are always aligned to the required number of bytes. */
	#if( portBYTE_ALIGNMENT != 1 )
	{
		if( xWantedSize & portBYTE_ALIGNMENT_MASK )
		{
			/* Byte alignment required. */
			xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
		}
	}
	#endif

	vTaskSuspendAll();
	{
		if( pucAlignedHeap == NULL )
		{
			/* Ensure the heap starts on a correctly aligned boundary. */
			pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
		}

		/* Check there is enough room left for the allocation. */
		if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
			( ( xNextFreeByte + xWantedSize ) > xNextFreeByte )	)/* Check for overflow. */
		{
			/* Return the next free byte then increment the index past this
			block. */
			pvReturn = pucAlignedHeap + xNextFreeByte;
			xNextFreeByte += xWantedSize;
		}

		traceMALLOC( pvReturn, xWantedSize );
	}
	( void ) xTaskResumeAll();

	#if( configUSE_MALLOC_FAILED_HOOK == 1 )
	{
		if( pvReturn == NULL )
		{
			extern void vApplicationMallocFailedHook( void );
			vApplicationMallocFailedHook();
		}
	}
	#endif

	return pvReturn;
}

​ 首先是字节对齐,根据不同硬件,字节对齐的长度不同。Cortex-M3是以8字节对齐的时候访问内存是更快的。heap1处理字节对齐是 &0x07,然后加上portBYTE_ALIGNMENT - xWantedSize & portBYTE_ALIGNMENT_MASK 这个值,就可以做到字节对齐了。

​ 如果是第一次分配的话,会先检查ucHeap是否处于字节对齐的位置,计算出对齐的位置后赋值给pucAlignedHeap,那么以后分配内存的时候都是以pucAlignedHeap的位置来开始分配。

​ 分配内存时,会检查当前内存够不够分、有没有出现溢出的问题。xNextFreeByte是个全局变量,表示当前这个堆已经分配的大小,每次都会加上分配的内存大小,通过这个值,至少能得出当前用了多少RAM还剩多少WRAM可用

​ heap1初始化图解:

2.heap2.c

heap2比heap复杂一下,重点在于分配和释放时,是以一种机制来操作的。

2.1申请内存

首先看prvHeapInit

static void prvHeapInit( void )
{
BlockLink_t *pxFirstFreeBlock;
uint8_t *pucAlignedHeap;

	/* Ensure the heap starts on a correctly aligned boundary. */
	pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) &
### 使用Python实现微信公众号内容的网络爬虫 为了构建一个能够抓取微信公众号内容的网络爬虫,可以采用多种方法和技术栈组合。考虑到目标网站可能具有复杂的JavaScript渲染机制,`Selenium`是一个不错的选择[^3]。 #### 导入必要的库 首先安装并导入所需的库: ```bash pip install selenium requests lxml beautifulsoup4 webdriver_manager ``` 接着,在脚本中引入这些模块: ```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service as ChromeService from webdriver_manager.chrome import ChromeDriverManager import time ``` #### 初始化浏览器实例 创建一个函数用于初始化Chrome WebDriver实例,并设置一些基本参数: ```python def init_driver(): options = webdriver.ChromeOptions() options.add_argument('--headless') # 设置无头模式运行 driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) return driver ``` #### 访问页面并获取数据 定义另一个函数负责访问指定URL以及提取所需的数据: ```python def fetch_wechat_articles(driver, public_account_name): base_url = "https://weixin.sogou.com/weixin" params = { 'query': public_account_name, '_sug_type_': '', 'sut': '', 'lkt': '', 'page': 1, 'ie': 'utf8', 'type': 1 } search_query = f"{base_url}?{urllib.parse.urlencode(params)}" driver.get(search_query) try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "news-list")) ) articles = [] items = element.find_elements(By.CSS_SELECTOR, ".txt-box h3 a") for item in items[:5]: # 只取前五篇文章链接为例 title = item.text.strip() link = item.get_attribute('href') articles.append({"title": title, "link": link}) return articles except Exception as e: print(f"Error occurred while fetching articles: {e}") return None ``` 此部分代码通过模拟搜索引擎查询特定公众号名称的方式找到对应的文章列表页,并从中解析出每篇推文的具体链接地址。 #### 处理HTML实体字符转义问题 当处理从网页上抓取下来的文本时,可能会遇到HTML实体编码的问题。对于这个问题,建议使用`html`标准库中的unescape方法替代已经过时的方法[^4]: ```python import html escaped_text = "<p>This is an example.</p>" unescaped_text = html.unescape(escaped_text) print(unescaped_text) # 输出:<p>This is an example.</p> ``` 以上就是利用Python编写的简单版微信公众号文章抓取器的主要组成部分。需要注意的是实际开发过程中还需要考虑更多细节如异常处理、反爬策略应对等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值