专栏名称: 嵌入式微处理器
关注这个时代最火的嵌入式微处理器,你想知道的都在这里。
目录
相关文章推荐
新京报评论  ·  DeepSeek成了“老中医”?AI能看病但 ... ·  昨天  
求是网  ·  健全主体明确、要求清晰的责任体系 ·  昨天  
CHINADAILY  ·  跑鞋,是越贵越好吗? ·  2 天前  
外交部发言人办公室  ·  外交部发言人介绍中方担任上合组织轮值主席国阶 ... ·  3 天前  
外交部发言人办公室  ·  【双语】外交部例行记者会 / MFA ... ·  3 天前  
51好读  ›  专栏  ›  嵌入式微处理器

函数调用在嵌入式架构设计中的应用

嵌入式微处理器  · 公众号  ·  · 2024-05-13 10:40

正文

1、前言

函数调用很好理解,即使刚学没多久的朋友也知道函数调用是怎么实现的,即调用一个已经封装好的函数,实现某个特定的功能。

把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口,然后在其他地方调用即可

2、函数调用方式

函数调用难道还能怎么调用?不就封装好直接调用吗?

函数调用方式分为两种: 直接调用 间接调用

直接调用

直接调用就是我们平常使用的方式,下面的方式就属于直接调用了。

int SumFun(int a, int b)
{
    return a + b;
}

int main()
{
    // 直接调用定义好的函数
    int sum = SumFun(56);
    printf("sum=%d", sum);
    return 0;
}

间接调用

间接调用在初学时很难使用到,这是通过 函数指针 的方式实现的。

函数指针 本质是一个指针变量,是一个指向函数的指针(函数本身也是有地址的,指向的是函数入口);
指针函数 本质是一个函数,其返回值为指针。

函数指针的用法如下:

typedef int (*FunctionCB)(intint);

int SumFun(int a, int b)
{
    return a + b;
}

int main()
{
    // 将定义好的函数赋值给函数指针
    FunctionCB pfnSum = SumFun;

    // 通过函数指针间接调用
    int sum = pfnSum(56);
    printf("sum=%d", sum);
    return 0;
}

3、什么场景使用

函数指针在软件架构分层设计中十分重要,因为分层设计中有一个设计原则,那就是 下层函数不能直接调用上层函数 ,那么可以通过函数指针的方式实现;一般称上层通过函数指针赋值给下层的函数为 回调函数

什么情况会存在需要下层程序需要调用上层程序的呢?
比如串口数据接收,虽然可以通过查询的方式接收,但是远不及通过串口中断的方式接收及时,当接收完成时,需要立即通知上层读取数据进行处理,而不是等待上层程序查询读取。

如何实现呢?

比如,硬件抽象层/驱动层中的串口模块实现函数。

/************* UART.c 文件 ****************/
static UartRecvCB sg_pfnUartRecv;

// 设置数据帧接收处理回调函数
void UART_SetRecvCallback(UartRecvCB pfnUartRecv)
{
    sg_pfnUartRecv = pfnUartRecv;
}

void UART_Task(void)
{
    if (RecvEnd)
    {
        // 数据一帧接收完成立即调用
        if (sg_pfnUartRecv != NULL)
        {
            sg_pfnUartRecv(UartRecvBuf, UartRecvLength);
        }
    }
}

/************* UART.h 文件 ****************/
typedef void (*UartRecvCB)(const char *, int);

extern void UART_SetRecvCallback(UartRecvCB pfnUartRecv);
extern void UART_Task(void);

应用层代码中实现回调函数,并调用下层函数。

// 回调函数:串口数据处理
void OnUartRecvProcess(const char *pBuf, int length)
{
    // 处理串口数据
    printf("Recv: %s", pBuf);
}

int main()
{
    UART_SetRecvCallback(OnUartRecvProcess);

    while(1






请到「今天看啥」查看全文