六.面向对象的嵌入式底层开发-LED(C面向对象开发)

内容参考于《抽象接口技术和组件开发规范及其思想》、《面向ametal框架和接口的C编程》

六.面向对象的嵌入式底层开发-LED

Ametal中LED的实现

资源图
在这里插入图片描述

1. demo_std_led.c

demo属于应用层。am_led_on和am_led_off属于通用接口,通用接口的第一个参数表示要操作的具体对象。一个系统可能有多颗LED,为每一颗LED分配一个ID号。通过ID形式隐藏了底层的对象和指针,对APP层更加友好,不被非业务的逻辑所影响。通过ID能查找到对象,但是,ID和对象并非是一对一的,一个对象可以拥有几个ID,可以理解为,主设备号(对象)下拥有这多个次设备号(ID)

#include "ametal.h"
#include "am_led.h"
#include "am_delay.h"

void demo_std_led_entry (int led_id)
{
   
   
    while (1) {
   
   
        am_led_on(led_id);
        am_mdelay(500);
        am_led_off(led_id);
        am_mdelay(500);
    }
}
2. am_led.h(LED标准接口)

demo_std_led.c依赖于am_led.h

#ifndef __AM_LED_H
#define __AM_LED_H

#ifdef __cplusplus
extern "C" {
   
   
#endif

#include "am_common.h"

int am_led_set(int led_id, am_bool_t state);
int am_led_on(int led_id);
int am_led_off(int led_id);
int am_led_toggle(int led_id);

#ifdef __cplusplus
}
#endif

#endif /* __AM_LED_H */
3. am_led_dev.c(通用LED设备管理器)

通用接口的实现

  1. 先看看int am_led_on (int led_id)和int am_led_off (int led_id),发现其实整个的核心代码是int am_led_set (int led_id, am_bool_t state)int am_led_toggle (int led_id),这两个函数屏蔽了底层的差异,无论底层如何变化(GPIO或者HC595),其使用p_dev->p_funcs->pfn_led_setp_dev->p_funcs->pfn_led_toggle即可,这部分下面再进行细讲。
  2. am_led_dev_t * __led_dev_find_with_id(int id),其通过ID号查找到对象,将对象屏蔽在底层。
  3. 一般来说,在嵌入式底层,对象都是确定的,有几个LED,有几个UART,在硬件设计那一刻就确定了,代码通过宏进行声明。应用层启动前会对对象进程初始化,再进入应用。把LED对象,挂在 *static am_led_dev_t __gp_head 这个链表下面,这部分下面再进行细讲。
#include "ametal.h"
#include "am_led.h"
#include "am_led_dev.h"
#include "am_int.h"

static am_led_dev_t *__gp_head;

static am_led_dev_t * __led_dev_find_with_id (int id)
{
   
   
    am_led_dev_t *p_cur   = __gp_head;

    int key = am_int_cpu_lock();

    while (p_cur != NULL) {
   
   

        if ((id >= p_cur->p_info->start_id) &&
            (id <= p_cur->p_info->end_id)) {
   
   

            break;
        }

        p_cur = p_cur->p_next;
    }

    am_int_cpu_unlock(key);

    return p_cur;
}

static int __led_dev_add (am_led_dev_t *p_dd)
{
   
   
    int key = am_int_cpu_lock();

    /* add the device to device list */
    p_dd->p_next = __gp_head;
    __gp_head    = p_dd;

    am_int_cpu_unlock(key);

    return AM_OK;
}

static int __led_dev_del (am_led_dev_t *p_dd)
{
   
   
    int            ret     = -AM_ENODEV;
    am_led_dev_t **pp_head = &__gp_head;
    am_led_dev_t  *p_prev  = AM_CONTAINER_OF(pp_head, am_led_dev_t, p_next);
    am_led_dev_t  *p_cur   = __gp_head;
  
    int key = am_int_cpu_lock();

    while (p_cur != NULL) {
   
   
        if (p_cur == p_dd) {
   
   

            p_prev->p_next = p_dd->p_next;
            p_dd->p_next   = NULL;
            ret            = AM_OK;
            break;
        }

        p_prev = p_cur;
        p_cur  = p_cur->p_next;
    }

    am_int_cpu_unlock(key);

    return ret;
}

int am_led_dev_lib_init (void)
{
   
   
    __gp_head = NULL;

    return AM_OK;
}

int am_led_dev_add (am_led_dev_t             *p_dev,
                    const am_led_servinfo_t  *p_info,
                    const am_led_drv_funcs_t *p_funcs,
            
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值