主要步骤是依据博主 @超级大洋葱806 写的移植过程,写的非常详细。链接为https://blog.youkuaiyun.com/u014779536/article/details/104047851
现将移植过程中遇到的问题记录如下
1、移植完毕后编译报错
是因为这几个函数仅仅被声明了,但是没有定义;
于是在报错的文件中添加函数定义
其实这四个函数是有其他作用的,可能是需要用户自己编辑,目前先这样简单处理,等后期用到再仔细研究。
修改完这几个问题之后再次编译就没有报错了-------2020.3.2
编译没有报错之后,就开始了创建任务,创建了一个开始任务start_task,并且在开始任务中创建了一个通信任务,烧写程序并开始测试。自己添加的程序,一定要在/USER CODE BEGIN/和/USER CODE END/之间,否则再次用stm32cube生成程序的时候,程序会被覆盖。
int main(void)
{
/* USER CODE BEGIN 1 */
OS_ERR err;
CPU_SR_ALLOC(); //ΪCPU_CRITICAL_ENTER()ºÍCPU_CRITICAL_EXIT()ÉêÇëÒ»¸ö±äÁ¿ cpu_sr
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_FSMC_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM5_Init();
MX_TIM8_Init();
MX_UART4_Init();
MX_RTC_Init();
/* Initialize interrupts */
MX_NVIC_Init();
/* USER CODE BEGIN 2 */
OSInit(&err); //UCOSIII
OS_CRITICAL_ENTER(); //
OSTaskCreate((OS_TCB* )&StartTaskTCB,
(CPU_CHAR* )"start task",
(OS_TASK_PTR )start_task,
(void* )0,
(OS_PRIO )START_TASK_PRIO,
(CPU_STK* )&START_TASK_STK[0],
(CPU_STK_SIZE )START_STK_SIZE/10,
(CPU_STK_SIZE )START_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void* )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR* )&err);
OS_CRITICAL_EXIT();
OSStart(&err);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
// while (1)
// {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// }
/* USER CODE END 3 */
}
void start_task(void *p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();//ΪCPU_CRITICAL_ENTER()ºÍCPU_CRITICAL_EXIT()ÉêÇëÒ»¸ö±äÁ¿ cpu_sr
p_arg = p_arg;
CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageInit(&err);
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_IntDisMeasMaxCurReset();
#endif
#if OS_CFG_SCHED_ROUND_ROBIN_EN
OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);
#endif
OS_CRITICAL_ENTER();
OSTaskCreate((OS_TCB* )&UartTaskTCB,
(CPU_CHAR* )"uart task",
(OS_TASK_PTR )uart_task,
(void* )0,
(OS_PRIO )UART_TASK_PRIO,
(CPU_STK* )&UART_TASK_STK[0],
(CPU_STK_SIZE )UART_STK_SIZE/10,
(CPU_STK_SIZE )UART_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void* )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR* )&err);
OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err);
OS_CRITICAL_EXIT();
}
结果发现连开始任务start_task都没有创建成功,每次都是在OSStart()函数里面的OSStartHighRdy()就不往下执行了,但是程序并没有死,而OSStartHighRdy函数中都是汇编,看不懂,并且也都可以正常执行,在网上没有找到解决办法。想到移植的时候没有按照上面的教程修改:启动文件中的PendSV_Handler和SysTick_Handler 修改为OS_CPU_PendSVHandler和OS_CPU_SysTickHandler,因为我并没有遇到相应的报错,就按照教程修改了启动文件。
修改完后,可以进入start_task开始任务了。但是到CPU_Init()函数,又不往下执行了。
我看好多例程里面并没有下面这一段语句,就都去掉了,去掉后可以正常往下执行了
CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageInit(&err);
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_IntDisMeasMaxCurReset();
#endif
#if OS_CFG_SCHED_ROUND_ROBIN_EN
OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);
#endif
这些函数应该是有特殊作用的,但是目前还用不到,就先删除了,先完成串口通信再说------2020.3.3
串口通信一直没有成功,不知道怎么查找问题,就先在里面写了一个LED点亮的任务,先把LED点亮证明UCOS移植是否 成功。
可是烧进程序后只进了一次LED任务,就不进了,最后发现根本没有开启系统时钟的中断,在主函数中调用BSP_Tick_Init();函数,开启中断,LED终于正常了!
LED正常之后,换回串口任务,目前串口正常了,电脑可以正常接收串口数据了!
接下来是串口接收数据,首先要使能接收中断 ------2020.3.5
HAL_UART_Receive_IT(&huart4,(uint8_t*)aRxBuffer,RXBUFFERSIZE);
然后编写串口回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==UART4)
{
if((USART_RX_STA&0x8000)==0)
{
if(USART_RX_STA&0x4000)
{
if(aRxBuffer[0] != 0x0a)
{
USART_RX_STA = 0;
}
else
{
USART_RX_STA |= 0x8000;
}
}
else
{
if(aRxBuffer[0] == 0x0d)
{
USART_RX_STA |= 0x4000;
}
else
{
USART_RX_BUF[USART_RX_STA&0x3fff] = aRxBuffer[0];
USART_RX_STA++;
if(USART_RX_STA >(USART_REC_LEN-1))
{
USART_RX_STA = 0;
}
}
}
}
}
}
还要在串口中断服务函数中增加两个语句,否则进一次中断就不进入了
void UART4_IRQHandler(void)
{
/* USER CODE BEGIN UART4_IRQn 0 */
/* USER CODE END UART4_IRQn 0 */
HAL_UART_IRQHandler(&huart4);
/* USER CODE BEGIN UART4_IRQn 1 */
while(HAL_UART_GetState(&huart4)!=HAL_UART_STATE_READY); //判断串口是否就绪,如果没有就等待就绪
while(HAL_UART_Receive_IT(&huart4,(uint8_t*)aRxBuffer,RXBUFFERSIZE)!=HAL_OK); //开启新的接收中断
/* USER CODE END UART4_IRQn 1 */
}