OpenEdv-开源电子网

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

stm32f103c8t6运行FREERTOS进入HardFault

[复制链接]

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2017-7-25
在线时间
44 小时
发表于 2018-3-27 20:10:41 | 显示全部楼层 |阅读模式
5金钱
如题,原来整个系统运行是没问题的,然后在一次烧录之后程序就一直卡死了,程序本身并没有变。。。。。。(这个就很头疼)
debug了后发现进入了HardFault,使用show caller code查看后发现是在freertos的 taskSELECT_HIGHEST_PRIORITY_TASK();
主程序也发现一旦使用了DMA+ADC就会出现上述问题,如果加了DMA 程序会一直运行到freertos的任务调度那后才会死掉,希望大佬能帮忙看下问题在哪。。




下面附上DMA+ADC的代码:

void adcDMAInit(void)
{
        ADC_InitTypeDef ADC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
        DMA_InitTypeDef DMA_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1, ENABLE);
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
       
        //gpio set
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
        DMA_DeInit(DMA1_Channel1);
        DMA_InitStructure.DMA_BufferSize = 256; //cache size
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //send data direction
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //disable RAM to RAM
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&adValue; //target address
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //16-bit width
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //target address increase
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //cycle mode
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //peripheral's address
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //16-bit width
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //unchange peripheral's address
        DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA has high priority
        DMA_Init(DMA1_Channel1,&DMA_InitStructure);
       
        DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); //enable DMA's interrupt
       
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
       
        ADC_DeInit(ADC1);
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //right align
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
        ADC_InitStructure.ADC_NbrOfChannel = dmaWays; //need to conver x channels
        ADC_InitStructure.ADC_ScanConvMode = ENABLE;
        ADC_Init(ADC1, &ADC_InitStructure);
       
        //2 channels
        ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_55Cycles5);
//        ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);
       
        ADC_DMACmd(ADC1,ENABLE);
        ADC_Cmd(ADC1,ENABLE);
       
        ADC_ResetCalibration(ADC1); //start the reseting of the calibration
        while(ADC_GetResetCalibrationStatus(ADC1));        //waiting for reseting the calibration
        ADC_StartCalibration(ADC1);         //start the calibration
        while(ADC_GetCalibrationStatus(ADC1));         //waiting for calibration
       
        DMA_Cmd(DMA1_Channel1,ENABLE); //until ADC already setted, enable the DMA
        ADC_SoftwareStartConvCmd(ADC1,ENABLE); //start ADC's auto-converion
}

void DMA1_Channel1_IRQHandler(void)
{
        u16 i,j;
        u32 sum = 0;
        if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
        {
                DMA_ClearITPendingBit(DMA1_IT_TC1);
                for(j=0;j<dmaWays;j++)
                {
                        sum = 0;
                        for(i=j;i<128*dmaWays;i+=dmaWays)
                        {
                                sum += adValue[i];
                        }
                        averValue[j] = ((sum>>7)*33)>>12;
                }
        }
}

最佳答案

查看完整内容[请看2#楼]

把DMA中断优先级调到5至15这个范围,我记得FreeRTOS可管理 的中断是在这个范围。同时在DMA中断中不要有太多处理,定义一个事件标志组来处理。同时 你的DMA应该数据处理,要注意把你的任务堆栈大小改大一点,避免任务切换时溢出,这样同样会进入HardFault。这个情况我遇到 过。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

46

主题

200

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1128
金钱
1128
注册时间
2016-3-25
在线时间
365 小时
发表于 2018-3-27 20:10:42 | 显示全部楼层
本帖最后由 Mr.liu 于 2018-3-27 21:14 编辑

把DMA中断优先级调到5至15这个范围,我记得FreeRTOS可管理 的中断是在这个范围。同时在DMA中断中不要有太多处理,定义一个事件标志组来处理。同时 你的DMA应该数据处理,要注意把你的任务堆栈大小改大一点,避免任务切换时溢出,这样同样会进入HardFault。这个情况我遇到 过。
代写STM32各类驱动,DEMO程序
回复

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2017-7-25
在线时间
44 小时
 楼主| 发表于 2018-3-29 00:20:00 | 显示全部楼层
Mr.liu 发表于 2018-3-27 20:10
把DMA中断优先级调到5至15这个范围,我记得FreeRTOS可管理 的中断是在这个范围。同时在DMA中断中不要有太多 ...

问题解决了 我把DMA里用于存放adc转换值的数组改大了点就正常了 结论应该是数组越界。。但是理论上分析数组并不会越界。。在裸跑的时候并不会出问题。。对该数组应用计算也是正常的。。加了RTOS就出问题,可能还是堆栈的问题把
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-8 22:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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