How to configure system resources
来自百问网嵌入式Linux wiki
Zhouyuebiao(讨论 | 贡献)2019年12月26日 (四) 16:09的版本
目录
如何配置系统资源
文章目的
- 本文介绍了如何配置在 Arm® Cortex®-A7 和 Arm® Cortex®-M4 上下文之间共享的 GPIO、EXTI、时钟和调节器系统资源。
- 在本文中,假定系统在生产启动模式下运行,其中Cortex-A7非安全上下文和Cortex-M4上下文都在运行。工程引导模式的特殊性不在此文中介绍。
简介
- 将外围设备分配给 Cortex®-M4 上下文时(有关详细信息,请参阅如何将内部外围设备分配给运行时上下文),开发人员必须注意在其与 Cortex®-A7 之间共享的系统资源进行配置。需要注意避免从Cortex®-A7和Cortex®-M4同时访问这些资源。
- 可以访问的系统资源:
- 从 Cortex®-A7 芯片:
- 在平台引导期间,通过U-Boot或TF-A进行引导(请参阅引导链概述),
- 在 Linux® 固件执行期间。
- 从 Cortex®-M4 到 STM32Cube 固件。
- 为了确保对这些系统资源的专有访问,在STM32MPU嵌入式软件发行版中实施了两种策略:
- 通过针对GPIO和EXTI配置的硬件信号量(请参见HSEM)进行保护,
- Cortex-A7 非安全上下文的独占访问。在这种情况下,Cortex-M4上下文依靠资源管理器通过Linux内核配置时钟和调节器。
通过硬件信号灯保护GPIO和EXTI系统资源
- HSEM的硬件信号灯保护GPIO和EXTI配置免受并发访问。
- 每个执行系统资源上下文的访问操作必须使用硬件信号量,以确保对GPIO和EXTI资源的关键寄存器的独占访问。
- 注意:开发人员必须确保在Cortex-A7非安全和Cortex-M4上下文中使用的硬件信号的一致性:在STM32MPU嵌入式软件发行版中,HSEM 0 和 HSEM 1 分别用于保护 GPIO 和 EXTI 的配置。
Cortex-A7安全上下文
- 在 STM32MPU 嵌入式软件发行版中,TF-A和OP-TEE不使用HSEM保护,因为尚未出现对 GPIO 和 EXTI 系统资源的并发访问的情况。但是,在安全的固件开发中必须考虑这种保护。
Cortex-A7非安全上下文
U-boot
- 由于U-Boot在启动Cortex-M4固件之前会配置系统资源,所以它不需要特殊保护。
Linux内核
- Linux 中的 GPIO和EXTI驱动程序使用信号量来防止访问寄存器:这些信号量在相应的设备树节点中定义:
exti: interrupt-controller@5000d000 {
compatible = "st,stm32mp1-exti", "syscon";
...
hwlocks = <&hsem 1>;
...
};
pinctrl: pin-controller@50002000 {
compatible = "st,stm32mp157-pinctrl";
...
hwlocks = <&hsem 0>;
...
}
Cortex-M4 上下文
- 在STM32Cube应用程序中,开发人员必须通过HSEM管理的硬件信号保护GPIO和EXTI配置寄存器。这可以通过使用锁定资源服务来完成。
- 注意:用于GPIO的HSEM 0和用于EXTI保护的HSEM 1的选择,在STM32Cube代码中有提及,并且在上述锁定资源服务中 可见:
void main(void)
{
GPIO_InitStruct.Pin = USER_BUTTON_PIN;
/*HW semaphore Clock enable*/
__HAL_RCC_HSEM_CLK_ENABLE();
PERIPH_LOCK(GPIOA);
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
PERIPH_UNLOCK(GPIOA);
...
PERIPH_LOCK(EXTI);
HAL_EXTI_SetConfigLine(&hexti, &EXTI_ConfigStructure);
PERIPH_UNLOCK(EXTI);
}
配置时钟和系统资源调节器
- 在Linux内核提供的服务,通过实施资源管理器,来控制时钟和调节分配给了 Cortex-M4 上下文中的外设配置:
- 在Cortex-M4启动之前,资源管理器会配置时钟和调节器。
- 在运行时,Cortex-M4 STM32Cube应用程序可以要求资源管理器更新时钟和调节器配置:
- 时钟频率
- 调节器设定
Cortex-A7非安全上下文上的系统资源管理器
- 资源管理器Linux内核驱动程序负责配置时钟和调节器,这些时钟和调节器用于操作分配给Cortex-M4上下文的外围设备。 这些配置在Linux内核设备树的m4_system_resources节点中定义。
- 为了帮助开发人员,Linux内核为可以分配给Cortex-M4上下文的大多数外围设备预定义了时钟系统资源:请参阅arch/arm/boot/dts/stm32mp157c-m4-srm.dtsi。
Cortex-M4上下文上的系统资源管理
- 由于时钟和调节器系统资源由Linux内核负责,因此Cortex-M4上下文不得直接配置以下系统资源:
- Cortex-M4不得设置这些资源的初始配置:这是由Linux内核完成的。
- Cortex-M4可以使用STM32Cube ResourceManager实用程序来更新这些资源的配置。
ADC示例
- 本示例描述了如何配置分配给 Cortex-M4 的ADC外设的系统资源。
Cortex-A7非安全上下文中的设备树
- 对Cortex-A7非安全上下文禁用Linux ADC设备节点(有关详细信息,请参见 如何将内部外围设备分配给运行时上下文 ):
&adc {
status = "disabled";
...
};
- 请注意,ADC时钟已经在 arch/arm/boot/dts/stm32mp157c-m4-srm.dtsi 中定义。
m4_adc: adc@48003000 {
compatible = "rproc-srm-dev";
reg = <0x48003000>;
clocks = <&rcc ADC12>, <&rcc ADC12_K>;
clock-names = "bus", "adc";
status = "disabled";
};
- 启用资源管理器
&m4_rproc {
m4_system_resources {
status = "okay";
};
};
- 为 Cortex-M4 启用Linux ADC资源节点并为其分配调节器
&m4_adc {
vref-supply = <&vdda>;
status = "okay";
};
在Cortex-M4上下文上的固件更新
- 无需任何实现即可将资源配置为初始状态。
- 下面的示例演示了如何更新ADC1稳压器配置:
- 初始化:
int main(void)
{
...
/* Initialize the ResourceManager with OpenAMP */
HAL_IPCC_Init(&hipcc);
OPENAMP_Init(RPMSG_REMOTE, NULL);
ResMgr_Init(NULL, NULL);
...
while (1)
{
/* ResourceManager with OpenAMP polling */
OPENAMP_check_for_message();
/* Application main processing */
...
}
- 调节器电压的更新:
config_in.regu.index = 0;
config_in.regu.enable = 1;
config_in.regu.min_voltage_mv = 1000;
config_in.regu.max_voltage_mv = 4000;
ResMgr_SetConfig(RESMGR_ID_ADC1, NULL, RESMGR_REGU, &config_in, &config_out);
log_info("Regulator voltage is now=%ld mv\n", config_out.regu.curr_voltage_mv);