如何配置系统资源

来自百问网嵌入式Linux wiki
Zhouyuebiao讨论 | 贡献2020年1月6日 (一) 15:47的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)


如何配置系统资源

文章目的

本文介绍了如何配置在 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非安全上下文中的设备树

	&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);