将iap的接收升级数据部分移植到freertos系统中


前言

        在完成基于TCP服务器的iap裸机程序后得到一个新的任务,该任务让我把iap中通过TCP接收数据的代码移植到一个带有freertos系统的项目中,因为暂时完成故而有了本篇对移植过程的记录文章。


一、移植思路

        对于移植设想了下面三个思路来进行。

        1.在freertos系统中开启一个新的任务用以处理数据接收。在使用这个方法尝试了一段时间后得知,本项目的栈空间已被项目原来的两个任务占满,无法开启新的任务而放弃。

        2.在系统初始化之前添加lwip初始化以及接收数据相关的TCP代码。这个方法同样失败了,在使用了freertos系统后,Systick无法作为主函数的时基需要用外部定时器TIMX,而Systick则是要用作freertos系统的时基。在代码执行后,如果freertos系统没有初始化完成则无法完成定时器的初始化,意味着在freertos系统初始化之前无法使用定时器,因为需要有等待连接的时间,故而放弃该方法。

        3.将这部分代码添加到本身存在的任务中,具体添加到那个任务看项目的需求。

二、移植过程

1.在任务中添加代码

    tcp_echoserver_init();

    int t = 0;//时间计数
    
    while(1)
    {
        t++;
        HAL_Delay(1000);
        if(1 == link_tcps_ok && 0XA5A5E5E5 == Read_Start_Mode())
        {
            My_tcp_echoserver_connection_close();
            __set_FAULTMASK(1);
            NVIC_SystemReset();
        }
        else if(t > 4 && 0 == link_tcps_ok )
        {
            My_tcp_echoserver_connection_close();
            break;
        }
    }

        变量link_tcps_ok是一个连接标志位,只有通过accept建立了连接这个变量的值才会被增加。0XA5A5E5E5 == Read_Start_Mode()读取flash固定内存的值,用来判断数据写入是否完成。

        这段代码如果在5s的时间内有客户端连接上则不会退出循环,一直等待数据写入完成后,将连接相关的资源清除并且进行软复位对设备进行重启。如果在5s内没有连接则退出循环去执行任务原本的代码。

        flash代码只要将之前中boot代码中用不上的部分删除就可以了,TCP代码只要在accept函数中添加link_tcps_ok标志位即可。
        之前的代码。


三、遇到的问题

1.boot跳转卡死在TIM6的中断使能

        boot跳转后进入app程序,在HAL_Init中卡死,通过debug找到问题在TIM6的中断使能处。该问题的原因是在boot函数中使能了全局中断,将下面这段代码注释掉即可解决问题。

附上修改后的boot跳转函数:

typedef void (*pFunction)(void);
void IAP_ExecuteApp (uint32_t App_Addr)
{
	pFunction JumpToApp;
	if ( ( ( * ( __IO uint32_t * ) App_Addr ) & 0x2F000000 ) == 0x20000000 )	//检查栈顶
	{ 
		//__set_FAULTMASK(1);				
		__set_PRIMASK(1); //关闭全局中断
                 
        /* 设置所有时钟到默认状态 */
        // 如果是HAL_RCC_DeInit会导致SysTick重新初始化,所以放在SysTick失能的前面。
        HAL_RCC_DeInit();
        
        /* 关闭滴答定时器,复位到默认值 */
        SysTick->CTRL = 0;
        SysTick->LOAD = 0;
        SysTick->VAL = 0;
        HAL_SuspendTick();        // 挂起滴答定时器
        /* 关闭所有中断,清除所有中断挂起标志 */  
        for (int i = 0; i < 8; i++)
        {
            NVIC->ICER[i]=0xFFFFFFFF;
            NVIC->ICPR[i]=0xFFFFFFFF;
        }
        
        /* 使能全局中断 */ 
        //__set_PRIMASK(0);
        
        /* 这个设置在 RTOS 应用程序中比较重要,因为基于 Cortex-M 内核的 RTOS 任务堆栈基本都是使用线程堆栈指针 PSP。但系统 bootLoader 使用的是主堆栈指针 MSP,所以务必要设置下,同时让 M 内核工作于特权级。此寄存器的作用 */
        __set_CONTROL(0);
                        
		JumpToApp = (pFunction) * ( __IO uint32_t *)(App_Addr + 4);				//第二个字开始	
		//MSP( * ( __IO uint32_t * ) App_Addr );								//初始化堆栈
		__set_PSP(*(__IO uint32_t *)App_Addr); 
		__set_MSP(*(__IO uint32_t*) App_Addr);
		JumpToApp();
		while(1);
	}
	
}

2.代码进入app后却卡死在boot的.s文件的B.处

         代码进入app后运行到freertos的任务创建处,之后就卡死。本问题的原因是代码的中断向量表没有偏移过来。检查代码后发现在system_stm32f7xx.c中只修改VECT_TAB_OFFSET的值并不能成功偏移还需要添加一句#define USER_VECT_TAB_ADDRESS才能生效。如下图所示:


总结

        一开始走了不少弯路并且刚毕业懂的不多不深,导致很久没出结果,不过多坚持一下,多想一些思路,还是很简单的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值