程序卡死如何定位错误

2019-07-21 03:31发布

我的程序主要是,定时器定时,每30S向传感器问询读数,我在数据接收的地方加入了RINGBUFFER(循环缓冲数组)之后进入定时中断,程序就会卡住。我的数据可以正常写入数组,也可以正常从循环缓冲数组中读出。RINGBUFFER主要参考的是机智云的代码;

************************************************************
* @file         ringbuffer.c
* @brief        Loop buffer processing
* @Author       Gizwits
* @date         2017-07-19
* @version      V03030000
* @copyright    Gizwits
*
* @note         Gizwits is only for smart hardware
*               Gizwits Smart Cloud for Smart Products
*               Links | Value Added | Open | Neutral | Safety | Own | Free | Ecology
*               www.gizwits.com
*
***********************************************************/
#include "ringBuffer.h"
#include "common.h"

rb_t DataRecievce;
uint8_t rbBuf[18];

/**********
创建环形缓冲区的函数
********************/
void RingbufferInit(void)
{   
    DataRecievce.rbCapacity =18;
    DataRecievce.rbBuff = rbBuf;
    if(0==rbCreate(&DataRecievce))
         {
          printf ("rbCreate success ");
         }
}

int8_t ICACHE_FLASH_ATTR rbCreate(rb_t* rb)  
{
    if(NULL == rb)
    {
        return -1;
    }
    rb->rbHead = rb->rbBuff;
    rb->rbTail = rb->rbBuff;
    return 0;
}

/*******
环形缓冲区删除函数
**********/
int8_t ICACHE_FLASH_ATTR rbDelete(rb_t* rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    rb->rbBuff = NULL;
    rb->rbHead = NULL;
    rb->rbTail = NULL;
    rb->rbCapacity = 0;
                return 0;
}

/****
获取环形缓冲区的容量
****/
int32_t ICACHE_FLASH_ATTR rbCapacity(rb_t *rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    return rb->rbCapacity;
}

/*******

*******/
int32_t ICACHE_FLASH_ATTR rbCanRead(rb_t *rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    if (rb->rbHead == rb->rbTail)
    {
        return 0;
    }

    if (rb->rbHead < rb->rbTail)
    {
        return rb->rbTail - rb->rbHead;
    }

    return rbCapacity(rb) - (rb->rbHead - rb->rbTail);
}

int32_t ICACHE_FLASH_ATTR rbCanWrite(rb_t *rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    return rbCapacity(rb) - rbCanRead(rb);
}

int32_t ICACHE_FLASH_ATTR rbRead(rb_t *rb, void *data, size_t count)
{
    int32_t copySz = 0;

    if(NULL == rb)
    {
        return 16;
    }

    if(NULL == data)
    {
        return 8;
    }

    if (rb->rbHead <= rb->rbTail)
    {
        copySz = min(count, rbCanRead(rb));
        memcpy(data, rb->rbHead, copySz);
        rb->rbHead += copySz;
        return copySz;
    }
    else
    {
        if (count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff))
        {
            copySz = count;
            memcpy(data, rb->rbHead, copySz);
            rb->rbHead += copySz;
            return copySz;
        }
        else
        {
            copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff);
            memcpy(data, rb->rbHead, copySz);
            rb->rbHead = rb->rbBuff;
            copySz += rbRead(rb, (char*)data+copySz, count-copySz);
            return copySz;
        }
    }
}

//将一定长度的数据(count)从某段地址(data)写入环形缓冲区
int32_t ICACHE_FLASH_ATTR rbWrite(rb_t *rb, const void *data, size_t count)
{
    int32_t tailAvailSz = 0;

    if((NULL == rb)||(NULL == data))
    {
        return -1;
    }

    if (count >= rbCanWrite(rb))
    {
        return -2;
    }

    if (rb->rbHead <= rb->rbTail)
    {
        tailAvailSz = rbCapacity(rb) - (rb->rbTail - rb->rbBuff);   //本次可写入的数量=环形数组容量—(尾指针地址-环形数组首地址)
        if (count <= tailAvailSz)
        {
            memcpy(rb->rbTail, data, count);
            rb->rbTail += count;
            if (rb->rbTail == rb->rbBuff+rbCapacity(rb))
            {
                rb->rbTail = rb->rbBuff;
            }
            return count;
        }
        else
        {
            memcpy(rb->rbTail, data, tailAvailSz);
            rb->rbTail = rb->rbBuff;

            return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);
        }
    }
    else
    {
        memcpy(rb->rbTail, data, count);
        rb->rbTail += count;
        return count;
    }
}

以上是机智云中的RINGBUFFER代码
下面是我向传感器问询及接收应答的代码(部分)

//串口2中断服务程序
void USART2_IRQHandler(void)
{       
         
        if((__HAL_UART_GET_FLAG(&huart2,UART_FLAG_RXNE)!=RESET))
        {
         uart2_buff[uart2_p++] =USART2->DR;//存入数组
        }
        if((__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)!=RESET))
        {
                __HAL_UART_CLEAR_IDLEFLAG(&huart2);
    rbWrite(&DataRecievce,uart2_buff,uart2_p);  //写入循环缓冲数列
        }
}


void getWinddirectionData()
{
                AskCmd((u8 *)WinddirectionAsk);
                DELAY;
                u8 *redata;
                //printf("缓冲区可读1:");
                //printf("%d",rbCanRead(&DataRecievce));
    rbRead(&DataRecievce,redata,7);   //从缓冲数组中读出数据
if(crcCheck(redata,7)==1)
{       
         SensorData.winddirection =        (redata[3]<<8 | redata[4] );  //这里我是要保存到结构体中,进行打包,形成报文上传(不会有错误)
         //rbDelete(&DataRecievce);
                 //printf("缓冲区可读0:");
                //printf("%d",rbCanRead(&DataRecievce));
}
         clean_rebuff2();
}


思路大概就是这样,如果不加缓冲数组没有错误,程序我们也用了很久了;
最近刚了解缓冲数组,想尝试添加,但是程序总是在定时器中断中卡住;
主要是,找不到错误的地方,大神也可以提供一下找错误的思路,谢谢;

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
03零三邓何芯桃
1楼-- · 2019-07-21 09:14
帮你顶帖问问吧
brucewoo
2楼-- · 2019-07-21 11:20
调试单步执行看看。
1599064432
3楼-- · 2019-07-21 14:17
设置断点,看看能不能进中断
1599064432
4楼-- · 2019-07-21 15:33
 精彩回答 2  元偷偷看……

一周热门 更多>