liteOS移植到STM32F746ZG(非接管中断)

平台配置:

开发板:NUCLEO-F746ZG,MCU为STM32F746ZG

库版本:最新版的HAL驱动库

操作系统:liteOS 1.0

第一步、创建裸机工程,工程结构如下图所示

工程目录说明:

app:用户创建的文件都可以添加到这里。

bsp:板级支持文件。

cmsis:架构相关文件

config:配置文件都可以添加到这里

hal:官方cube_hal库

linker:链接文件

startup:启动文件

创建完工程后,编译,改错,确保没有编译错误,有开发板的话最好是写个简单的LED程序测试一下,工程是否可以正常工作,避免移植操作系统时不成功,造成调试困难。

第二步、添加【liteos】源文件到工程中

首先,在工程中添加liteos/arch目录,并添加以下文件到工程,如下图

接着,在工程中添加 liteos/kernel目录,并添加以下文件到工程

  • los_init.c
  • base/core 下面全部 .c 文件
  • base/ipc 下面全部 .c 文件
  • base/mem/bestfit_little 下面全部 .c 文件
  • base/mem/common 下面全部 .c 文件
  • base/mem/membox 下面全部 .c 文件
  • base/misc 下面全部 .c 文件
  • base/om 下面全部 .c 文件
  • extended/tickless 下面全部 .c 文件(如果没有使用 tickless,可以不必添加)

接着,在工程添加 liteos/os_config目录,添加以下三个文件方便修改

修改target_config.h

修改成对应MCU系列的头文件

修改为 NO

配置SRAM的起始地址和结束地址

第三步、添加路径,如下图

到这一步,我们可以编译一下试试,发现两个错误,如下图

提示,PendSV_Handler 和 SysTick_Handler重复定义,很简单,注释掉stm32f7xx_it.c中这两个函数,重新编译,没有错误了。

 liteos中的 PendSV_Handler 在 los_dispatch_iar.S 中定义

SysTick_Handler 在 los_hwi.c中定义

void SysTick_Handler(void)
{
    if (g_bSysTickStart)
    {
        osTickHandler();
    }
    else
    {
        g_ullTickCount++;
        //HAL_IncTick();          // 有强迫症的同学可以把这句代码移到这里
    }
}

最后,重写一下 HAL_GetTick()函数,这样可以保证HAL_Delay() 函数可以继续正确使用

/* 重写 HAL_GetTick 函数  */
uint32_t HAL_GetTick(void)
{
    return (uint32_t)LOS_TickCountGet();
}

重新编译,看有没有错误,完美,没有错误。

第四步、测试移植的正确性

首先,不添加任务,跑裸机LED闪烁工程试试,看能否正常工作,这次改用HAL_Delay()延时,顺便验证一下重写后的HAL_GetTick 函数正常不

main.c 源文件

#include "stm32f7xx.h"
#include "stm32f7xx_nucleo_144.h"
#include "sys_init.h"
#include "dwt.h"


__IO FlagStatus SwitchClock = RESET;


/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  HAL_Init();

   
  /* Enable HSI oscillator and configure the PLL to reach the max system frequency (216 MHz)
     when using HSI oscillator as PLL clock source. */
  SystemClock_Config();
  
  dwt_init(SystemCoreClock);
  
  /* Configure LED1 */
  BSP_LED_Init(LED1);

  /* Initialize User push-button, will be used to trigger an interrupt each time it's pressed.*/
  BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);

  /* Toggle some leds in an infinite loop */
  while (1)
  {  
    /* Toggle LED1 */
    BSP_LED_Toggle(LED1);
    HAL_Delay(100);
   // delayms(100);
  }
}

/**
  * @brief  EXTI line detection callbacks.
  * @param  GPIO_Pin: Specifies the pins connected EXTI line
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if (GPIO_Pin == KEY_BUTTON_PIN)
  {
    SwitchClock = SET;
  }
}

重新编译,下载,很好,程序工作正常。

接下来,使用 liteos 创建一个 LED 闪烁程序,来测试 liteos 内核工作是否正常

先新建一个 includes.h 头文件,然后把所有  liteos 的头文件全部 #include “los_*.h” 到这个文件里,方便以后使用

includes.h 头文件

#ifndef INCLUDES_H
#define INCLUDES_H


#include "los_builddef.h"
#include "los_printf.h"
#include "target_config.h"


#include "los_base.h"
#include "los_compiler.h"
#include "los_config.h"
#include "los_err.h"
#include "los_errno.h"

#include "los_event.h"
#include "los_heap.h"
#include "los_list.h"

#include "los_membox.h"
#include "los_memcheck.h"
#include "los_memory.h"

#include "los_mux.h"
#include "los_queue.h"
#include "los_sem.h"
#include "los_slab.h"
#include "los_swtmr.h"
#include "los_sys.h"
#include "los_task.h"
#include "los_tick.h"
#include "los_tickless.h"
#include "los_typedef.h"



#endif

 liteos 内核初始化流程

初始化内核(调用LOS_KernelInit() )---> 创建用户任务 ---> 启动内核(调用 LOS_Start()),简单吧,详细代码如下

liteos初始化过程源代码
  
// 初始化 liteos
  UINT32 uwRet = LOS_OK;
  
  uwRet = LOS_KernelInit();
  if(uwRet != LOS_OK)
      return LOS_NOK;
  
  //创建用户任务
  uwRet = CreatAppTask();
  if(uwRet != LOS_OK)
      return LOS_NOK;
  
  // 启动 liteos 内核
  (void)LOS_Start();

创建 user_task.h 和 user_task.c 文件,源码如下

user_task.h  头文件

#ifndef USER_TASK_H
#define USER_TASK_H


#include "includes.h"


UINT32 CreatAppTask(void);


#endif
user_task.c 源文件


#include "user_task.h"
#include "includes.h"

#include "stm32f7xx_nucleo_144.h"




/*********** task ID ***************************/
UINT32  g_tskLedHandle;
UINT32  g_tskRedHandle;

/*  private fn ********************************/

static void Task_LED(void);
static void Task_Red(void);




UINT32 CreatAppTask(void)
{
    UINT32 uwRet = LOS_OK;
    TSK_INIT_PARAM_S task_init_param;

    
    // 创建第一个任务 Task_LED
    task_init_param.usTaskPrio = 2;
    task_init_param.pcName = "Task Led";
    task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)Task_LED;
    task_init_param.uwStackSize = 0x400;
    uwRet = LOS_TaskCreate(&g_tskLedHandle,&task_init_param);
    if(LOS_OK != uwRet)
        return uwRet;
    
    // 创建第二个任务 Task_Red
    task_init_param.usTaskPrio = 3;
    task_init_param.pcName = "Task Red";
    task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)Task_Red;
    task_init_param.uwStackSize = 0x400;
    uwRet = LOS_TaskCreate(&g_tskRedHandle,&task_init_param);
    if(LOS_OK != uwRet)
        return uwRet;
    
    return uwRet;
}

// 第一个任务,绿灯闪烁任务
static void Task_LED(void)
{
    while(1)
    {
        BSP_LED_Toggle(LED1);
        LOS_TaskDelay(500);
    }
}

// 第二个任务,红灯闪烁任务
static void Task_Red(void)
{
    while(1)
    {
        BSP_LED_Toggle(LED3);
        LOS_TaskDelay(200);
    }
}

编译,下载,go,绿灯和红灯都按照延时要求正确闪烁,说明移植成功了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值