本帖最后由 DKENNY 于 2024-8-7 18:29 编辑
#申请原创# @21小跑堂
## 前言 最近在学习操作系统,发现了OSAL这个玩意儿,网上查了一下,OSAL的主要目的是提供一个统一的接口,使得上层应用程序能够独立于底层操作系统的具体实现,从而简化多平台开发的复杂性。目前已经有大佬已经完成了OSAL的移植框架,下面简单讲讲怎么将这个玩意儿移植到APM32F407。
## 什么是OSAL? OSAL 是“操作系统抽象层”(Operating SystemAbstraction Layer)的缩写。简单来说,OSAL 是一种帮助软件开发者与不同操作系统进行交互的工具或接口。它的主要作用是提供一个统一的平台,使得开发者可以在编写代码时不必过多关心具体操作系统的细节,使得软件能够更容易地在不同的操作系统上运行。
## 为什么需要 OSAL? 1. 兼容性:不同的操作系统(如Windows、Linux、MacOS 等)有各自的系统调用和管理方式。OSAL 可以隐藏这些差异,让开发者只需要使用统一的接口就能达到相同的效果。 2. 可移植性:使用OSAL 编写的程序更容易在不同的环境中运行。这样,开发者不需要为每个操作系统单独编写一套代码,只需编写一次,通过OSAL 就可以在多种平台上使用。 3. 简化开发:OSAL提供了一套简化的开发接口,减少了与底层操作系统交互时的复杂性,开发者可以更专注于应用的功能实现,而不是底层细节。
## OSAL 的组成部分 OSAL 通常包括一些基本的组件和功能,例如: - 线程管理:提供创建、销毁和管理线程的功能。 - 时间管理:提供时间延迟、计时器等功能。 - 内存管理:提供动态内存分配和释放的接口。 - 文件系统访问:提供统一的方式来读写文件。
想象一下,你正在开发一个需要访问文件和网络的应用。如果不使用 OSAL,当你想要在 Windows 上和 Linux 上运行此应用时,你可能需要分别处理这两个系统的文件和网络接口,这会让工作变得复杂而繁琐。而如果你使用了 OSAL,你只需调用 OSAL 提供的统一函数,无需关心实际底层的实现。
## 源码 获取地址:https://github.com/mcuwty/osal,其内部代码结构如下。
## 移植 这份代码原来是在linux上编译运行的,我把它移植到了windows的keil编译环境上。可以直接去geehy官网直接下载一个F4的SDK包,使用里面的模板工程进行移植。
1、将osal整个文件夹复制到工程路径下。
2、添加必要的头文件以及源文件 我这里对OSAL源文件做了一个简单的结构优化,不过总体上不影响使用。
3、修改注释掉apm32f4xx_int.h中的Sys_Handler,重新实现timer.c文件。 - /****************************************************************************************
- * 文件名 :timer.c
- * 描述 :硬件定时器配置文件,为osal操作系统提供系统时钟,移植时需要修改的文件
- * 开发平台:
- * 库版本 :
- ***************************************************************************************/
- #include "timer.h"
- #include "osal_timer.h"
- //硬件定时器初始化,设定系统时钟
- void OSAL_TIMER_TICKINIT(void)
- {
- SysTick_Config(SystemCoreClock / 1000);
- }
- //开启硬件定时器
- void OSAL_TIMER_TICKSTART(void )
- {
- }
- //关闭硬件定时器
- void OSAL_TIMER_TICKSTOP(void )
- {
- }
- //此处添加硬件定时器中断溢出函数,并调用系统时钟更新函数osal_update_timers()
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] This function handles SysTick Handler.
- * @param None
- * @retval None
- */
- void SysTick_Handler(void)
- {
- osal_update_timers();
- }
4、编写serial_task.c文件- /****************************************************************************************
- * 文件名 :serial_task.c
- * 描述 :系统串口通信任务
- * 开发平台:
- * 库版本 :
- ***************************************************************************************/
- #include "application.h"
- #include <string.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include "Board.h"
- uint8 Serial_TaskID; //系统串口通信任务ID
- /*********************************************************************
- * LOCAL FUNCTION PROTOTYPES
- */
- /*********************************************************************
- * FUNCTIONS
- *********************************************************************/
- //串口通信任务初始化
- void Serial_Task_Init(uint8 task_id)
- {
- Serial_TaskID = task_id;
- //串口配置初始化
- USART_Config_T usartConfig;
- usartConfig.baudRate = 115200;
- usartConfig.hardwareFlow = USART_HARDWARE_FLOW_NONE;
- usartConfig.mode = USART_MODE_TX_RX;
- usartConfig.parity = USART_PARITY_NONE;
- usartConfig.stopBits = USART_STOP_BIT_1;
- usartConfig.wordLength = USART_WORD_LEN_8B;
- APM_TINY_COMInit(COM1, &usartConfig);
-
- APM_TINY_LEDInit(LED2);
- APM_TINY_LEDInit(LED3);
- }
- //串口通信任务事件处理
- uint16 Serial_Task_EventProcess(uint8 task_id,uint16 task_event)
- {
- if ( task_event & SYS_EVENT_MSG ) //判断系统消息事件
- {
- osal_sys_msg_t *MSGpkt; //定义一个指向接受系统消息结构体的指针
- //从消息队列获取消息
- MSGpkt = (osal_sys_msg_t *)osal_msg_receive( task_id );
-
- while ( MSGpkt )
- {
- switch ( MSGpkt->hdr.event ) //判断消息事件
- {
- case OSAL_PRINTF:
- break;
- default:
- break;
- }
- // Release the memory
- osal_msg_deallocate( (uint8 *)MSGpkt );
- // Next 获取下一个消息
- MSGpkt = (osal_sys_msg_t *)osal_msg_receive( task_id );
- }
- // return unprocessed events
- return (task_event ^ SYS_EVENT_MSG);
- }
-
- if(task_event & PRINTF_STR)
- {
- static int dir = 1;
- if(dir)
- {
- dir = 0;
- APM_TINY_LEDOn(LED2);
- }
- else
- {
- dir = 1;
- APM_TINY_LEDOff(LED2);
- }
-
- printf("APM32F407 printf !\r\n");
-
- return task_event ^ PRINTF_STR;
- }
- return 0;
- }
5、编写main函数。 - /*!
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] Main program body
- *
- * [url=home.php?mod=space&uid=895143]@version[/url] V1.0.3
- *
- * [url=home.php?mod=space&uid=212281]@date[/url] 2023-07-31
- *
- * @attention
- *
- * Copyright (C) 2021-2023 Geehy Semiconductor
- *
- * You may not use this file except in compliance with the
- * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
- *
- * The program is only for reference, which is distributed in the hope
- * that it will be useful and instructional for customers to develop
- * their software. Unless required by applicable law or agreed to in
- * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
- * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
- * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
- * and limitations under the License.
- */
- /* Includes */
- #include "main.h"
- #include "Board.h"
- #include "stdio.h"
- #include "apm32f4xx_gpio.h"
- #include "apm32f4xx_adc.h"
- #include "apm32f4xx_misc.h"
- #include "apm32f4xx_usart.h"
- #include "apm32f4xx_tmr.h"
- /** @addtogroup Examples
- @{
- */
- /** @addtogroup ADC_AnalogWindowWatchdog
- @{
- */
- /** @defgroup ADC_AnalogWindowWatchdog_Macros Macros
- @{
- */
- /* printf using USART1 */
- #define DEBUG_USART USART1
- #define APM_COMInit APM_TINY_COMInit
- /**@} end of group ADC_AnalogWindowWatchdog_Macros*/
- /** @defgroup ADC_AnalogWindowWatchdog_Functions Functions
- @{
- */
- #include "application.h"
- /*!
- * [url=home.php?mod=space&uid=247401]@brief[/url] Main program
- *
- * @param None
- *
- * @retval None
- */
- int main(void)
- {
- //系统硬件、外设等初始化
-
- //禁止中断
- HAL_DISABLE_INTERRUPTS();
- //osal操作系统初始化
- osal_init_system();
- //添加任务
- osal_add_Task(Serial_Task_Init,Serial_Task_EventProcess,1);
- //添加的任务统一进行初始化
- osal_Task_init();
- osal_mem_kick();
- //允许中断
- HAL_ENABLE_INTERRUPTS();
- //设置初始任务事件,上电就需要自动轮询的任务事件可在此添加
- osal_start_reload_timer( Serial_TaskID, PRINTF_STR, 1000);
- //启动osal系统,不会再返回
- osal_start_system();
- }
- #if defined (__CC_ARM) || defined (__ICCARM__) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
- /*!
- * [url=home.php?mod=space&uid=247401]@brief[/url] Redirect C Library function printf to serial port.
- * After Redirection, you can use printf function.
- *
- * @param ch: The characters that need to be send.
- *
- * @param *f: pointer to a FILE that can recording all information
- * needed to control a stream
- *
- * @retval The characters that need to be send.
- *
- * @note
- */
- int fputc(int ch, FILE* f)
- {
- /* send a byte of data to the serial port */
- USART_TxData(DEBUG_USART, (uint8_t)ch);
- /* wait for the data to be send */
- while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
- return (ch);
- }
- #elif defined (__GNUC__)
- /*!
- * [url=home.php?mod=space&uid=247401]@brief[/url] Redirect C Library function printf to serial port.
- * After Redirection, you can use printf function.
- *
- * @param ch: The characters that need to be send.
- *
- * @retval The characters that need to be send.
- *
- * @note
- */
- int __io_putchar(int ch)
- {
- /* send a byte of data to the serial port */
- USART_TxData(DEBUG_USART, ch);
- /* wait for the data to be send */
- while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
- return ch;
- }
- /*!
- * [url=home.php?mod=space&uid=247401]@brief[/url] Redirect C Library function printf to serial port.
- * After Redirection, you can use printf function.
- *
- * @param file: Meaningless in this function.
- *
- * @param *ptr: Buffer pointer for data to be sent.
- *
- * @param len: Length of data to be sent.
- *
- * @retval The characters that need to be send.
- *
- * @note
- */
- int _write(int file, char* ptr, int len)
- {
- int i;
- for (i = 0; i < len; i++)
- {
- __io_putchar(*ptr++);
- }
- return len;
- }
- #else
- #warning Not supported compiler type
- #endif
- /**@} end of group ADC_AnalogWindowWatchdog_Functions */
- /**@} end of group ADC_AnalogWindowWatchdog */
- /**@} end of group Examples */
## 现象
## 总结
OSAL 是一种能够帮助开发者编写更灵活、可移植代码的工具。通过抽象化操作系统的底层细节,OSAL使得在不同环境中开发和运行软件变得更简单。 针对OSAL跟RTOS的区别,我做了一份简单的表格。 特性 | | | | OSAL 是一种软件层,提供对不同操作系统的抽象,以便于在不同平台上进行可移植和可重用的代码开发。 | RTOS 是一种操作系统,设计用于实时应用程序中,确保任务在严格的时间约束内执行。 | | 实现代码的可移植性,简化对不同操作系统的适配过程。 | 提供实时任务调度和响应能力,确保时间敏感的操作具备准确性和可靠性。 | | 被用于需要在多个不同操作系统上运行的应用程序中,例如嵌入式系统。 | 被用于对时间要求严格的应用场景,如飞行控制、医疗设备、工业自动化等。 | | | 涉及底层硬件管理,提供任务调度、中断管理、时间管理等基本功能。 | | | | | | | | | |
如果有条件的话,最好选择使用实时操作系统(RTOS),因为它的功能比较丰富。如果不使用RTOS,操作系统抽象层(OSAL)也是一个不错的选择。不过,使用OSAL之前,最好先对它的源码有一定的了解,这样在遇到问题时才能更有效地解决。
附件:
2.
osal源码.zip
(176.79 KB, 下载次数: 27)
|