如何解耦外设(UART)的应用程序和驱动程序代码时构造嵌入式应用程序?

问题描述 投票:1回答:2

因此,我正在STM32上编写UART驱动程序,尽管我对布局结构有一定的想法,但我仍然想在实现之前进行澄清,并且还要考虑保持代码整洁的必要性且井井有条。

所以我有main.csensor.c(使用UART层的应用程序文件),hal_usart.c(这是驱动程序文件)。

我听说过有关应用程序代码如何不了解驱动程序API的不同观点,并且有一天读了一篇文章,您可以使用函数指针将传感器代码与HAL驱动程序代码分离,但不确定如何做在这里,如果考虑到我仍在传递对USART_Handle结构的引用,该结构包含baudRate,parityControl,wordLength,对USART_TypeDef的引用等信息,则将其解耦,

下面是我的想法的摘要:

// main.c
static USART_Handle pUSART;

int main(void) {
   // initialize clocks/HAL 

   // ...initialize USART struct

   // Get data via UART (calling application API)
   GetData(&pUSART);   
}

// sensor.c (application)
void GetData(USART_Handle *pUSART) {
     HAL_USART_TX(); 
     HAL_USART_RX();   // assuming data is stored in one of the struct members
}

// hal_usart.c  (Driver file)
void HAL_USART_TX() {} 
void HAL_USART_RX() {}



c embedded stm32 uart hal
2个回答
1
投票

如果要在程序运行时更改指针,则函数指针的效用最大。或者换句话说,当您具有至少两个不同的功能,并且根据某种条件,您想要使用一个或另一个。

例如,假设您有一个例程,该例程使用一个串行端口读取传感器,并且用户可以从一个传感器切换到另一个传感器(两个串行端口,甚至两种不同的方法)。在这种情况下,传感器例程可以调用函数,以使用函数指针进行读取,并管理反向读取的数据。通过更改功能指针,主程序可以指示传感器例程使用一个或另一个传感器。

如果您不需要在运行时进行更改,则只需编写传感器例程,使其调用其他文件中定义的读取函数(外部)即可。传感器例程的文档仅必须声明必须在某个地方定义一个名为“ int sensor_get_data()”的例程。

这涉及根据来自“分离的驱动程序”的数据来往和设计,来设计自己的“内部协议”。例如,处理传感器的精确模型的传感器例程可能需要发送命令并接收响应。您可以编写用于构造命令并解码答案的传感器例程,并删除将所有它们包装在单个函数“ int sensor_get_data(int command)”中的低级详细信息。然后,您可以链接或包含传感器代码,并在主代码中实现功能sensor_get_data()。

main()不知道传感器的详细信息,它仅知道传感器代码在需要时将调用函数sensor_get_data()。但是,该功能可以使用UART,i2c或spi,而传感器例程甚至不会注意到这一点。此外,该例程可以使用这三个端口中的任何一个,也许基于用户可以在运行时修改的参数。

所有这些都可以称为“回调机制”,并且实现了声明和实现之间的某种分离,如另一个答案中所述。我描述的内容与此没有什么不同,但它是static-程序使用固定的回调进行编译,而不是在每次调用中都传递函数指针。


0
投票

由于您想在嵌入式系统中分离应用程序代码和驱动程序代码,因此建议您研究如何在C嵌入式系统中实现回调函数。

这里是reference

© www.soinside.com 2019 - 2024. All rights reserved.