目录
前言
在完成基于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才能生效。如下图所示:
总结
一开始走了不少弯路并且刚毕业懂的不多不深,导致很久没出结果,不过多坚持一下,多想一些思路,还是很简单的。
标签:__,set,freertos,代码,boot,uint32,iap,移植 From: https://blog.csdn.net/qq_33983114/article/details/140990832