需要好好看看ld的script file了

本文详细探讨了在进程管理中遇到的问题及解决方法,包括父子进程间PID记录、子进程异常退出处理、进程间同步机制的改进等。此外,还讨论了在执行特定命令时如何避免数据丢失的问题,并提出了一种通过监控脚本来解决该问题的方法。最后,针对共享内存超出限制的情况,提出了调整内存布局的解决方案。

今天按照计划把原型推翻重新写了一遍,基本上还算顺利,但还是有些问题花了我不少的时间。

首先是fork之后,父进程需要记录子进程的pid,一遍在收到SIGCHLD信号时进行跟踪管理,没想到有时候子进程异常退出非常快,使得pid没有被记录到。虽然知道fork之后父子进程间的执行顺序是没有保证的,但是以前的应用可能不是很复杂吧。最后的方法是在子进程里面先sleep(1)保证父进程先得到执行的机会。这可能最土的方法了,不过这个只是在初始化阶段,对整个的影响不大。那位有更好的方法可以告诉我下,谢了。

reader和writer的同步采用改进后的方案后没有什么问题,但是新的问题是在执行load命令时只能关闭掉到mysql的链接才能使query语句返回,即使删掉fifo文件也不顶用,不知道这算不算是mysql connector C的一个bug呢?明天有时间发帖子问下。但是判断关闭连接的时间也是一个问题,因为此时IB的loader可能正在工作,close掉链接的话可能使得部分数据丢失或者出错。我打算做一个脚本来监控下,同时让用户自己选择关闭整个应用系统。这个需要做到loader进程的自动化管理,因为将来会有很多的reader进程,都是自动产生的。

今天还处理了下客户那里碰到的共享内存的问题,由于某个应用申请的共享内存超出了我们库里面提供的内存空间,导致应用初始化失败。这个应用很变态,我不知道为什么一定要用我们的库提供的封装而不是直接调用系统的API,负责这个应用的Leader也不能说服我,但是这位老大又不愿意更改。因为马上就到发布了,改动太大对应的测试就是很多,很难保证高质量。我想了很久才想到一种可能的解决方案,更改应用的内存布局,使得我们的库可以管理更多的内存空间,对Technique Leader讲将来如果要将server移植到linux的话再将应用更到一个更加合理的设计上去。这个方案目前看来是唯一的快捷方式,也许是唯一可行的,短时间内。所以原型一弄完就得接着这个来。

傍晚TL来问我进展,我老实告诉他我今天没有花什么时间在上面,大部分时间在调试原型,不过已经快好了,等弄得差不多了立马处理这个问题。TL的脸色显得不大好看:刚从我手下离开,就不听我的话了?呵呵!好在他还算是比较理解,答应我做完原型。半小时后总算是调试好原型,在wiki上吧上周没有总结的IB的一些问题共享了一下。立马开始调研这个问题,好在TL昨天给的网页很有用,不然我查ld和gcc的手册就得老半天了。明天得好好研究ELF和ld的script file,确认我的方案没有问题。

快过年了,事情真多啊!

### 如何通过 map 文件分析剩余可用 RAM 在嵌入式开发中,`map` 文件是由链接器生成的一个文本文件,它记录了程序的内存布局,包括各个模块占用的地址范围以及对应的存储区域(如 `.text`, `.data`, `.bss` 等)。要通过 `map` 文件分析剩余可用 RAM,以下是具体方法: #### 1. 查找目标硬件的总 RAM 容量 首先确认所使用的硬件平台及其总的 RAM 资源。例如,引用提到 BES2600IUC 系列有静态 RAM 和动态分配开销[^1];而 ESP32 则提供 520 KB 片上 SRAM 和可选的片外 SPI RAM 高达 4 MB[^2]。 #### 2. 找到 map 文件中的内存分布信息 打开由编译器生成的 `map` 文件,查找以下部分的关键字: - **Memory Configuration**: 显示设备上的不同存储区定义。 - **Section to Segment Mapping**: 表明哪些代码或数据段被放置在哪种类型的存储器中(如 ROM 或 RAM)。 通常可以看到如下结构的内容: ```plaintext Linker script and memory map ... .text 0x08000000 0x7c00 .data 0x20000000 0x1a8 load address 0x08007c00 .bss 0x200001a8 0xabc ``` 这里展示了三个主要的部分: - `.text`: 只读代码段位于闪存 (Flash),不会消耗 RAM; - `.data`: 初始化变量所在的 RAM 地址空间; - `.bss`: 未初始化全局/静态变量所在位置同样占据 RAM。 #### 3. 计算实际可用 RAM 大小 根据上述找到的信息计算剩余可用 RAM 数量时需要注意两点因素影响: - 已经明确标注出来的各分区大小之和; - 动态运行期间额外增加的大块内存需求,像音频处理或者通信过程中的缓冲池等临时开辟的空间——这可以从产品规格书得知固定数值,例如之前提及的约90KB损耗[^1]。 假设已知整个系统的初始静态分配详情,则最终真实可供第三方功能扩展利用的有效 RAM 应当是从原始总量扣除掉这些固定的预设值之后的结果。 #### 示例 Python 脚本解析 Map File 并统计 RAM Usage 下面给出一段简单的 python 脚本来帮助自动提取并汇总来自标准 GNU ld 输出格式的地图文档内的 ram 占用量统计数据: ```python import re def parse_map_file(map_filepath): with open(map_filepath, 'r') as f: content = f.read() sections = { '.data': {'address': None, 'size': 0}, '.bss' : {'address': None, 'size': 0} } pattern = r"(?P<section>\.\w+)\s+(?P<addr>0x[0-9a-f]+)\s+(?P<size>[0-9a-f]+)" matches = re.finditer(pattern, content) total_ram_used = 0 for match in matches: section_name = match.group('section') if section_name not in ['.data', '.bss']: continue addr = int(match.group('addr'), base=16) size = int(match.group('size'), base=16) sections[section_name]['address'] = addr sections[section_name]['size'] += size total_ram_used += size return sections, total_ram_used if __name__ == "__main__": sections_info, used_ram = parse_map_file('./example.map') print(f"Total Used RAM: {used_ram} bytes") for sec, info in sections_info.items(): print(f"{sec}: Address={info['address']:X}, Size={info['size']} bytes") ``` 此脚本能够快速定位`.data`与`.bss`两节各自的起始地址及长度,并累加得到当前项目启动后的基础RAM耗损状况。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值