LiteOS学习笔记-2外设驱动移植方法


此文参考华为云官方社区多篇文章,如有侵权,请联系删除。

一、裸机驱动是什么?

驱动层代码,简单通俗的来说就是向上给用户提供一层可以控制设备的API,向下负责和设备打交道,直接操作硬件。
比如LED的驱动代码可以给用户提供一个初始化的 API 和打开/关闭的 API ,按键的驱动代码可以提供初始化的 API 和读取按键状态的 API,LCD的驱动代码可以提供初始化的 API 和屏幕上显示相关内容的API,传感器的驱动代码可以提供传感器初始化的API 和读取数据的 API,等等。
这里以使用 STM32CuebMX 生成的 LED 闪烁的裸机工程为例,其中 Src 目录下的gpio.c文件就相当于 LED 的驱动层文件,其中提供了 LED 的初始化代码:

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);

}

如果是比较简单的外设,比如LED,按键这种,只使用了GPIO,可以直接使用STM32CubeMX生成的gpio.c文件和gpio.h文件;
如果是比较复杂的外设,比如LCD的底层是使用SPI驱动的,那么除了 STM32CubeMX 生成的spi.h和spi.c文件,还需要自己在此基础上手写LCD屏幕的驱动文件。

二、移植步骤

1.复制裸机驱动文件

工程文件结构
其中和设备驱动相关的有三个文件夹:

  • Inc:对应STM32CubeMX生成裸机工程中的Inc
  • Src: 对应STM32CubeMX生成裸机工程中的Src
  • Hardware:存放自己编写的设备驱动代码
    复制文件的时候按照情况复制到对应的文件夹即可。如LED相关的代码文件只有gpio.h和gpio.c,所以复制gpio.h到 Inc 文件夹,复制gpio.c到 Src 文件夹。

2.添加裸机驱动文件路径

因为 LiteOS 的整个项目工程使用 make 构建,所以复制驱动文件之后,需要添加驱动文件的路径到 makefile 中,加入编译。
project.mk文件指明了工程中所有文件的路径。
在该文件中:
C文件路径

  • HARDWARE_SRC:对应Hardware文件夹下的Src文件夹
  • USER_SRC:对应Src文件夹
    头文件路径
  • HARDWARE_INC:对应Hardware文件夹下的Inc文件夹
  • USER_INC:对应Inc文件夹
    如LED驱动的gpio.c文件默认已添加到USER_SRC下,gpio.h文件添加到USER_INC下。
    至此,复制文件到LiteOS工程中,并将新复制的文件路径添加到makefile中,加入工程编译,就完成了驱动的移植。

三、使用驱动

1. 初始化外设

在使用外设之前,首先需要初始化外设,在LiteOS中,初始化设备有两种方式:

  • 在系统启动调度之前初始化:设备在系统中随时可被任意任务使用。如LED可能在任意任务中调用以打开关闭LED。

在任务中初始化:设备一般只在该任务中被使用。如像光照强度传感器这种驱动,一般都是有专门的数据采集任务,专门去读取传感器数据,不需要别的线程去调用驱动读取数据,所以放在该数据采集任务中初始化就可以。

在系统启动之前调用初始化API

在 Src 文件夹下的main.c中,main函数如下:

int main(void)
{
    UINT32 uwRet = LOS_OK;
    HardWare_Init();
    uwRet = LOS_KernelInit();
    if (uwRet != LOS_OK)
    {
        return LOS_NOK;
    }

    extern void shell_uart_init(int baud);
    shell_uart_init(115200);

    if(!link_test())
    {
        LCD_ShowString(30, 170, 240, 16, 16, "Connect NET OK");
    }
    (void)LOS_Start();
    return 0;
}

可以看到,系统上电后首先调用 HardWare_Init 函数初始化硬件设备,然后初始化内核,初始化shell,初始化网络连接,最后启动LOS内核。

HardWare_Init函数的实现
VOID HardWare_Init(VOID)
{
	HAL_Init();
	/* Configure the system clock */
	SystemClock_Config();
	MX_GPIO_Init();
	MX_I2C1_Init();
	MX_SPI2_Init();
	dwt_delay_init(SystemCoreClock);
	LCD_Init();					
	LCD_Clear(BLACK);
	POINT_COLOR = GREEN;
 	LCD_ShowString(30, 170, 240, 16, 16, "Connecting NET......");
}

2. 调用外设

创建文件夹,在文件夹下创建源文件用以编写相关代码。
将源文件添加到makefile中
修改config文件添加对应宏

四、小熊派E53扩展板

E53接口

E53接口标准的E取自扩展(Expansion)的英文首字母,板子的尺寸为5×3cm,故采用E53作为前缀来命名尺寸为 5cm*3cm 类型的案例扩展板,任何一款满足标准设计的开发板均可直接适配E53扩展板。

E53扩展板是根据不同的应用场景来设计的,以最大的程度在扩展板上还原真实应用场景,不同案例的扩展板根据不同的应用场景来命名后缀。例如:E53_SC1,SC是智慧城市(Smart City)的缩写,SC1表示的是智慧城市中的智慧路灯,再比如SC2则表示的是智慧城市中的智慧井盖。

E53扩展接口在电气特性上,包含了常用的物联网感知层传感器通信接口,比如5V、3.3V、GND、SPI、UART、IIC、ADC、DAC等等,可以适配各种传感器,还留有4个普通GPIO,如图:
在这里插入图片描述

移植使用

参照上述步骤即可完成扩展板移植,然而除了操作project.mk外,可在userdemo.mk中动态添加。直接在user_demo.mk中配置,只有当开启了该demo后,才会添加这些驱动文件路径,不会造成冲突。

#example for oc_agriculture_template
ifeq ($(CONFIG_USER_DEMO), "oc_agriculture_template")	
	user_demo_src  = ${wildcard $(TARGET_DIR)/Demos/oc_agriculture_template/*.c}
	user_demo_inc = -I $(TARGET_DIR)/Demos/oc_agriculture_template
	user_hardware_src = ${wildcard $(TARGET_DIR)/Hardware/E53_IA1/*.c} 
	user_hardware_inc = -I ${wildcard $(TARGET_DIR)/Hardware/E53_IA1}
	user_demo_defs = -D CONFIG_OC_ARRICULTURE_DEMO_ENABLE=1
	
endif
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值