ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Chrome EC框架探索_0.0_引言

2019-11-08 22:00:55  阅读:507  来源: 互联网

标签:封装 Chrome 0.0 EC 嵌入式 int GPIO i2c


0.0 引言

        嵌入式硬件抽象框架常常面临着这样的尴尬:封装层次较高的(arduino,mbed)不能充分暴露必要的API并面临着性能问题,封装层次较低的(HAL,LL)接口复杂且开发困难。近日发现的一个框架Chrome Embed Controller(下简称EC)较好地权衡了开发效率和运行效率,还具有其他的一些可贵的特性。先来看看EC的几个常用API:

  //GPIO declaration //GPIO(name, pin, flag) GPIO(PD11,          PIN(D, 11), GPIO_OUT_HIGH)//declare as output GPIO(PC6,       PIN(C, 6), GPIO_INPUT) //declare as input   gpio_set_level(GPIO_PD11, 1); //set GPIO output int input = gpio_get_level(GPIO_PC6); //read GPIO input   //initialize an i2c port GPIO(I2C1_SCL, PIN(B, 6), GPIO_ODR_HIGH) // I2C port 1 SCL GPIO(I2C1_SDA, PIN(B, 7), GPIO_ODR_HIGH) // I2C port 1 SDA ALTERNATE(PIN_MASK(B, 0x00C0), GPIO_ALT_F1, MODULE_I2C, GPIO_PULL_UP) const struct i2c_port_t i2c_ports[] = { {"test", STM32_I2C2_PORT, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);   //int i2c_write8(int port, int slave_addr, int offset, int data) i2c_write8(1, 0x40, 0x2 + bank, 0x4C); //write u2c output //int i2c_read8(int port, int slave_addr, int offset, int *data) i2c_read8(1, 0x40, 0x6 + bank, & tmp); //read i2c input
 

怎么样,是不是比stdlib和HAL什么的简洁多了?作为一个为专门用途设计的框架,将EC用于通用开发的资料哪怕在国外也寥寥无几。本文首先是我自己探索EC过程中的笔记,更希望能让这样一个优秀且有巨大潜力的框架为嵌入式开发者所知、所用。

What's EC?

  • EC是较新的chromebook上用于硬件管理和启动引导的硬件
  • chromebook团队认为传统BIOS是bullshit,于是自己用通用嵌入式SoC实现了一个作为替代(所以不要对Google说you can you up, the do can and they will up)
  • EC也指运行在该硬件上的嵌入式程序框架,Google团队将其基于BSD License开源(后文中的EC多指该框架)
  • EC具有传统BIOS启动和引导OS以及硬件管理的功能,所以需要与CPU(也称AP,应用处理器)通信
  • EC还直接控制着chromebook上的诸多设备,如键盘,PMU,各种传感器等,所以集成了它们的驱动
  • 尽管EC原本设计用于chromebook,但可以直接移植到独立的MCU上,即我们可以将它用于自己的项目。这也是本文的主要目的。

How does EC works?

任务(Tasks)

  • EC并没有暴露程序入口点(main函数)。我们的程序需要以任务的形式交给调度器执行。
  • 和其他任务调度器一样,EC中的任务是函数
  • 任务有预设的优先级,并在中断时发生抢占
  • 用户把需要执行的任务声明在一个单独文件里

模块(Modules)

  • 模块就是封装好的各个功能单元,有程序体和对应的头文件
  • 既包括SoC上的外设(UART, SPI, etc.)又包括一些硬件设备(传感器,键盘,etc.),还有非硬件的控制逻辑(手势控制,SHA1,etc.)。
  • 通过头文件引入工程,含有初始化函数(配置使用前需要设定的一些寄存器)

控制台(Console)

  • EC使用I2C,SPI或LPC总线与AP通信,尽管EC实际上最终被映射成一个USB设备
  • EC的console执行用户在终端上发来的一些预定义的指令,可以是自带的或用户自定义的,包括打印运行状态,硬件操作和模块的一些操作等。每个模块的操作指令定义在独立的文件里。
  • EC可以直接通过控制台升级固件
  • 控制台也是一个模块,它在debug时可以提供极大的便利,在生产时若不需要也可以不引入

多平台适配(标题格式还想再挣扎一下)

  • 由于不同型号的chromebook使用不同种类的EC控制器,EC固件需要进行跨平台适配
  • EC巧妙设计的API允许用户只针对不同SoC做少量设定即可移植代码
  • 这些设定以宏定义的形式暴露给用户,包括系统时钟,FLASH和RAM大小等
  • 每个平台的设定被写入独立的config文件中
  • 注意:本教程以STM32为平台

Why EC?

  • Light and Fast

    EC不基于任何现有框架,而是直接对寄存器操作进行了一定层次的封装。这使得它甚至可以运行在32MHz/16kb RAM的STM32L151上——除非自己造轮子,这可能是现在最轻量的多任务嵌入式框架了。
  • 简明的API

    例如,要声明一个GPIO引脚,只需要写一行 GPIO(name, pin, flags) ,让GPIO_XXXX()、GPIO_Typedef啥的都见鬼去吧
  • 跨平台硬件抽象

    正如前文所述,EC是一个跨平台框架,目前已涉及意法STM32、德仪TM4、新唐npcx、Microchip mec1322等产品线,覆盖ARM cortex-m, cortex-m0, nds32等架构。EC将各平台上不同的底层操作封装成统一、高级、简洁的API供用户调用,实现了跨平台、高性能的硬件抽象。
  • 专长

    如果你正在寻找一个合适的方案来辅助高级SoC(比如AP)的启动和硬件管理,那EC无疑是你的极佳选择!EC集成了boot,电源管理,常见IO设备驱动等必要的功能,可以大大简化你的开发流程。又或者你想驱动一些只有在笔记本上应用较多的设备,这些库对于嵌入式MCU不太常见(e.g.触摸板,PD物理层,etc.),EC很可能包含了这些驱动。
  • Google,Yes!

    EC由Google团队开发和维护。EC为千万台chromebook产品提供底层支持。EC有完善的单元和闭环测试程序。EC迄今已有5年的历史,其间很好地证明了它可以胜任传统BIOS的工作并且做得更好。这几点保证了EC的代码质量和健壮性——相比之下,把个人建立和维护的封装库用在某些场合就显得不那么令人放心了。另外,EC的维护和更新至今仍然非常活跃,并且团队对于合并修改的请求的响应非常积极。

……But noting is perfect

你不能……

  • 使用堆

    EC的任务调度器的内存分配机制不允许使用动态内存。尽管如此,EC仍然提供了一个共享缓冲区(Shared Memory Buffer)——目前仅用于debug。实际上因为缺少MMU,降低的可靠性和高昂的开销,在嵌入式系统上使用动态内存一直不被建议。而禁用堆从根本上杜绝了内存泄漏,这在稳定性上带来的巨大提升使得副作用的一点点限制显得不值一提了。
  • ……以及那些并不是很通用的外设

    用作EC的MCU大多较为低端,所以很多高端MCU才有的功能并没有被EC实现或高层封装(e.g.DAC,FSMC,Ethernet,etc.),一些显然对于chromebook没用的功能也同样没有(e.g. CAN)。你可能想自己实现一些外设封装库,但要注意不要与EC的内存管理和资源锁机制冲突。
  • 没有一颗热爱折腾的心

    如果你对嵌入式开发毫无兴趣而只想make things work,EC极可能不是你的最佳选择。EC不是被设计用于通用嵌入式开发的,没有arduino、mbed等流行平台那样完善的生态和丰富的资源——实际上有关于使用EC进行通用开发的资料少得可怜。这意味着你需要自己实现每个EC未封装的功能并有相当的解决问题的能力。

……以及我个人的一点吐槽(TL;DR)

  • 泛滥的宏

    EC在宏的应用上简直称得上出(sang)神(xin)入(bing)化(kuang),例如GPIO的三种声明全都是宏函数你敢信?虽然知道在嵌入式系统上为了提升运行时效率这是常规操作,但读源码的时候我还是想【脏话】
  • 简单不简约

    虽然EC并没有mbed等平台那样的宏图壮志,但却有着不输任何框架的独创设计——"独创"在这里没有褒义。EC使用枚举来声明引脚和任务,使用数组来声明外设,与主流框架使用函数的声明风格相比显得特立独行。尤其是任务和引脚的声明都需要写在独立的文件里,应该是出于被多个文件依赖和增加可维护性的考虑。这样的设计似乎有点声明式的味道,可能有更好的性能,也可能是为了简化针对多任务的统一资源管理的妥协。但无疑的是,这种集中的静态的声明风格损失了灵活性,增加了代码移植和进一步封装的难度,并产生了额外的学习负担。
  • 向上污染的底层特性

    EC的封装为我们省去了大量繁琐的初始化和配置等操作,但恼人的底层特性仍有部分残余,比如基于位操作的配置和令人眼花缭乱的16进制常量。可以通过添加一些简单的宏摆脱这些麻烦,不知为什么已经大面积使用宏的EC没有这么做。更致命的是,这些大量的宏给进一步的高层封装带来了巨大的困难,实际上除非从底层重构,我想不出在接口中完全消除这些宏的办法。

参考资料

标签:封装,Chrome,0.0,EC,嵌入式,int,GPIO,i2c
来源: https://www.cnblogs.com/Excr/p/11823530.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有