举例说明嵌入式框架该如何分层


素材来源:https://www.php.cn/link/4ac4cbd6ebfd454fd1d1c310cad3c644

整理:技术让梦想更伟大 | 李肖遥

前言为了提升产品开发速度和未来迭代及移植的便利性,框架分层设计是必不可少的。然而,对于中小型项目严格遵循这些原则,可能会耗费过多精力在系统设计上,这是一个需要权衡的过程。

一、框架分层是什么?在嵌入式架构中,通常分为硬件架构与软件架构。这里主要讨论的是嵌入式软件设计,这是大多数人接触的设计。

所谓的分层,也可以理解为模块化的设计,但框架分层的设计通常遵循以下原则:

每个模块提供的接口必须统一,只能增加,不能修改。设计时需考虑兼容性和使用便利性。同级模块之间应相互独立,不能相互调用,只能调用下一层的接口。不同模块构成不同的层,层与层之间不能跨级调用。模块内部可以继续分层,根据项目需求增减分层。一般可以分为:硬件驱动层->功能模块层->应用接口层->业务逻辑层->应用层

让我们通过一个经典的图示,简单了解一下框架分层的结构。

举例说明嵌入式框架该如何分层从图中可以看出,设计是遵循设计原则的,层与层之间不能相互调用。

二、框架分层的优劣势1.优势单一职责:每一层只负责一个职责,职责边界清晰,不会造成跨级调用。在大型项目中,每个人负责的部分不同,加快整个项目的开发进度。高内聚:分层将相同职责放在同一层中,所有业务逻辑内聚在领域层。测试时,只需测试该领域的层,通常不需要考虑其他层的问题。低耦合:依赖关系简单,上层只能依赖下层,没有循环依赖。易维护:面对变更容易修改。在平台更改后,如果仅改了驱动,其他层无需修改,只需更改驱动层即可。易复用:如果功能模块变动,只需升级相应的功能模块,其他模块不受影响,应用层也不受影响。要充分利用这些优势,必须严格遵循设计原则。

2.劣势开发成本高:因为多层分别承担各自的职责,增加功能需要在多个层增加代码,这难免会增加开发成本。但合理的抽象和根据项目设置合理的层级可以降低开发成本。性能略低:业务流需要经过多层代码处理,性能会有所消耗。可扩展性低:因为上下层之间存在耦合度,有些功能变化可能涉及多层的修改。有优势也有劣势,需根据项目需求进行取舍。对于中小型项目,如果不考虑未来迭代,可以不分层或部分分层,既能利用框架分层的部分优势,又能降低开发成本。

三、一个简单的例子主要讨论的是软件框架的分层设计,这里使用STM32cubemx进行硬件初始化,尽可能少考虑硬件驱动部分。

以一个智能小灯为例:

功能

通过按键控制小灯的亮度,等级为:0,1,2,3通过串口观察当前小灯亮度等级通过OLED观察当前小灯亮度等级下面是这个例子的一个简单图示。

这个例子较为简单,业务逻辑层可以省略,直接从应用层调用功能模块层,加快开发进度。

举例说明嵌入式框架该如何分层最后附上一点关于LED如何在不同层进行封装的代码。

VALL-E VALL-E

VALL-E是一种用于文本到语音生成 (TTS) 的语言建模方法

VALL-E 134 查看详情 VALL-E

硬件层

首先查看HAL库生成的代码,这是LED硬件层,即GPIO层,cubemx已经生成,在stm32f4xx_hal_gpio.c(我使用的是F4)中,已有相应的GPIO驱动,这里不需要我们处理。

举例说明嵌入式框架该如何分层硬件层驱动层

查看LED部分的驱动,即下面的两个函数:

void MX_TIM1_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle);
/* TIM1 init function */
void MX_TIM1_Init(void)
{
  /* USER CODE BEGIN TIM1_Init 0 */
  /* USER CODE END TIM1_Init 0 */
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
  /* USER CODE BEGIN TIM1_Init 1 */
  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 168-1;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 10000;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSl*eMode = TIM_MASTERSL*EMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */
  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(timHandle->Instance==TIM1)
  {
  /* USER CODE BEGIN TIM1_MspPostInit 0 */
  /* USER CODE END TIM1_MspPostInit 0 */
    __HAL_RCC_GPIOE_CLK_ENABLE();
    /**TIM1 GPIO Configuration
    PE11     ------> TIM1_CH2
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  /* USER CODE BEGIN TIM1_MspPostInit 1 */
  /* USER CODE END TIM1_MspPostInit 1 */
  }
}

对其进行封装,就是我们想要的LED小灯驱动,未来如果需要修改驱动,直接修改底层即可。

void Led_init(){
  MX_TIM1_Init();
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);//启动PWM
}

功能模块层

根据上面的需求要求,划分为四个不同等级,同时需要对LED驱动进行进一步封装,以满足层与层之间不能跨级调用的原则(到这里是不是发现很麻烦!小项目就不要用啦!)

//ARR计数器设置值为0~10000
#define LED_GRADE_0  0
#define LED_GRADE_1  3000
#define LED_GRADE_2  6000
#define LED_GRADE_3  10000
//设置LED亮度功能
void Led_Set_brightness(int Grade){
  if(Grade==LED_GRADE_0)
  {
      __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, Grade);
      HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_2);//关闭PWM输出
  }
  else
  {
      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2, Grade);
      __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, Grade);
  }
}
//启动LED功能
void Led_Start(){
  Led_init();
}

业务逻辑层

这里仅以启动层为例:

void Start_app(){
  Led_Start();
}

应用层

基本流程是:启动业务逻辑->读取业务逻辑->处理业务逻辑->显示业务逻辑。

四、总结到这里,一个简单的例子也解释完毕了,通过LED这个简单的例子,已经大概了解到这个设计的复杂性。如果是大型项目,运用起来会很爽,但小型项目完全没必要这样分层,太麻烦了,严重减慢开发效率,时间都用在思考如何进行分层才能符合框架分层的原则。下一篇文章将会结合框架分层与MVC进行一个小综合。

版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

以上就是举例说明嵌入式框架该如何分层的详细内容,更多请关注其它相关文章!


# ai  # gpio  # 这是  # 只需  # 小灯  # 举例说明  # 的是  # 未来  # 该如何  # igs  # typedef  # 网站软文推广文章怎么写  # 方山附近哪里有网站推广  # 采购论文网站怎么做推广  # 天津平原网站建设  # 杭州关键词排名七天上线  # 电商网站建设功能需求  # 老社区如何推广营销  # 双十一营销推广视频  # 行唐品牌网站推广  # seo头条百科  # 不受  # 不需要  # 应用层 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: 亚太地区 70% 的企业高管正探索生成式 AI 应用或已经进行投资  掌阅科技对话式AI应用“阅爱聊”开启内测  美图公司吴欣鸿:AI技术重构影像产业  阿里达摩院向公众免费开放100项AI专利许可  贫穷让我预训练  配 3D 机器人头像,谷歌展示全新安卓 LOGO  微软在 Bing 和 Edge 浏览器中拓展网购服务,帮用户选购心仪产品  Vision Pro头显重磅发布;苹果收购AR厂商Mira  清华朱军团队新作:使用4位整数训练Transformer,比FP16快2.2倍,提速35.1%,加速AGI到来!  科学家称,面对人工智能,人类未来或只有灭亡与虚拟永生两个选择  科技数码圈的新物种 乐天派桌面机器人 AI +安卓+机器人 首发价1799元  “具身智能”引爆机器人产业,看绝影Lite3/X20四足机器人有何特别之处?  解决导航“最后50米”难题 高德地图升级AR步行导航找终点功能  一次购买全年省心,入手科沃斯这几台机器人,省下时间就是金钱  DreamAvatar数字人使用教程  北京公司实施AI技术,推行4.5天工作制,抵制996文化,提升员工工作幸福感  华为推出两款商用 AI 大模型存储新品,支持 1200 万 IOPS 性能  一文看懂基础模型的定义和工作原理  宇宙探索下一阶段,机器代替人类,AI会在太空探索中取代人类吗?  百川智能发布Baichuan-13B AI模型,号称“130亿参数开源可商用”  高通发布长期产品计划,为工业和企业物联网产品提供全新组合方案  焊接协作机器人或将成为26届埃森展最大看点  猿力科技入选北京市通用人工智能产业创新伙伴计划  午报 | 字节跳动要造机器人;东方甄选首次启动自有APP|直播|  Unity 推出面向开发者的 AI 软件市场 AI Hub,股价飙涨 15%  黄仁勋:5年前,我们对AI抱有巨大期望  苹果AI战略与微软谷歌大相径庭,到底是领先还是落后?  泗洪:畅通城市“血管” ,管下机器人来帮忙  探展WAIC |万向区块链杜宇:不存在单一技术的iPhone时刻,Web3.0核心将基于AI+区块链+物联网  「社交达人」GPT-4!解读表情、揣测心理全都会  华为4G5G通信物联网收费标准公布,多年研发成果,十年花费近万亿  梦想实现!硬核科幻大片VR智能头盔即将问世  “黑科技”亮相大湾区轨交论坛 智慧交通迈向“强AI”  跟着AI大热的“光模块”到底是什么?  世界上第一个完全由人工智能驱动的图像编辑器!  基于预训练模型的金融事件分析及应用  2025 WAIC|美团无人机发布第四代新机型  “一般智力”与工艺学批判是认识AI的重要入口 | 社会科学报  人工智能正在弥合认知和表达之间的鸿沟  数据科学,解码智能未来——Altair首次提出“Frictionless AI”概念  烟台大学学生首次在全国大学生无人机航拍竞赛中获奖  首届亚太网络法实务大会召开 九位大咖探讨元宇宙与人工智能发展  无人机在电力巡检中的应用:全面解析高效巡检流程  Snap宣布研发出新技术 可大幅提升AI生成图像速度  看似低调,实则稳健:字节在AI路上会遇到什么?  掌阅科技申请阅爱聊商标 掌阅科技申请AI相关商标  人工智能在交通领域的革新:智能解决方案彻底改变交通方式  美版贴吧8000小组自爆停摆!拒绝数据被谷歌OpenAI白嫖,CEO被网友骂翻:背刺第三方应用  全国体育人工智能大会举办,专家聚焦体育人工智能领域人才培养  北交大推出国内首个开源交通大模型TransGPT,可免费商用 

 2025-04-24

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.