OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2040|回复: 4

程序卡死如何定位错误

[复制链接]

9

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
152
金钱
152
注册时间
2018-12-5
在线时间
41 小时
发表于 2019-4-3 18:50:17 | 显示全部楼层 |阅读模式
我的程序主要是,定时器定时,每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\n");
         }
}

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();
}


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

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

153

主题

310

帖子

0

精华

高级会员

Rank: 4

积分
673
金钱
673
注册时间
2019-3-26
在线时间
18 小时
发表于 2019-4-4 14:02:38 | 显示全部楼层
http://www.iis7.com/c/90/
回复 支持 反对

使用道具 举报

8

主题

293

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1001
金钱
1001
注册时间
2018-8-16
在线时间
327 小时
发表于 2019-4-4 14:07:14 | 显示全部楼层
调试单步执行看看。
回复 支持 反对

使用道具 举报

22

主题

271

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
405
金钱
405
注册时间
2019-3-21
在线时间
107 小时
发表于 2019-4-4 14:09:27 | 显示全部楼层
设置断点,看看能不能进中断
回复 支持 反对

使用道具 举报

22

主题

271

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
405
金钱
405
注册时间
2019-3-21
在线时间
107 小时
发表于 2019-4-4 14:09:54 | 显示全部楼层
设置断点,看看能不能进中断
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 03:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表