[N32G45x] 基于RT-Thread内核的AUTOSAR在n32g上的实现

[复制链接]
 楼主| 安小芯 发表于 2022-5-19 16:31 | 显示全部楼层 |阅读模式
本帖最后由 安小芯 于 2022-5-19 16:34 编辑

基于RT-Thread内核的AUTOSAR在n32g上的实现

作品来源:RT-Thread

作者:happycode999


一、项目介绍
  随着小米宣布造车,当下“软件定义汽车”的趋势如火如荼,autosar的全称Automotive Open System Architecture,即汽车开放软件架构,这正如TCP/IP对网络进行统一,autosar是对汽车软件技术的统一,TCP/IP制定的初衷是为统一网络标准从而诞生了今天的互联网,而AUTOSAR的制定是为实现汽车电子软件的统一从而实现汽车电子软件的复用。本项目是基于autosar3.1的开源代码arctic core,在此基础上,完成在n32g45x上的mcal驱动,适配RT-Thread内核为autosar的操作系统。
  目前已完成mcal的mcu驱动,autosar的osek操作系统已经能在n32g45x上正常调度,移植rtthread到arctic core,但是在适配OSEK/VDX的接口过程中,发现这个适配工作不是一两个月所能完成,因为osek/vdx的标准非常严格,如果对OSEK/VDX感兴趣的小伙伴可以一起加入rtthread对osek/vdx的适配。
二、简述AUTOSAR及OSEK/VDX2.1 AUTOSAR的分层模型及各层简述

  AUTOSAR从上往下分为应用层、RTE层和基础软件层(BSW)。
  应用层由多个软件组件SWC组成,每个SWC是具有一定功能的模块,如汽车发动机控制逻辑,这些模块可以由matlab的autosar软件包依据模型进行设计;RTE全称Runtime Environment,即运行时环境,它的内部是一条autosar框架定义的虚拟功能总线(VFB),SWC、BSW通过这条虚拟功能总线进行通信。
  BSW从上到下分为服务层、ECU抽象层、MCU抽象层,分层的目的是为了实现各层的复用和对下一层的隔离,这正如RT-Thread的分层思想那样,RT-Thread可以适配不同的MCU就是因为采用了驱动和设备分离的策略,RT-Thread的同一个设备因为注册了不同的驱动就可以驱动不同的MCU。在AUTOSAR中,和MCU有关的一层是MCU抽象层,及MCAL,用RTT的驱动和设备分离的思想来理解autosar的mcal就是同一个ECU抽象层因为注册了不同的MCU驱动就可以驱动不同的MCU。在autosar的成员中就有nxp这样的芯片原厂提供autosar的mcal。
2.2 简述OSEK/VDX接口api
  在autosar的服务层中有一个符合OSEK/VDX标准的操作系统,负责内存管理、对各个功能的调度,api分为任务管理、中断处理、事件机制、资源管理、报警器。
2.2.1 任务管理api
  1. StatusType ActivateTask ( TaskType <TaskID> )
  2. 将任务号为TaskID的任务由挂起态变为就绪态。
  3. StatusType TerminateTask ( void )
  4. 将任务由就绪态转为挂起态。
  5. StatusType ChainTask ( TaskType <TaskID> )
  6. 将当前任务由就绪转为挂起,并将TaskID的任务由挂起转为就绪,相当于TerminateTask和ActivateTask的连用。
  7. StatusType Schedule ( void )
  8. 执行一次调度。

2.2.2 事件api
  1. StatusType SetEvent ( TaskType <TaskID> EventMaskType <Mask> )
  2. 设置一个事件位,当执行SetEvent后等待该事件位的任务可以由等待态变为就绪态。
  3. StatusType ClearEvent ( EventMaskType <Mask> )
  4. 清楚事件位
  5. StatusType GetEvent ( TaskType <TaskID> EventMaskRefType <Event> )
  6. 返回TaskID任务的所有事件位
  7. StatusType WaitEvent ( EventMaskType <Mask> )
  8. 等待事件位,等待事件位的任务由就绪态转为等待态。

2.2.3 报警器(闹钟)api
  1. StatusType GetAlarmBase ( AlarmType , AlarmBaseRefType  )
  2. 获取报警器的时基
  3. StatusType GetAlarm ( AlarmType  TickRefType )
  4. 获取闹钟当前的tick
  5. StatusType SetRelAlarm ( AlarmType , TickType , TickType  )
  6. 设置相对闹钟
  7. StatusType SetAbsAlarm ( AlarmType , TickType ,
  8. TickType <cycle> )
  9. 设置绝对闹钟
  10. StatusType CancelAlarm ( AlarmType  )
  11. 取消闹钟

三、AUTOSAR开源代码arctic core软件框架和分析3.1 相关资源链接3.2 软件框架说明

在arch文件夹中的文件为MCU内核架构相关的文件,如cortex-m3,主要内容为M3的启动文件(见M3编程指南),MCU的固件库。
在boards文件夹中的文件为各个MCU的实现,包括对板子的配置。
system文件夹中包含了一个OSEK/VDX标准的操作系统。
四、在N32G45X上完成AUTOSAR的MCAL
以MCU驱动的时钟设置为例,static void SetClocks(Mcu_ClockSettingConfigType *clockSettingsPtr)是autosar的mcal定义的一个接口,用于设置MCU的时钟,在n32g45x的实现如下:
  1. /**
  2.   * Set bus clocks. SysClk,AHBClk,APB1Clk,APB2Clk
  3.   */
  4. static void SetClocks(Mcu_ClockSettingConfigType *clockSettingsPtr)
  5. {
  6.   volatile uint32 StartUpCounter = 0, HSEStatus = 0;

  7.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
  8.   /* Enable HSE */
  9.   RCC->CTRL |= ((uint32_t)RCC_CTRL_HSEEN);

  10.   /* Wait till HSE is ready and if Time out is reached exit */
  11.   do
  12.   {
  13.     HSEStatus = RCC->CTRL & RCC_CTRL_HSERDF;
  14.     StartUpCounter++;
  15.   } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));

  16.   if ((RCC->CTRL & RCC_CTRL_HSERDF) != RESET)
  17.   {
  18.     HSEStatus = (uint32_t)0x01;
  19.   }
  20.   else
  21.   {
  22.     HSEStatus = (uint32_t)0x00;
  23.   }

  24.   if (HSEStatus == (uint32_t)0x01)
  25.   {
  26.     /* Enable Prefetch Buffer */
  27.     FLASH->AC |= FLASH_AC_PRFTBFEN;

  28.     /* Flash 2 wait state */
  29.     FLASH->AC &= (uint32_t)((uint32_t)~FLASH_AC_LATENCY);
  30.     FLASH->AC |= (uint32_t)FLASH_AC_LATENCY_2;


  31.     /* HCLK = SYSCLK */
  32.     RCC->CFG |= (uint32_t)RCC_CFG_AHBPRES_DIV1;

  33.     /* PCLK2 = HCLK */
  34.     RCC->CFG |= (uint32_t)RCC_CFG_APB2PRES_DIV1;

  35.     /* PCLK1 = HCLK */
  36.     RCC->CFG |= (uint32_t)RCC_CFG_APB1PRES_DIV2;

  37. #ifdef STM32F10X_CL
  38.     /* Configure PLLs ------------------------------------------------------*/
  39.     /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
  40.     /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */

  41.     RCC->CFG2 &= (uint32_t)~(RCC_CFG2_PREDIV2 | RCC_CFG2_PLL2MUL |
  42.                               RCC_CFG2_PREDIV1 | RCC_CFG2_PREDIV1SRC);
  43.     RCC->CFG2 |= (uint32_t)(RCC_CFG2_PREDIV2_DIV5 | GetPll2ValueFromMult(clockSettingsPtr->Pll2) |
  44.                              RCC_CFG2_PREDIV1SRC_PLL2 | RCC_CFG2_PREDIV1_DIV5);

  45.     /* Enable PLL2 */
  46.     RCC->CTRL |= RCC_CR_PLL2ON;
  47.     /* Wait till PLL2 is ready */
  48.     while((RCC->CTRL & RCC_CR_PLL2RDY) == 0)
  49.     {
  50.     }

  51.     /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
  52.     RCC->CFG &= (uint32_t)~(RCC_CFG_PLLXTPRE | RCC_CFG_PLLSRC | RCC_CFG_PLLMULL);
  53.     RCC->CFG |= (uint32_t)(RCC_CFG_PLLXTPRE_PREDIV1 | RCC_CFG_PLLSRC_PREDIV1 |
  54.                             GetPllValueFromMult(clockSettingsPtr->Pll1));
  55. #else
  56.     /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
  57.     RCC->CFG &= (uint32_t)((uint32_t)~(RCC_CFG_PLLSRC | RCC_CFG_PLLHSEPRES |
  58.                                         RCC_CFG_PLLMULFCT));
  59.     RCC->CFG |= (uint32_t)(RCC_CFG_PLLSRC_HSE | GetPllValueFromMult(clockSettingsPtr->Pll1));
  60. #endif /* STM32F10X_CL */

  61.     /* Enable PLL */
  62.     RCC->CTRL |= RCC_CTRL_PLLEN;

  63.     /* Wait till PLL is ready */
  64.     while((RCC->CTRL & RCC_CTRL_PLLRDF) == 0)
  65.     {
  66.     }

  67.     /* Select PLL as system clock source */
  68.     RCC->CFG &= (uint32_t)((uint32_t)~(RCC_CFG_SCLKSW));
  69.     RCC->CFG |= (uint32_t)RCC_CFG_SCLKSW_PLL;

  70.     /* Wait till PLL is used as system clock source */
  71.     while ((RCC->CFG & (uint32_t)RCC_CFG_SCLKSTS) != (uint32_t)0x08)
  72.     {
  73.     }
  74.   }
  75.   else
  76.   { /* HSE fails to start-up, the application will have wrong clock */
  77.       NVIC_SystemReset();
  78.   }
  79. }

  写好mcal的mcu后编译成可执行文件下载到板子上,AUTOSAR能够在n32g45x上正常运行,可以看到三个任务块在调度。下载工具用的是pyocd。

五、RT-THREAD的移植
  由于源码采用的构建工具是makefile,所以需要将rtthread的源码和头文件路径添加到makefile文件。编译下载到板子上可以看到rtthread正常运行。

六、仓库地址
  由于arctic core没有github,不能采用fork的方式协作开发,我的代码上传到gitee提示版权风险无法转为公开的仓库,对源码感兴趣的小伙伴可以在下方留下gitee账号或发邮件给我369247354@qq.com,我拉你到项目组。源码从附件下载:
n32g45x_arctic_core.zip
七、项目视频八、总结和展望
  本次移植过程中,mcal的移植较为轻松,适配n32g45x的寄存器花了不少时间,需要查看n32g45x的参考手册的寄存器定义一个一个的去改。移植rtthread到arctic core的源码比较简单,只是添加rtt的源码到arctic core的makefile。遗憾的是还没完成rtt适配OSEK/VDX的接口,希望对OSEK/VDX感兴趣的小伙伴加入进来,一起完成rtt对OESK/VDX的适配。


james03 发表于 2022-5-20 10:44 | 显示全部楼层
这个不错,一直准备学习autosar,顶起
jtracy3 发表于 2022-5-28 13:30 | 显示全部楼层
AUTOSAR是应用在哪里的  

评论

汽车CAN  发表于 2022-6-25 20:40
timfordlare 发表于 2022-6-20 16:04 | 显示全部楼层
RT-Thread是不是有这个组件?
iyoum 发表于 2022-6-20 16:13 | 显示全部楼层
autosar源码需要工具链吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:国民技术股份有限公司
简介:国民技术股份有限公司(简称:国民技术)2000年源于国家“909”集成电路专项工程成立,2010年创业板上市(股票代码:300077),是通用MCU、安全芯片领先企业和国家高新技术企业。

151

主题

210

帖子

17

粉丝
快速回复 返回顶部 返回列表