手把手教你学BSP(二)--BSP的作用

目录

1. 硬件抽象

主要特点:

示例代码(STM32 HAL库):

2. 初始化硬件

主要任务:

示例代码(ARM Cortex-M3为例):

3. 设备驱动

主要任务:

示例代码(Linux驱动程序):

4. 启动加载程序(Bootloader)

主要功能:

示例代码(U-Boot):

总结


下面将详细介绍BSP(Board Support Package)中的四个关键概念:硬件抽象(通过HAL实现)、硬件初始化、设备驱动以及启动加载程序(Bootloader)的功能及其重要性。

1. 硬件抽象

硬件抽象(Hardware Abstraction)是指通过软件层(通常是HAL)将硬件的具体实现细节隐藏起来,从而使得操作系统可以更加容易地移植到不同的硬件平台上。硬件抽象的主要目的是提供一个统一的接口,让操作系统能够以一致的方式访问不同的硬件设备。

主要特点:
  • 硬件独立性:HAL层将硬件的细节抽象出来,使得操作系统可以在不同的硬件平台上运行,而无需修改代码。
  • 简化开发:开发人员只需要关注HAL提供的API,而不需要关心硬件的具体实现。
  • 易维护性:当更换硬件平台时,只需要修改HAL层即可,无需改动操作系统核心代码。
示例代码(STM32 HAL库):
 

c

深色版本

void HAL_InitTick(void)
{
    /* Configure the systick timer as a source of an interrupt */
    SysTick_Config(SystemCoreClock / HAL_MAX_DELAY);
}

void HAL_Delay(uint32_t Delay)
{
    uint32_t tickstart = HAL_GetTick();

    if (Delay != 0U)
    {
        while((HAL_GetTick() - tickstart) < Delay)
        {
            /* Keep looping until the remaining delay is reached */
        }
    }
}

2. 初始化硬件

硬件初始化是指在操作系统启动之前,通过一系列的代码来配置和设置硬件设备,确保它们处于可用状态。这个过程非常重要,因为只有在硬件被正确初始化之后,操作系统才能顺利加载并运行。

主要任务:
  • 处理器初始化:设置CPU寄存器,配置处理器的工作模式。
  • 内存初始化:配置内存控制器,设置内存映射,分配内存区域。
  • 时钟初始化:配置系统时钟,确保各外设能够正常工作。
  • 中断控制器初始化:配置中断控制器,设置中断优先级和向量表。
  • 外设初始化:初始化I/O端口、定时器、ADC、DAC、SPI、I2C、UART等外设。
示例代码(ARM Cortex-M3为例):
 

c

深色版本

void SystemInit(void) {
    // 设置系统时钟
    RCC->CR |= RCC_CR_HSEON;         // 开启外部高速时钟
    while ((RCC->CR & RCC_CR_HSERDY) == 0) {} // 等待HSE稳定
    RCC->CFGR &= ~RCC_CFGR_SW_Msk;   // 设置系统时钟源为HSE
    RCC->CFGR |= RCC_CFGR_SWS_1;     // 设置系统时钟源为HSE
    RCC->CFGR &= ~RCC_CFGR_PLLON_Msk; // 关闭PLL
    RCC->CFGR |= RCC_CFGR_PLLON;     // 开启PLL
    while ((RCC->CFGR & RCC_CFGR_PLLRDY) == 0) {} // 等待PLL稳定
    RCC->CFGR &= ~RCC_CFGR_SW_Msk;   // 设置系统时钟源为PLL
    RCC->CFGR |= RCC_CFGR_SW_PLL;    // 设置系统时钟源为PLL

    // 配置AHB/APB1/APB2时钟
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // AHB频率为系统频率
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // APB1频率为系统频率的一半
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; // APB2频率为系统频率的一半

    // 使能GPIO时钟
    RCC->APB2ENR |= RCC_APB2ENR_GPIOAEN | RCC_APB2ENR_GPIOBEN;

    // GPIO初始化
    GPIOA->MODER = (1 << GPIO_MODER_MODER0_Pos); // 设置PA0为输出模式
}

3. 设备驱动

设备驱动程序是操作系统与硬件设备之间的通信桥梁,它为操作系统提供了一种与硬件设备进行交互的方式。设备驱动程序通常需要完成以下几项任务:

主要任务:
  • 硬件初始化:在设备首次使用前对其进行初始化。
  • 设备控制:提供一组API函数,用于控制硬件设备的状态和行为。
  • 数据传输:实现数据的读写操作,如读取传感器数据、发送指令给执行器等。
  • 错误处理:检测并处理硬件故障或异常情况。
示例代码(Linux驱动程序):
 

c

深色版本

static int my_device_open(struct inode *inode, struct file *file) {
    /* 设备打开时的处理 */
    return 0;
}

static int my_device_release(struct inode *inode, struct file *file) {
    /* 设备关闭时的处理 */
    return 0;
}

static ssize_t my_device_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
    /* 读取数据 */
    return count;
}

static ssize_t my_device_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
    /* 写入数据 */
    return count;
}

static const struct file_operations my_fops = {
    .owner = THIS_MODULE,
    .open = my_device_open,
    .release = my_device_release,
    .read = my_device_read,
    .write = my_device_write,
};

static int __init my_driver_init(void) {
    /* 注册设备驱动 */
    register_chrdev(DEVICE_NR, DEVICE_NAME, &my_fops);
    return 0;
}

static void __exit my_driver_exit(void) {
    /* 卸载设备驱动 */
    unregister_chrdev(DEVICE_NR, DEVICE_NAME);
}

module_init(my_driver_init);
module_exit(my_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple character device driver");

4. 启动加载程序(Bootloader)

启动加载程序(Bootloader)是系统启动时最先运行的程序之一,它的主要职责是引导操作系统启动。Bootloader通常具有以下功能:

主要功能:
  • 硬件初始化:初始化硬件设备,如内存、时钟等。
  • 加载内核:将操作系统内核从存储介质(如闪存)加载到内存中。
  • 启动内核:跳转到内核的入口点,开始执行内核代码。
  • 故障恢复:提供一定的故障恢复机制,如检测并修复启动错误。
示例代码(U-Boot):
 

c

深色版本

int board_init_f(int flag)
{
    /* Initialize common hardware */

    /* Enable clocks */
    enable_clocks();

    /* Setup GPIO pins */
    setup_gpio();

    /* Setup memory controller */
    setup_memory_controller();

    /* Setup UART */
    setup_uart();

    /* Setup NAND flash */
    setup_nand_flash();

    return 0;
}

int do_bootm(cmd_table_t *cmdtp, int flag, int argc, char *argv[])
{
    ulong loadaddr, entrypoint;
    int ret;

    /* Load kernel image */
    loadaddr = load_kernel_image();

    /* Set entry point */
    entrypoint = get_entry_point(loadaddr);

    /* Jump to kernel */
    ret = jump_to_kernel(entrypoint);

    return ret;
}

总结

通过上述介绍,你已经了解了BSP中硬件抽象(通过HAL实现)、硬件初始化、设备驱动以及启动加载程序(Bootloader)的基本概念和实现方法。每部分都是BSP不可或缺的一部分,它们共同作用以确保嵌入式系统的正常启动和运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值