

前言

有移植过BT, WIFI, TP等驱动的会发现厂家都会提供一个固件(Firmware)文件。这个文件一般是对应芯片的固件。为什么不将固件烧录到芯片中呢?主要有两个好处,第一是节省成本,第二是方便升级。


固件API简介

在Linux系统中,设备驱动程序处于内核态,而固件文件处于用户态,因此需要一个安全稳定可靠的机制,用来确保设备驱动程序成功加载固件文件,所以Linux提供了固件API。这些固件API不仅能加载固件文件,还能加载参数文件, 比如校准参数。


固件搜索路径

在Linux系统下,应该将固件放在哪里,才能让驱动能够找到呢?主要有如下几个路径:
fw_path_para : 模块参数,默认为空。
/lib/firmware/updates/UTS_RELEASE/
/lib/firmware/updates/
/lib/firmware/UTS_RELEASE/
/lib/firmware/


API函数

Linux版本:5.15
固件请求
/*
*同步固件请求
* firmware_p:固件镜像指针
* name:镜像文件名
* device:正在加载固件的设备
*/
int request_firmware(const struct firmware **firmware_p,
const char *name, struct device *device)
//同上,只是找不到时不提示警告
int firmware_request_nowarn(const struct firmware **firmware,
const char *name, struct device *device)
复制
/*
*异步固件请求
* module: 请求固件的模块
* uevent: 是否发送uevent
* name:镜像文件名
* device:正在加载固件的设备
* gfp:分配标志
* context:上下文,会传给cont回调函数
* cont:请求结束回调函数
*/
int request_firmware_nowait(struct module *module,
bool uevent, const char *name,
struct device *device, gfp_t gfp,
void *context,
void (*cont)(const struct firmware *fw, void *context))
复制
释放固件
release_firmware(const struct firmware *fw)
复制


典型用法

if(request_firmware(&fw_entry, $FIRMWARE, device) == 0)
copy_fw_to_device(fw_entry->data, fw_entry->size);
release_firmware(fw_entry);
复制
1. 使用request_firmware()加载固件
2. 将固件内容传到芯片设备上
3. 使用release_firmware()释放资源


例子

static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
//.......
//加载固件
if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) {
BT_ERR("Mini driver request failed");
usb_free_urb(data->urb);
return -EIO;
}
BT_DBG("minidrv data %p size %zu", firmware->data, firmware->size);
size = max_t(uint, firmware->size, 4096);
data->buffer = kmalloc(size, GFP_KERNEL);
if (!data->buffer) {
BT_ERR("Can't allocate memory for mini driver");
release_firmware(firmware);
usb_free_urb(data->urb);
return -ENOMEM;
}
//拷贝固件数据到buffer中
memcpy(data->buffer, firmware->data, firmware->size);
//通过USB发送数据到设备上
usb_fill_bulk_urb(data->urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP),
data->buffer, firmware->size, bcm203x_complete, data);
//释放固件资源
release_firmware(firmware);
//.......
}
复制

往期推荐
文章转载自嵌入式软件开发交流,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。