|
本帖最后由 jorya_txj 于 2016-5-14 18:35 编辑
raw-os 2.x中新增加了硬件抽象层hal层,很多人可能不清楚具体的用法。首先hal层的意思是指硬件抽象层的意思,实质上是一层和底下芯片无关的驱动抽象层。针对不同的芯片可以做具体的驱动封装。
hal层对于项目代码的复用是有很大的意义的。上层应用可以调用hal层接口,底下hal层只需要对接芯片的驱动即可。raw-os中提供的hal抽象层不仅仅是提供了这一层抽象,对于多任务调用来说也是安全的。
下面的代码是 i2c_master_transmit 的抽象层,我们可以看到我们采用了mutex锁来防止了多任务的重入。实质性的驱动工作是在 i2c_lld_master_transmit 里面完成的,所以只要驱动对接 i2c_lld_master_transmit 这一个函数就可以了。lld层处于hal层之下,和具体的芯片相关,不同的芯片,lld层的封装不同。
HAL_ERROR i2c_master_transmit(I2C_DRIVER *i2cp,
RAW_U32 dev_addr,
RAW_U8 *tx_buf, RAW_U32 tx_bytes,
RAW_U8 *rx_buf, RAW_U32 rx_bytes,
RAW_U32 timeout)
{
HAL_ERROR ret;
RAW_ASSERT((i2cp != 0) && (dev_addr != 0U) && (tx_bytes > 0U) && (tx_buf != 0));
raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
ret = i2c_lld_master_transmit(i2cp, dev_addr, tx_buf, tx_bytes, rx_buf, rx_bytes, timeout);
raw_mutex_put(&i2cp->i2cp_lock);
return ret;
}
对于上面的代码来说结构体 I2C_DRIVER 也是由下面的lld层的移植去实现,这样针对不同的芯片会非常的灵活,比起一般意义上的抽象要好。下面的代码是hal层一些使用的演示代码:
i2c_config.i2c_speed = 100000;
i2c_init(&I2C0);
i2c_start(&I2C0, &i2c_config);
i2c_master_transmit(&I2C0, FN_EEPROM_SLAVE_WRITE_ADDRESS, i2c_data, 3, 0, 0, 0);
对于hal层以上还有一层bsp层,这一层是和板级相关的。
比如以下的接口:
BSP_ERROR eeprom_write(RAW_U32 page_num, RAW_U32 addr, RAW_U8 *buffer, RAW_U32 size, RAW_U32 timeout, EEPROM_TYPE device_type);
BSP_ERROR eeprom_read(RAW_U32 page_num, RAW_U32 addr, RAW_U8 *buffer, RAW_U32 size, RAW_U32 timeout, EEPROM_TYPE device_type);
eeprom_write 以及eeprom_read是eeprom的驱动接口底下包含了i2c的接口逻辑去具体实现。bsp层的接口的定义和企业的业务逻辑有比较大的关联,封装的粒度各个公司可能不尽相同。企业的应用层可以直接调用bsp层的接口。
对于第三方的协议栈来说因为已经定义好了底下的驱动接口,所以可以绕开hal层的封装直接对接芯片的具体驱动。
|
|