广州旅游团购网站建设,北京工程工程建设交易信息网站,网站制作 成都,泰安房产网签数据前言
在学习一款MCU之前#xff0c;一般我的习惯是先下载官方提供的SDK包进行学习。然后学习了解SDK提供的资源、框架、以及各目录结构文件作用等#xff0c;下面边学边做笔记记录。
S32K1系列SDK我们可以到下面的NXP官网去获取#xff1a; https://www.nxp.com.cn/design…前言
在学习一款MCU之前一般我的习惯是先下载官方提供的SDK包进行学习。然后学习了解SDK提供的资源、框架、以及各目录结构文件作用等下面边学边做笔记记录。
S32K1系列SDK我们可以到下面的NXP官网去获取 https://www.nxp.com.cn/design/software/development-software/s32-sdk/s32-software-development-kit-for-s32k1:S32SDK-ARMK1 1. S32K1系列SDK概述
下面是引用自NXP官网对S32K1xx SDK的介绍 S32K1的S32软件开发工具包(SDK)提供了性价比高且使用便捷的完整解决方案可与S32K1整个系列微控制器的连接、电机控制和安全库堆栈相匹配。S32K1系列的S32SDK非常适合汽车领域的所有应用。 特征
包含在S32 Design Studio中Processor Expert图形配置集成的恩智浦软件电机控制库(AMMCLib)、结构核心自检(sCST)、SBC中间件支持5类编译器GCC、GreenHills、Arm编译器、IAR和WindRiver DIAB带有操作系统接口层的FreeRTOS或裸机符合MISRA C 2012的量产级驱动程序以太网(TCP/IPLWIPWOLFSSL)LIN堆栈
2. S32K1xx SDK软件架构
下图是 S32K1xx SDK 的软件架构 从这幅图片我们可以了解到S32K1xx SDK编程有分层的思想包含有
底层
各系列MCU芯片支持Low-level Drivers底层驱动程序。包括PDPeripheral Driver外设驱动层驱动和PALPeripheral Abstract Layer外设抽象层驱动各个编译器平台的Start-up启动文件、Linker files 支持
实时操作系统层
SDK提供移植好的 FreeRTOS还有OSIF操作系统接口层OSIF层提供了统一的操作系统API接口是基于 FreeRTOS 或者裸机代码封装而来如果不使用FreeRTOS那么OSIF层就是裸机接口实现的。
中间件Middleware
在 Low-level Drivers 上面就是中间件层。主要包含有一些静态库。如AMMCLib电机驱动库、Touch sensing触摸感应库、安全相关的库SCST、SPTLib这类库是不开源的只提供编译好的 .a 文件。移植好的通信协议栈。如 TCP/IP、LIN、USB和文件系统等。SCBSystem Basis Chip驱动程序。这部分就是NXP移植好了的一些外围芯片的驱动程序。
应用层
一些demo应用程序驱动程序的示例程序包括PD和PAL驱动辅助工具。如Processor Expert UI config file处理器专家配置文件根据图形化配置界面生成初始化代码。
3. S32K1xx SDK各目录结构
从官网下载了 S32K1xx SDK 后安装到本地目录SDK的根目录包含的内容如下 下面对各个子目录结构简单介绍。
3.1 doc
该目录存放的就算各系列芯片SDK的帮助文档如快速入门指南、各系列芯片的html格式的帮助文档等等。比如打开S32K144的html帮助文档如下 可以看到对SDK的各个组件还要Example还有代码的变量、结构体定义都有介绍。
我们对SDK哪部分内容不了解首先可以在这里找找有没有对应的介绍。
3.2 examples
该目录存放的是各系列芯片的示例程序包括demo应用的综合示例程序以及外设驱动代码的使用示例程序。以 S32K144 为例 3.3 lib
该目录存放的是前面介绍的编译好的中间件文件。比如电机驱动库、SCST安全库。还有触摸驱动库、NFC等这些 lib 也是不开源的而且在这个目录还找不到看网上的介绍说是需要找 NXP 的 FAE 才能拿到。 3.4 middleware
该目录存放的就是中间件的一些代码。比如lin总线协议栈、tcp/ip协议栈、sbc驱动代码。 3.5 platform
该目录是最重要的一个目录是存放平台相关代码的目录。其中包含有devices、drivers、pal三个子目录。如下 这个目录非常重要下面对各子目录详细介绍。
3.5.1 platform/devices目录
devices目录包含各个MCU系列的设备头文件如S32K144.h、链接文件、启动文件、内核文件、还要一些公共的类型声明、断言的定义等等。
下面是该目录的截图 下面对该目录的部分文件介绍
1common子目录
该目录 s32_core_cm4.h/s32_core_cm0.h 主要是 cm0/4 内核定义相关的操作。比如全局中断的开启和关闭、进入低功耗、获取内核ID等相关的宏定义这些定义都是使用汇编指令操作的。
2S32K1xx 各系列型号的子目录
这些目录主要是各系列的 S32K1xx.h 属性头文件、各个编译器平台的启动文件和链接文件、xxx.svd 仿真文件等等。
比如以 S32K144 子目录为例 S32K144.h 这个文件是对应芯片型号的寄存器结构体定义、寄存器位域的宏定义、各个外设中断号的定义、一些公共操作的宏定义等等。 S32K144_features.h 这个文件定义的是对应芯片型号外设的属性特点全是 FEATURE_xxxxxx 这样的宏定义。另外还定义了芯片勘误表的信息以 ERRATA 开头。部分勘误表的宏定义如下 /* brief ARM Errata 838869: Store immediate overlapping exception return operation might vector to* incorrect interrupt. */
#define ERRATA_E9005/* brief ARM Errata 709718: VDIV or VSQRT instructions might not complete correctly when very* short ISRs are used. */
#define ERRATA_E6940/* brief E10655: When using LPSPI in master mode and the SR[MBF] bit is read as a one, then, the* flag is set. If it is read as a zero, it must be read second time and this second read will be* the correct state of the bit. */
#define ERRATA_E10655ERRATA_E9005 这个E9005就是勘误表的编号上面有注释说明该勘误编号修正了什么内容。如果在这个头文件定义了这个勘误码那么会使能对应勘误码的错误修正代码。
3startup子目录
很明显就是包含各个编译器平台的汇编启动文件还有一个system_S32K144.c/h文件下面主要介绍下 system 文件汇编的启动文件到时研究启动过程时再学习记录。
system_S32K144.c 文件是ARM公司规定的 Cortex M 系列MCU的软件接口标准(CMSIS)规定的系统和时钟初始化API函数。主要有3个函数
SystemInit 系统的初始化函数。该函数主要作用是使能 FPU、关闭 WatchDog、使能 I-Cache CPU内部指令高速缓存。SystemCoreClockUpdate 系统内核时钟更新函数不过在 SDK 中并没有调用这个函数。但是用户可以调用这个函数对MCU时钟进行初始化当然 PD 层外设驱动代码也有系统时钟的初始化函数。SystemSoftwareReset MCU的软件复位函数操作的是内核 SCB 寄存器实现的MCU软件复位。
4devices子目录的其他文件 startup.c/h 里面实现了一个 init_data_bss() 函数下面列出 __ARM_CC 编译器的部分代码 /* Copy initialized data from ROM to RAM */
while (data_rom_end ! data_rom)
{*data_ram *data_rom;data_ram;data_rom;
}/* Copy functions from ROM to RAM */
while (code_rom_end ! code_rom)
{*code_ram *code_rom;code_ram;code_rom;
}/* Clear the zero-initialized data section */
while(bss_end ! bss_start)
{*bss_start 0;bss_start;
}/* Copy customsection rom to ram */
while(custom_rom_end ! custom_rom)
{*custom_ram *custom_rom;custom_rom;custom_ram;
}/* Copy the vector table from ROM to RAM */
/* Workaround */
for (n 0; n (((uint32_t)(vector_table_size))/sizeof(uint32_t)); n)
{vector_ram[n] vector_rom[n];
}
/* Point the VTOR to the position of vector table */
*s_vectors[coreId] (uint32_t) __VECTOR_RAM;从这个代码内容可以看出主要完成的工作是 初始化 .data 段。其实就是把已经初始化的全局变量或者静态局部变量从 Flash 复制到 RAM 中初始化 .code_ram 段。就是用户写的代码声明需要在RAM中运行的代码那么就把那部分代码从 FLASH 复制到 RAM 中。清除 .bss 段。目的就是把初值为0的全局变量或者静态局部变量所占用的那一段RAM空间清0.初始化 .custom_ram 。就是用户自定义的数据段然后这些数据是有初始值的初值不是0然后把这段数据从Flash复制到RAM中。把外设的中断向量表从Flash复制到RAM中并且把新的中断向量表地址赋值给CPU内部的中断向量基地址寄存器。
上面复制数据的过程中都需要知道从哪里复制、复制到哪里去、复制的长度这3条信息。这些其实都可以通过链接文件获取到。
疑问这里有点点疑问为什么要把中断向量表复制到RAM程序又没有在RAM中运行除非程序被搬运到了RAM运行才需要重定向中断向量表吧后面估计需要研究下启动过程才能了解清楚。 callbacks.h 定义了全局的中断事件类型、中断回调函数类型。 /* UART 外设的事件类型定义 */
/*!* brief Define the enum of the events which can trigger UART callback** This enum should include the events for all platforms** Implements : uart_event_t_Class*/
typedef enum
{UART_EVENT_RX_FULL 0x00U, /*! Rx buffer is full */UART_EVENT_TX_EMPTY 0x01U, /*! Tx buffer is empty */UART_EVENT_END_TRANSFER 0x02U, /*! The current transfer is ending */UART_EVENT_ERROR 0x03U, /*! An error occured during transfer */
} uart_event_t;/* UART 外设的回调函数类型定义 */
/*!* brief Callback for all peripherals which support UART features** Implements : uart_callback_t_Class*/
typedef void (*uart_callback_t)(void *driverState, uart_event_t event, void *userData);可以看出每个外设的类型定义 xxx_event_t 然后回调函数类型是 xxx_callback_t 其中 xxx 就是外设的名称。 devassert.h S32 SDK 内部所有函数都使用了断言的机制用于检查用户输入的参数是否合法。这个文件就是断言宏的定义用户可以定义自己的断言函数又或者使用SDK定义的默认的断言函数。 device_registers.h 该文件包含所有系列MCU的外设头文件然后通过定义某个芯片的宏定义具体包含哪个芯片的头文件。 status.h 该文件定义了全局的状态码主要是指示外设驱动代码的API函数操作成功还是其他什么错误状态。
3.5.2 platform/drivers目录
该目录存放的就算 PD 外设驱动层的驱动代码包含了所有MCU外设的驱动。每个外设就是一个子文件夹。下面以edma外设为例介绍下文件的作用。
1、edma 外设的源文件目录 edma_driver.c 就是对用户开放的外设驱动层 API 函数的定义和实现用户可以调用这些函数编写应用程序。edma_hw_access.c/.h 文件外设寄存器访问函数的实现。这些函数大部分都是 inline 内联函数会被 edma_driver.c 文件实现的驱动封装函数所调用。这些函数是不对用户开放的函数。edma_irq.c/.h 文件这些函数都是 .s 启动文件中断向量表定义的函数然后在这些文件实现了。这些函数的函数名一定是要和中断向量表的函数名一致的不然发生了中断就找不到中断的入口了。函数内部调用的是 driver 层实现的中断处理函数比如 EDMA_DRV_IRQHandler() 函数。
2、drivers/inc目录 就是对用户开放的函数声明以及结构体、宏定义、枚举等数据类型的声明和定义。每一个外设都有一个 xxx_driver.h 的头文件。
3.5.3 platform/pal目录
这个目录放的就是 PAL外设抽象层驱动代码了。外设抽象层其实就是外设驱动层代码的进一步封装PAL的函数实现是调用了PD层的函数的。
下面是PAL层的软件架构 PAL层的主要特性有
一系列外设的接口抽象例如 LPUART LINFlexD_UART eSCI FlexIO_UART 等每个 SDK 单层多个平台上的相同通用 API可以具有跨平台的特性。
PAL层代码开发适用的场景
每当应用程序需要一个简化的通用接口来尽可能多地抽象底层芯片功能时。每当开发可移植的更高级别通用代码时这些代码都旨在在不同的 NXP 平台上运行。这可能包括从低级控制台实用程序库到 TCP/IP 等通信堆栈的任何内容。
3.6 rtos
该目录存放的是已经适配了 S32K1xx 系列芯片的 FreeRTOS 源码FreeRTOS_S32K子目录以及 rtos 接口层代码的实现osif子目录。下面介绍下 osif 子目录。 osif_freertos.c 基于 FreeRTOS 实现的 os 接口层API函数比如信号量、互斥量、任务创建等等和RTOS有关的接口。osif_baremetal.c 基于裸机实现的操作系统接口层。没有任务相关的接口函数但是有互斥量、信号量、嘀嗒心跳等一些API接口。
3.7 tools
这个目录存放的应该是一些工具文件但是我还不了解文件怎么使用。后面再探索。
4. 总结
到这里就对 S32K1xx SDK 做了基本的介绍可以说是大致了解了这个SDK了。但是怎么去使用这个SDK它的各个外设编程思路又是怎么样的各个外设又有哪些数据结构SDK的中断的处理机制是怎么样的…等等。这些都是我到目前为止的一些疑问后面的学习中慢慢了解这些内容吧。