没有详细信息的问题:
是否可以将从DDR运行的裸机可执行文件复制到处理器内部SRAM并运行它?此应用程序将暂停DDR并禁用电源轨以修复硬件问题。
详细信息:
我正在使用ARM处理器和运行嵌入式Linux的自定义嵌入式产品。处理器是Atmel ATSAMA5D36。我们正在使用以下辅助引导加载程序和内核:
当前启动过程大致如下:
设备以两种模式运行:连接到主电源或由电池备份。当连接到主电源时,可以发出一个命令来挂起linux,这会使我们的LPDDR内存进入自刷新模式。一旦LPDDR处于自刷新状态,主电源就可以被移除,LPDDR将持续到下一个上电周期。电路板上有一个小型辅助ARM Cortex-M0微控制器,可以一直运行,进行IO处理和其他一些与时间相关的任务。
问题:
当从电路板上移除主电源时,电池切换为LPDDR,辅助ARM微控制器供电,主SAMA5电源关闭。当从SAMA5断电并且电源电容器放电时,处理器短暂(100uS)变为褐色并迫使IO进入复位状态,然后关闭电源。不幸的是,电源中的“闪烁”将LPDDR CKE线拉高到足以使LPDDR退出自刷新模式。这会导致LPDDR上的内存损坏。
显示主电源电压和DDR_CKE信号的示波器图:
要解决此问题,我们需要暂停LPDDR,然后告诉PMIC禁用处理器上的DDR_IO电源(DDR的IO电源和主电源是独立的稳压器)。这样可以防止弹出LPDDR的电源短路自刷新。不幸的是,这是一个鸡蛋或鸡蛋问题。如果我们暂停LPDDR,我们就无法运行任何代码与PMIC通信并禁用特定供应。如果我们禁用电源,我们将无法再与LPDDR通信以使其自动刷新。
当前的解决方法:
当发出命令暂停主处理器时,它会将其转发到辅助微控制器,然后暂停LPDDR进行自刷新。然后,辅助微控制器重置主处理器并等待辅助引导加载程序出现。当引导加载程序启动时,它会检查微控制器以查看是否发出了挂起。如果是,它会将LPDDR置于自刷新状态,告诉PMIC(通过I2C)禁用DDR_IO电源,并等待(1)等待电源被移除。
这个问题是启动时间 - 从复位到DDR初始化和挂起需要120ms。 LPDDR的刷新周期为16-64ms,因此我们至少缺少一个DDR的刷新周期。到目前为止,在测试中我们没有看到由于这种延迟导致的内存损坏,但这显然是一个不太理想的解决方案(但比硬件修订更好)。
答案 0 :(得分:1)
回过头来回答这个问题。事实上,可以将代码从DRAM加载到SRAM中并执行它。经过进一步调查,我们发现许多嵌入式平台使用这种方法来处理电源管理功能,特别是暂停/恢复 - 就像我在这里试图解决的问题一样。
以下是linux如何在at91平台上处理暂停:http://lxr.free-electrons.com/source/arch/arm/mach-at91/pm.c#L416
我们需要对此进行自定义实现,最终创建了一个使用相同方法的内核模块。然后我们从user-land插入了内核模块,它为我们提供了一种从SRAM运行代码来执行电源管理功能的方法。
#include <linux/io.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#define VIRT_BASE 0xFEF78000 //for AT91
static void (*sram_fn)(void) = NULL;
unsigned char buf[] = {
//your complied ARM byte code
};
static void __init init_sram_fn (void)
{
sram_fn = (void *) (VIRT_BASE – sizeof(buf));
memcpy(sram_fn, &buf, sizeof(buf));
sram_fn();
}
static void __exit cleanup_sram_fn (void){}
module_init(init_sram_fn);
module_exit(cleanup_sram_fn);
system("insmod custom_pm_module.ko");
答案 1 :(得分:0)
是否可以将从DDR运行的裸机可执行文件复制到处理器内部SRAM并运行它?
根据您的平台,这是非常难以实现的。 Linux内核本身是从DRAM运行的,所以当DRAM关闭时,你将没有实时Linux内核,也没有任何OS服务(没有系统调用,没有调度程序,没有irqs / irq处理程序;如果它在dram中没有irq向量?)。
你的芯片只有128 KB的SRAM:http://www.atmel.com/devices/ATsama5d36.aspx?tab=parameters - 它只是小到包含完整的Linux内核。
因此,您可以尝试创建一些可执行文件,将其优先级更改为RT(实时)以便能够忽略调度程序/ irqs ...您应该将此可执行文件完全放入SRAM(仅当SRAM可以用作直接寻址内存)...你还应该检查它是否需要它,它将被加载(或者你应该让可执行文件在核心上一直运行吗?它是多核芯片吗?)
写这个不是可执行文件,但作为内核的一部分可能更容易......但任务看起来仍然不可能......
在关闭DRAM之前DRAM和CPU运行的时间是什么时候?
DRAM可以保存数个刷新周期;它将保留大部分数据数秒(冷却时间更长 - https://en.wikipedia.org/wiki/Cold_boot_attack;热时更短)。您可能想要添加一些数据校验和...(您的芯片没有用于DRAM的ECC?)