BabyOS-Protocol使用

本文介绍,BabyOS组件Protocol使用;

代码连接:https://gitee.com/notrynohigh/BabyOS_Example/blob/examples/example/protocol/stm32f107/main.c

 通过 USART1 接收与发送。

由外向内-代码分析

代码块1

此代码关注2处:

bTransFileInit();    // 发送文件初始化

bHalItInvoke(B_HAL_IT_UART_RX, B_HAL_UART_1, &param);    //通过串口中断接收每个字节

int main()
{
    BoardInit();

    SysTick_Config(SystemCoreClock / TICK_FRQ_HZ);
    NVIC_SetPriority(SysTick_IRQn, 0x0);

    bInit();

    bTransFileInit();
    
    while (1)
    {
        bExec();
    }
}
void USART1_IRQHandler()
{
    uint8_t       uart_dat = 0;
    bHalItParam_t param;
    param._uart.len  = 1;
    param._uart.pbuf = &uart_dat;
    if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
    {
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
        uart_dat = USART_ReceiveData(USART1);
        bHalItInvoke(B_HAL_IT_UART_RX, B_HAL_UART_1, &param);
    }
}

代码块2

//创建了 bProtoUart     结构体实例
bHAL_UART_CREATE_ATTR(bProtoUart, 1024, 100, _bProtoRevHandle, NULL);
//创建了 bProtol     结构体实例
B_PROT_SRV_CREATE_ATTR(bProtol, "bos", bProtoCallback);

//根据bProtoUart 实例参数,100ms 接收空闲中断 回调 _bProtoRevHandle
bHalUartReceiveIdle(B_HAL_UART_1, &bProtoUart);

// 查找bProtol -> name 与  b_srv_protocol 有没有匹配的,返回实例 bProtoUart 地址
sgSrvId = bProtSrvInit(&bProtol, NULL);
/*
bProtSrvId_t bProtSrvInit(bProtSrvAttr_t *attr, bProtSrvGetInfo_t func)
{
    if (attr == NULL)
    {
        return NULL;
    }
    bSECTION_FOR_EACH(b_srv_protocol, bProtocolInstance_t, instance)
    {
        if (strcmp(instance->name, attr->name) == 0)
        {
            attr->attr.get_info = func;
            attr->attr.package  = instance->package;
            attr->attr.parse    = instance->parse;
            break;
        }
    }
    if (attr->attr.parse && attr->attr.package)
    {
        return attr;
    }
    return NULL;
}
*/
//b_srv_protocol.c 
//bSECTION_DEF_FLASH(b_srv_protocol, bProtocolInstance_t); //68行

//b_mod_protocol.c
//bPROTOCOL_REG_INSTANCE("bos", _bProtocolParse, _bProtocolPackage); //320行

代码块3 BOS 私有通讯协议

/**
|      |                    |                     |       |          |       |
| :--- | ------------------ | ------------------- | ----- | -------- | ----- |
| Head | Device ID          | Len(cmd+param)    | Cmd   |  Param   | Check |
| 0xFE | sizeof(bProtoID_t) | sizeof(bProtoLen_t) | 1Byte | 0~nBytes | 1Byte |
*/

 Device ID 

 

在这个例程中,device id = 0;

使用效果

        经过上面初始化之后:

  1. 接收到1帧数据;        //串口中断接收 (硬件外设)
  2. 空闲100ms;             //空闲中断 (软件实现) 
  3. 这里接收回调;         //产生回调(软件实现)
static int _bProtoRevHandle(uint8_t *pbuf, uint16_t len, void *user_data)
//调用 bProtSrvParse 后
//调用_bProtocolParse 后
//解码成功会 回调 bProtoCallback

        

int bProtoCallback(bProtoCmd_t cmd, void *param)
{
    if (cmd == B_PROTO_TRANS_FILE_INFO)
    {
        bProtoFileInfo_t *p        = (bProtoFileInfo_t *)param;
        bTransFileRunParam.fsize   = p->size;
        bTransFileRunParam.f_crc32 = p->fcrc32;
    }
    else if (cmd == B_PROTO_SET_FILE_LOCATION)
    {
        bProtoFileLocation_t *p   = (bProtoFileLocation_t *)param;
        bTransFileRunParam.dev_no = p->dev;
        bTransFileRunParam.offset = p->offset;
        bTransFileRunParam.rlen   = 0;
    }
    else if (cmd == B_PROTO_FILE_DATA)
    {
        bProtoFileData_t *p = (bProtoFileData_t *)param;
        if (bTransFileRunParam.rlen == p->offset)
        {
            bLseek(sgFd, bTransFileRunParam.offset + bTransFileRunParam.rlen);
            bWrite(sgFd, p->dat, p->size);
            bTransFileRunParam.rlen += p->size;
            bSemRelease(sgSemId);
        }
    }
    return 0;
}

文件收发

B_TASK_CREATE_ATTR(bTransFileAttr);
B_SEM_CREATE_ATTR(bTransFileSemAttr);

这个例程中使用了一个线程与一个信号量实现,此处代码不是本篇文章的重点内容。

总结 

        BabyOS-Protocol 提供了一套 协议解析的框架;

        并提供了一套私有的bos 协议;

        可以很容易嵌入其他协议,如 

// proto_name \ref "bos": babyos私有协议
//                 "modbus", "xmodem128", "ymodem"
// callback \ref bProtSrvCallback_t
#define B_PROT_SRV_CREATE_ATTR(attr_name, proto_name, _callback) \
    static bProtSrvAttr_t attr_name = {                          \
        .name          = proto_name,                             \
        .attr.callback = _callback,                              \
        .attr.parse    = NULL,                                   \
        .attr.package  = NULL,                                   \
    }

        这是一个看上去很不错的框架,非常建议去了解一下这套框架;

        并且在你没有对比发现比这套框架更好的代码时候,非常建议你去实际使用一下它。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值