bootloader+APP程序,FreeRTOS不运行问题记录

博主写完bootloader后,APP程序这边不管怎么样freeRTOS都不运行,最基本的LED闪烁任务创建都有问题,

bootloader主函数如下:

#include "main.h"
#include "user_header.h"



typedef  void ( *pFunction )( void );

pFunction   Jump_To_Application; //函数指针
uint32_t    JumpAddress = 0;


void delay_1( void )
{
	uint16_t nTime = 0x0000;

	for( nTime = 0; nTime < 0x0FFF; nTime++ ) {
	}
}

void BKP_RtcInit( void )
{
	/* enable PMU clock */
	rcu_periph_clock_enable( RCU_PMU );
	rcu_periph_clock_enable( RCU_RTC );
	/* enable the access of the RTC registers */
	pmu_backup_write_enable();//使能对BKP寄存器的访问
}


int main( void )
{
    //systick_config();
	static uint16_t timeOutCnt = 0;
	BSP_Init();
	BKP_RtcInit();
	printf( "APP\n" );
	//BKP_DATA6 = 0x0000;
	if( ( BKP_DATA6&BKP_BOOT )== BKP_BOOT ) { //APP跳转过来
		printf( "APP Enter Boot Succeed" );
		//响应APP接收
		transmit_message.tx_data[0] = 0x60;
		transmit_message.tx_data[1] = 0x55;
		transmit_message.tx_data[2] = 0x22;
		transmit_message.tx_data[3] = 0xff;
		transmit_message.tx_data[4] = 0xff;
		transmit_message.tx_data[5] = 0xff;
		transmit_message.tx_data[6] = 0xff;
		CAN_ProtocolSendData( CF,7 ); 

		usartProtocol_str.functionCode = 0x11;
		usartProtocol_str.Data[0] = 0x22;
		usartProtocol_str.Data[1] = 0xff;
		usartProtocol_str.Data[2] = 0xff;
		usartProtocol_str.Data[3] = 0xff;
		usartProtocol_str.Data[4] = 0xff;
		UART_ProtocolSendData( usartProtocol_str.functionCode,usartProtocol_str.Data,5 );
	}

	while( 1 ) {
		if( ( BKP_DATA6&BKP_BOOT ) == BKP_APP ) {
			if( ( BKP_DATA6&BKP_REAL_APP )!= BKP_REAL_APP ) { //APP运行区域数据是否有效		
				if( ( ( *( __IO uint32_t * )AppRealAddress ) & 0x2FFE0000 ) == 0x20000000 ) { //ApplicationAddress为新程序的起始地址,检查栈顶地址是否合法,即栈顶地址是否为0x2000xxxx(内置SRAM)
					printf( "JMP TO APP" );
					can_interrupt_disable( CAN0, CAN_INTEN_RFNEIE1 ); //FIFO1
					can_interrupt_disable( CAN0, CAN_INTEN_RFNEIE0 ); //FIFO0
					NVIC_ClearPendingIRQ( SysTick_IRQn );
					usart_disable( USART0 );
					usart_disable( USART2 );
					/*配置跳转到用户程序复位中断入口*/
					JumpAddress = *( __IO uint32_t * )( AppRealAddress + 4 );           //用户代码区第二个字存储为新程序起始地址(新程序复位向量指针)
					/*将地址指针强制转换成函数指针*/
					Jump_To_Application = ( pFunction ) JumpAddress;
					/*设置栈*/
					__set_MSP( *( __IO uint32_t * ) AppRealAddress );                   //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
					/*跳转*/
					Jump_To_Application();                                              //设置PC指针为新程序复位中断函数的地址

				} else {
					BKP_DATA6 = BKP_DATA6 | BKP_BOOT;                                     //文件错误则处于boot,直到升级成功
				}
			} else {
//让系统处于BOOT区域
				//此时如果备份APP有效可以把备份APP数据拷贝到运行APP区域...
				BKP_DATA6 = BKP_DATA6 | BKP_BOOT;
			}
		} else { //等待升级
			printf( "Wait for upgrade\n" );
			//串口升级
			if( Uart_Fram_Record_Struct.InfBit.FramLength1!=0 ) {
				UART_Firmware_Update( Uart_Fram_Record_Struct.Data_uart1_RX_BUF );
				Uart_Fram_Record_Struct.InfBit.FramLength1 = 0;
				timeOutCnt = 0;
			}
			//CAN升级
			if( CanUserDataType.canId != 0x00000000 ) {
				CAN_Firmware_Update( &CanUserDataType ); //CAN数据处理进程
				CanUserDataType.canId = 0x00000000;
				timeOutCnt = 0;
			}
			timeOutCnt++;
			if( timeOutCnt >= 50000 ) { //超时
				timeOutCnt = 0;
				printf( "UpData Time Out" );
				if( BKP_DATA6 & BKP_REAL_APP ) { //APP运行区无效
					
				} else {
					BKP_DATA6 = 0x0000;    //APP运行区无效
				}

			} else {
				delay_1();
			}
		}
	}
}

APP主函数如下:

#include "user_header.h"

TaskHandle_t            Task1_Handler;

void task1(void *pvParameters) {
    while(1) {
        vTaskDelay(200);
        gpio_bit_set(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
        vTaskDelay(200);
        gpio_bit_reset(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    }
}

void GPIO_config() {
    /* enable the LED1 GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    /* configure LED1 GPIO port */ 
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    /* reset LED1 GPIO pin */
    gpio_bit_reset(GPIOA,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
}

void BKP_RtcInit( void )
{
	/* enable PMU clock */
	rcu_periph_clock_enable( RCU_PMU );
	rcu_periph_clock_enable( RCU_RTC );
	/* enable the access of the RTC registers */
	pmu_backup_write_enable();//使能对BKP寄存器的访问
}

int main(void)
{
	//systick_config(); 								    //系统滴答
	nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x4000);	//设置向量表基地址(重映射向量表) :基地址+偏移量
	/*设置中断优先级*/
	nvic_priority_group_set(NVIC_PRIGROUP_PRE3_SUB1);   //3位抢占 1位响应
	GPIO_config();				    					//LED的GPIO初始化
	BKP_RtcInit();										//使能BKP
	USART2_Init(); 					 				    //串口2初始化
#if CAN0_OPEN==1
	can_gpio_config();									//CAN初始化
    can_config();
	/* initialize transmit message */
    can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &g_transmit_message);//结构体初始化
    g_transmit_message.tx_sfid = 0x00;								//标准格式帧标识符
    g_transmit_message.tx_efid = 0x18FEEEBB;						//扩展格式帧标识符
    g_transmit_message.tx_ft = CAN_FT_DATA;							//帧类型:数据帧/远程帧
    g_transmit_message.tx_ff = CAN_FF_EXTENDED;						//帧格式:标准帧/扩展帧
    g_transmit_message.tx_dlen = 8;									//数据长度
    g_transmit_message.fd_flag = 0;									//FD帧标志位 
    g_transmit_message.fd_brs = 1;									//位速率转换开关
    g_transmit_message.fd_esi = 0;									//错误状态指示
    /* initialize receive message */
    can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &g_receive_message);//接收结构体初始
#endif
    taskENTER_CRITICAL();     /* 进入临界区 */			
		 xTaskCreate((TaskFunction_t)task1, 
                                (const char*   )"task1",
                                50,
                                NULL,
                                5, 
                                (TaskHandle_t*  )&Task1_Handler);											
	taskEXIT_CRITICAL();            /* 退出临界区 */
    vTaskStartScheduler();
    while(1) {}
}

经过反复排查,FreeRTOSConfig.h文件中设定的任务优先级后,

#define configMAX_PRIORITIES			( 5 )  //任务优先级

APP创建任务优先级给得过高,任务创建优先级调整后,RTOS运行依旧不正常。

       taskENTER_CRITICAL();     /* 进入临界区 */			
		 xTaskCreate((TaskFunction_t)task1, 
                                (const char*   )"task1",
                                50,
                                NULL,
                                3, 
                                (TaskHandle_t*  )&Task1_Handler);											
		taskEXIT_CRITICAL();            /* 退出临界区 */
        vTaskStartScheduler();

经过仔细排查,发现FreeRTOS可以干预的最高优先级,文件默认给的5(单片机数字越低,优先级越高),优先级很低。

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5

重新调整FreeRTOS可以干预的优先级,改为如下

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	1

调整后,程序运行正常,说明就是任务优先级+FreeRTOS系统最高干预优先级引起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值