一个设备接口实例(迭代)

[复制链接]
11947|18
手机看帖
扫描二维码
随时随地手机跟帖
keer_zu|  楼主 | 2021-12-24 07:43 | 显示全部楼层


接口的定义:

simple.h

#ifndef __SAMPLE_H__
#define __SAMPLE_H__

#include "k_list.h"

#ifndef NULL
#define NULL ((void *)0)
#endif


typedef struct {
        int (*on_info_recv)(void *);
        int (*sample)(void *);
}sample_methods_t;


typedef struct {
        char *name;
        struct list_head dev_node;
        sample_methods_t* methods;
        void *pdev;
}sample_interface_t;


int register_sampler(sample_interface_t *devi);
int run_sample(void);



#endif


使用特权

评论回复
keer_zu|  楼主 | 2021-12-24 07:44 | 显示全部楼层
注册和运行:
simple.c
#include <stdio.h>
#include "sample.h"
#include "os_depend.h"

struct list_head g_samplers;

int register_sampler(sample_interface_t *dev)
{
        if(dev == NULL) {
                printf("%d: devi is NULL!\n",__LINE__ + 1);
                return -__LINE__;
        }
       
        if(dev->name == NULL || dev->methods == NULL) {
                printf("%d: name or methods or method is NULL!\n",__LINE__ + 1);
                return -__LINE__;
        }

       
        ENTER_CRITICAL();
        list_add(&dev->dev_node,&g_samplers);
        EXIT_CRITICAL();
       
        return 0;
}

int run_sample(void)
{
        sample_interface_t *pos;
        list_for_each_entry(pos,&g_samplers,dev_node) {
                if(pos->methods->sample != NULL) {
                        pos->methods->sample(pos->pdev);
                }
        }
       
        return 0;
}


使用特权

评论回复
keer_zu|  楼主 | 2021-12-24 07:45 | 显示全部楼层
接口的实现之485:头文件:simple_485.h

#ifndef __SAMPLE_485_H__
#define __SAMPLE_485_H__

#include "k_list.h"

typedef struct {
        char *name;
        struct list_head node;
}sample_485_t;


int sample_485_init(void);



#endif


使用特权

评论回复
keer_zu|  楼主 | 2021-12-24 07:46 | 显示全部楼层
接口的实现之485:simple_485.c


#include <stdio.h>
#include "sample.h"
#include "sample_485.h"
#include "os_depend.h"

static int sample_485(void *param)
{
        sample_485_t *dev485;
        if(param ==NULL){
                printf("%d: param NULL!\n",__LINE__ + 1);
                return -__LINE__;
        }

        list_for_each_entry(dev485,(struct list_head *)param,node) {

        }
       
        return 0;
}

static int on_485_recv(void *param)
{
        if(param ==NULL){
                printf("%d: param NULL!\n",__LINE__ + 1);
                return -__LINE__;
        }
       
        return 0;
}


sample_methods_t sample_485_methords = {
        .sample = sample_485,
        .on_info_recv = on_485_recv
};

sample_485_t g_sampler_485;

static struct list_head dev_485_head;

sample_interface_t dev_485 = {
        .name = "485",
        .pdev = &dev_485_head,
        .methods = &sample_485_methords
};


int sample_485_init(void)
{
        INIT_LIST_HEAD(&dev_485_head);

        int ret = register_sampler(&dev_485);
       
        return ret;
}

int add_485_sample_dev(struct list_head *node)
{
        ENTER_CRITICAL();
        list_add(node,&dev_485_head);
        EXIT_CRITICAL();
        return 0;
}


使用特权

评论回复
keer_zu|  楼主 | 2021-12-24 07:48 | 显示全部楼层
接口的实现之can:头文件:simple_can.h


#ifndef __SAMPLE_CAN_H__
#define __SAMPLE_CAN_H__

#include "k_list.h"

typedef unsigned char (*CAN_MODE_INIT_FUN)(unsigned char,unsigned char,unsigned char,unsigned short,unsigned char);
typedef int (*CAN_RECV_MSG)(unsigned char *,unsigned int *,unsigned char *);
       

typedef struct {
        char *name;
        unsigned char tsjw;
        unsigned char tbs2;
        unsigned char tbs1;
        unsigned short brp;
        unsigned char mode;
        CAN_MODE_INIT_FUN init;
        CAN_RECV_MSG recv_msg;
        struct list_head node;
}sample_can_t;


int sample_can_init(unsigned char);


#endif


使用特权

评论回复
keer_zu|  楼主 | 2021-12-24 07:49 | 显示全部楼层
接口的实现之can:simple_can.c


#include <stdio.h>
#include "sample.h"
#include "sample_can.h"
#include "Device_info.h"
#include "os_depend.h"

extern ConfigCan_Info_t        CAN_Info;

static int sample_can(void *param)
{
        sample_can_t *can;
        if(param ==NULL){
                printf("%d: param NULL!\n",__LINE__ + 1);
                return -__LINE__;
        }

        list_for_each_entry(can,(struct list_head *)param,node) {
                if(can->recv_msg!= NULL) {
                        //printf("+++++++++ name:%s\n",can->name);
                        //pos->init(pos->tsjw,pos->tbs2,pos->tbs1,pos->brp,pos->mode);
                }
        }
       
        return 0;
}

static int on_can_recv(void *param)
{
        if(param ==NULL){
                printf("%d: param NULL!\n",__LINE__ + 1);
                return -__LINE__;
        }
       
        return 0;
}


sample_methods_t sample_can_methords = {
        .sample = sample_can,
        .on_info_recv = on_can_recv
};

static struct list_head dev_can_head;



int add_can_sample_dev(struct list_head *node)
{
        ENTER_CRITICAL();
        list_add(node,&dev_can_head);
        EXIT_CRITICAL();
        return 0;
}


sample_can_t g_sampler_can1 = {
        .name = "can1",
        .tsjw = CAN_SJW_1tq,
        .tbs2 = CAN_BS2_3tq,
        .tbs1 = CAN_BS1_10tq,
        .brp  = 12,
        .mode = CAN_Mode_Normal,
        .init = CAN1_Mode_Init,
        .recv_msg = CAN1_Receive_Msg_Ex
};
sample_can_t g_sampler_can2 = {
        .name = "can2",
        .tsjw = CAN_SJW_1tq,
        .tbs2 = CAN_BS2_3tq,
        .tbs1 = CAN_BS1_10tq,
        .brp  = 12,            //CAN1初始化成功 波特率为 250K
        .mode = CAN_Mode_Normal,
        .init = CAN2_Mode_Init,
        .recv_msg = CAN2_Receive_Msg_Ex
};


static int sample_can_start(unsigned char channel)
{
        switch(channel) {
                case 0x00: //默认不开启can       
                        printf("\r\nCAN不初始化\r\n");
                        break;
                case 0x01: //开启can1
                        add_can_sample_dev(&g_sampler_can1.node);
                        break;
                case 0x02: //开启can2
                        add_can_sample_dev(&g_sampler_can2.node);
                        break;
                case 0x03: //开启can3
                        add_can_sample_dev(&g_sampler_can1.node);
                        add_can_sample_dev(&g_sampler_can2.node);
                        break;
                default:
                        break;
        }

        return 0;
}

static sample_interface_t dev_can = {
                .name = "can",
                .pdev = &dev_can_head,
                .methods = &sample_can_methords
        };


int sample_can_init(unsigned char channel)
{

        INIT_LIST_HEAD(&dev_can_head);
               
       
        sample_can_t *pos;

        sample_can_start(channel);

        list_for_each_entry(pos,&dev_can_head,node) {
                if(pos->init != NULL) {
                        printf("+++++++ can init:init:0x%x  pos->tsjw:%d\n",pos->init,pos->tsjw);
                        pos->init(pos->tsjw,pos->tbs2,pos->tbs1,pos->brp,pos->mode);
                }
        }

        int ret = register_sampler(&dev_can);
       
        return ret;
}



使用特权

评论回复

评分

参与人数 1威望 +10 收起 理由
qin552011373 + 10 很给力!
keer_zu|  楼主 | 2021-12-24 07:51 | 显示全部楼层
更新完毕,欢迎关注,@qin552011373

@21ic小管家 @21小跑堂 请给个原创和编辑推荐,以上内容包括代码都是原创

使用特权

评论回复
qin552011373| | 2021-12-24 12:51 | 显示全部楼层
代码这样子写的话,太清晰了,搞起来好舒服

使用特权

评论回复
keer_zu|  楼主 | 2021-12-24 13:58 | 显示全部楼层
qin552011373 发表于 2021-12-24 12:51
代码这样子写的话,太清晰了,搞起来好舒服

多谢鼓励

使用特权

评论回复
qin552011373| | 2021-12-25 18:19 | 显示全部楼层

可以考虑有时间就来分享给我学习下

使用特权

评论回复
keer_zu|  楼主 | 2021-12-27 08:14 | 显示全部楼层
qin552011373 发表于 2021-12-25 18:19
可以考虑有时间就来分享给我学习下

想要分享什么?

使用特权

评论回复
qin552011373| | 2021-12-27 15:29 | 显示全部楼层

这些接口就很值得学习啊,其他没有炫出来就不清楚了

使用特权

评论回复
li880wert| | 2021-12-29 13:49 | 显示全部楼层
好多次我写项目涉及到LCD 时候都想 做前后台,前台画界面,注册事件(按键,信号,IO),然后后台处理回调,但是写着写着,就开始骂自己SB了
单片机这玩意 本来就是简单易用为主,搞些这应用 ,把本来可以写简单的程序 ,多占用了几KB ROM.
就像ST写的USB库样,本来 就是 几十行代码搞定的,经过ST的层层封装 整个几千行代码

使用特权

评论回复
keer_zu|  楼主 | 2021-12-30 13:05 | 显示全部楼层
li880wert 发表于 2021-12-29 13:49
好多次我写项目涉及到LCD 时候都想 做前后台,前台画界面,注册事件(按键,信号,IO),然后后台处理回调, ...

有多少单片机系统刚开始就为了”简单易用”的目的,后来越来越不简单易用了,到后来自己都看不下去了,软件开发是需要花心思的活,今天花的心思是为了明天少花心思。
现在的单片机系统越来越不简单了,特别是平台不如其他系统友好

使用特权

评论回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则