OpenHarmony HDF WIFI之WLAN_Core 原创 精华
@[toc]
WIFI Core
在WLAN HDI 的那篇文章中,命令最终被发送到HDF WIFI驱动模块,该驱动的实现就在hdf_wifi_core.c中:
struct HdfDriverEntry g_hdfWifiEntry = {
.moduleVersion = 1,
.Bind = HdfWifiDriverBind,
.Init = HdfWlanMainInit,
.Release = HdfWlanDriverRelease,
.moduleName = "HDF_WIFI"
};
HDF_INIT(g_hdfWifiEntry);
WIFI Core 驱动对消息的处理流程如图:
由于WIFI Core所涉及的对象多且复杂,最好先来了解这些对象是如何生成的,再看他们是如何使用。
一、LocalNodeService
展开宏定义后的LocalNodeService,根据上图可了解到LocalNodeService有三个,分别用于响应base、sta、ap消息,于是就有三个文件对应实现。
typedef struct LocalNodeService {
enum MessageEngineStatus status;
OsalAtomic refCount;
struct RemoteService *(*Ref)(struct RemoteService * obj);
void (*Disref)(struct RemoteService * obj);
void (*Destroy)(struct RemoteService * obj);
//发送请求消息
void (*ExecRequestMsg)(const struct RemoteService *service, MessageContext *context);
//发送响应消息
void (*ExecResponseMsg)(const struct RemoteService *service, MessageContext *context);
//发送消息
ErrorCode (*SendMessage)(const struct RemoteService *service, MessageContext *context);
void (*Shutdown)(struct RemoteService * service);
//service类型:base、ap、sta
ServiceId serviceId;
//dispatch用于缓存消息
MessageDispatcher *dispatcher;
//响应消息的服务
struct ServiceDef *mapper;
} LocalNodeService;
以sta.c为例子,学习LocalNodeService是如何被创建的:
sta.c中定义了三个MessageDef数组,分别用于处理三种类型的HDI message。例如sta.c中定义了5个成员的数组,用于处理5个具体的sta命令,例如WifiCmdAssoc()是用于响应wifi连接命令的。
static struct MessageDef g_wifiStaFeatureCmds[] = {
DUEMessage(CMD_STA_CONNECT, WifiCmdAssoc, 0),
DUEMessage(CMD_STA_DISCONNECT, WifiCmdDisconnect, 0),
DUEMessage(CMD_STA_SCAN, WifiCmdScan, 0),
DUEMessage(CMD_STA_ABORT_SCAN, WifiCmdAbortScan, 0),
DUEMessage(CMD_STA_SET_SCAN_MAC_ADDR, WifiCmdSetScanningMacAddress, 0)
};
同时还要注意到g_wifiStaFeatureCmds下方有一句宏定义:将该宏定义展开,可得到函数CreateServiceSTAService(),该函数创建了一个ServiceDef结构体,并调用InitService()函数.同时在StaInit()在调用该函数:
ServiceDefine(STAService, STA_SERVICE_ID, g_wifiStaFeatureCmds);
/**
Service *CreateServiceSTAService(const ServiceCfg *cfg)
{
static struct ServiceDef serviceDef = {
.serviceId = STA_SERVICE_ID,
.messagesLength = sizeof(g_wifiStaFeatureCmds) / sizeof(struct MessageDef),
.messages = g_wifiStaFeatureCmds
};
return InitService(&serviceDef, cfg);
}
*/
int32_t StaInit(struct WifiFeature *feature)
{
(void)feature;
if (g_staService == NULL) {
ServiceCfg cfg = {
.dispatcherId = DEFAULT_DISPATCHER_ID
};
//g_staService = CreateServiceSTAService(&cfg);
g_staService = CreateService(STAService, &cfg);
if (g_staService == NULL) {
return HDF_FAILURE;
}
}
return HDF_SUCCESS;
}
InitService()函数在sidecar.c中,其最重要的部分是调用RegistLocalService(),而RegistLocalService简单的调用RegistServiceInner():
该函数的目的是创建LocalNodeService,但创建LocalNodeServic需要使用到MessageNode,这里先暂时不管。
//主要是创建LocalNodeServic
static ErrorCode RegistServiceInner(const NodeId nodeId, const DispatcherId dispatcherId, struct ServiceDef *mapper)
{
HDF_STATUS status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
//获取default node(非重点)
MessageNode *node = RefMessageNode(nodeId, false);
RemoteService *remoteService = NULL;
MessageDispatcher *dispatcher = NULL;
do {
//获取default dispatcher
dispatcher = RefDispatcherInner(dispatcherId, false);
//重要:调用CreateLocalNodeService(node,dispatcher, mapper)
remoteService = node->CreateRemoteService(node, dispatcher, mapper);
errCode = NotifyAllNodesServiceAdd(nodeId, mapper);
//把remoteService添加到g_servicesIndex[]
errCode = DoRegistService(nodeId, dispatcherId, remoteService);
} while (false);
return errCode;
}
CreateLocalNodeService() 创建了LocalNodeService对象。
RemoteService *CreateLocalNodeService(MessageNode *node, MessageDispatcher *dispatcher, struct ServiceDef *mapper)
{
//create local node service
LocalNodeService *service = (LocalNodeService *)OsalMemCalloc(sizeof(LocalNodeService));
do {
service->status = ME_STATUS_RUNNING;
//填充函数:处理请求消息
service->ExecRequestMsg = HandleRequestMessage;
service->ExecResponseMsg = HandleResponseMessage;
service->SendMessage = SendMessageLocalNode;
service->Shutdown = ShutdownLocalService;
service->serviceId = mapper->serviceId;
//把sta.c中定义的ServiceDef 赋值给 LocalNodeService
service->mapper = mapper;
service->dispatcher = dispatcher->Ref(dispatcher);
} while (false);
return (RemoteService *)service;
}
总结一下,调用sta.c,ap.c,wifi_base.c中的初始化函数,就能创建上图所示的LocalNodeService。
二、消息传递流程
了解了LocalNodeService是如何创建的,我们就能轻松的了解消息的传递流程。
在hdf_wifi_core.c中的HdfWifiDriverBind函数定义了HDF_WIFI驱动所提供的服务,并启动MessageRouter来创建MessageNode,创建dispatch,MessageNode和Dispatch正是我们前面创建LocalNodeService所需要的。
static int32_t HdfWifiDriverBind(struct HdfDeviceObject *dev)
{
static struct IDeviceIoService wifiService = {
.object.objectId = 1,
.Dispatch = DispatchToMessage,
};
errCode = StartMessageRouter(MESSAGE_NODE_CONFIG_DEFAULT);
errCode = EnableDefaultDispatcher();
dev->service = &wifiService;
return HDF_SUCCESS;
}
这里我们重点关注DispatchToMessage():
该函数定义在sidecar.c中。sidecar.c封装了LocalNodeService,提供接口给HDF_WIFI驱动使用,起到中介的作用。要注意到,驱动的命令是以id+HdfSBuf的形式传递进来的,需要转换成messagecontext。
int32_t DispatchToMessage(struct HdfDeviceIoClient *client, int id, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
{
//create message
context = CreateMessageContext(RESERVED_SERVICE_ID, serviceId, cmd, reqData);
context->rspData = rspData;
//从HDI发送过来的是REQ
context->requestType = MESSAGE_TYPE_SYNC_REQ;
context->client = client;
RemoteService *targetService = NULL;
do {
//获取特定的 LocalNodeService
targetService = RefRemoteService(serviceId);
//SendMessage就是在LocalNodeService创建时设置的 SendMessageLocalNode()
errCode = targetService->SendMessage(targetService, context);
} while (false);
}
SendMessage()根据message类型作不同的处理:
- sync:同步类消息需要马上处理
- async:异步类消息由RunDispatcher线程稍后处理
ErrorCode SendMessageLocalNode(const RemoteService *service, MessageContext *context)
{
//MESSAGE_TYPE_SYNC_REQ 来自HDI的同步请求,马上处理并回复
if (!context->crossNode && context->requestType == MESSAGE_TYPE_SYNC_REQ) {
//处理请求
HandleRequestMessage(service, context);
//回复
SetToResponse(context);
return context->responseStatus;
} else if (context->requestType == MESSAGE_TYPE_SYNC_RSP) {
//同步响应,释放信号量?
(void)OsalSemPost(&context->rspSemaphore);
return ME_SUCCESS;
} else {
//异步请求,交给dispatch缓存处理
return localService->dispatcher->AppendMessage(localService->dispatcher, pri, context);
}
}
HandleRequestMessage()获取定义在sta.c、wifi_base.c、ap.c的messageDef,然后指定handler函数,例如:WifiCmdAssoc()
static void HandleRequestMessage(const RemoteService *service, MessageContext *context)
{
LocalNodeService *localNodeService = (LocalNodeService *)service;
//根据commandID获取请求对应的messageDef
struct MessageDef messageDef = { NULL, 0 };
if (localNodeService->mapper != NULL && context->commandId < localNodeService->mapper->messagesLength) {
messageDef = localNodeService->mapper->messages[context->commandId];
}
//调用messageDef的函数处理请求
context->responseStatus = messageDef.handler((RequestContext *)context, context->reqData, context->rspData);
}
让我们重新回到sta.c中,看看messageDef[]中的handler函数是如何处理消息的。还是以WifiCmdAssoc()为线索:
static int32_t WifiCmdAssoc(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
{
struct WlanConnectParams params = { 0 };
WifiAssociateParams assoc = { 0 };
struct NetDevice *netdev = NULL;
ifName = HdfSbufReadString(reqData);
//设置连接参数
if (WifiFillAssocParams(&assoc, reqData) != HDF_SUCCESS) {
return HDF_FAILURE;
}
//获取netdev
if ((netdev = NetDeviceGetInstByName(ifName)) == NULL) {
HDF_LOGE("%s:netdev not found!ifName=%s", __func__, ifName);
return HDF_FAILURE;
}
//设置连接参数
if (WifiSetAssocParams(&assoc, netdev, ¶ms) != HDF_SUCCESS) {
return HDF_FAILURE;
}
do {
params.centerFreq = assoc.freq;
//开始连接wifi
ret = Connect(netdev, ¶ms);
} while (false);
}
Connect()使用 chipDriver 对象提供的接口进行连接:
inline static int32_t Connect(struct NetDevice *netDev, struct WlanConnectParams *param)
{
//获取chip driver
struct HdfChipDriver *chipDriver = GetChipDriver(netDev);
RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->staOps, Connect);
//chip driver 开始连接
return chipDriver->staOps->Connect(netDev, param);
}
至此 WIFI Core 的任务就完成了。
三、HDF WIFI 初始化
首先来看HdfWlanMainInit函数,这是驱动的初始化函数,负责生成上图所用到的所有对象。
HDF_WIFI的初始化分为三个部分:
- HdfWlanGetConfig是获取配置文件的配置信息,暂不分析。
- HdfWlanInitProduct:调用InitWifiModule 初始化wifi module(本质是初始化三个LocalNodeService)
- HdfWlanScanAndInitThread:初始化硬件
/* main init process including config, powers, load the factory, and chip init */
static int32_t HdfWlanMainInit(struct HdfDeviceObject *device)
{
//获取配置文件的配置信息
if (HdfWlanGetConfig(device) != HDF_SUCCESS) {
HDF_LOGE("%s:HdfWlanGetConfig get wlan config failed!", __func__);
return HDF_FAILURE;
}
rootConfig = HdfWlanGetModuleConfigRoot();
moduleConfig = &rootConfig->wlanConfig.moduleConfig;
//初始化Modules
if (HdfWlanInitProduct(device, moduleConfig) != HDF_SUCCESS) {
HDF_LOGE("%s:HdfWlanInitProduct failed!", __func__);
return HDF_FAILURE;
}
//初始化硬件
if (HdfWlanScanAndInitThread(device) != HDF_SUCCESS) {
HDF_LOGE("%s: LoadChipFactoryThread failed, the load process failed!", __func__);
return HDF_FAILURE;
}
}
int HdfWlanInitProduct(struct HdfDeviceObject *device, const struct HdfConfigWlanModuleConfig *config)
{
g_hdfWlanProductData = OsalMemCalloc(sizeof(struct HdfWifiProductData));
ret = InitWifiModule(&(g_hdfWlanProductData->module), config);
}
3.1、HdfWlanInitProduct
初始化WIFI Module,其根本目的是为了创建三个LocalNodeService,分别是:BASE、STA、AP LocalNodeService
函数调用流程是:InitWifiModule()->InitFeatures(),其中分别调用BaseInit()、StaInit()、ApInit()来创建LocalNodeService
static int32_t InitFeatures(struct WifiModule *module)
{
//初始化 BASE LocalNodeService
ret = BaseInit();
//获取 ApFeature、staFeature
module->feList.fe[HDF_WIFI_FEATURE_AP] = GetWifiApFeature();
module->feList.fe[HDF_WIFI_FEATURE_STA] = GetWifiStaFeature();
for (i = 0; i < HDF_WIFI_FEATURE_NUM; i++) {
if ((module->moduleConfig.hslConfig->featureMap & (1 << i)) && module->feList.fe[i] != NULL) {
//调用StaInit() ApInit()
module->feList.fe[i]->init(module->feList.fe[i]);
}
}
return HDF_SUCCESS;
}
3.2、HdfWlanScanAndInitThread
HdfWlanScanAndInitThread会回调HdfWlanInitThread函数,在其中初始化硬件,如sdio控制器,芯片电源引脚,复位引脚,驱动程序。
static int32_t HdfWlanInitThread(void *para)
{
struct HdfDeviceObject *device = (struct HdfDeviceObject *)para;
OsalSleep(initDelaySec);
devList = HdfWlanGetDeviceList();
for (i = 0; i < devList->deviceListSize; i++) {
//sdio config
ret = HdfWlanConfigSDIO(devList->deviceInst[i].bus.busIdx);
// init hardware
wlanDevice = ProbeDevice(&(devList->deviceInst[i]));
ret = HdfWlanAddDevice(wlanDevice);
// Load chip driver
(void)DevSvcManagerClntSubscribeService(wlanDevice->driverName, callback);
(void)HdfWifiInitDevice(wlanDevice);
}
}
HdfWlanInitThread也分为三个部分:
- HdfWlanConfigSDIO:由驱动开发者实现,配置sdio控制器外设
- ProbeDevice:初始化硬件
- HdfWifiInitDevice:初始化硬件驱动程序
3.2.1、HdfWlanConfigSDIO
由驱动开发者实现,配置sdio控制器外设,以海思的芯片为例:
int32_t HdfWlanConfigSDIO(uint8_t busId)
{
struct HdfConfigWlanRoot *config = HdfWlanGetModuleConfigRoot();
if (strcmp("hi3516dv300", config->wlanConfig.hostChipName) == 0) {
return ConfigHi3516DV300SDIO(busId);
}
if (strcmp("hi3518ev300", config->wlanConfig.hostChipName) == 0) {
return ConfigHi3518EV300SDIO(busId);
}
HDF_LOGE("%s: platform chip not supported!", __func__);
return HDF_FAILURE;
}
static int32_t ConfigHi3516DV300SDIO(uint8_t busId)
{
if (busId == 2) {
HDF_LOGE("%s: Config Hi3516DV300 SDIO bus %d", __func__, busId);
const uint32_t PMC_REG_ADDR_REG0 = 0x12090000;
const uint32_t PIN_REG_ADDR_CLK = 0x112F0008;
const uint32_t PIN_REG_ADDR_CMD = 0x112F000C;
const uint32_t PIN_REG_ADDR_DATA0 = 0x112F0010;
const uint32_t PIN_REG_ADDR_DATA1 = 0x112F0014;
const uint32_t PIN_REG_ADDR_DATA2 = 0x112F0018;
const uint32_t PIN_REG_ADDR_DATA3 = 0x112F001C;
REG_SET_BITS(PMC_REG_ADDR_REG0, 0x0080);
REG_WRITE(PIN_REG_ADDR_CLK, 0x601);
REG_WRITE(PIN_REG_ADDR_CMD, 0x501);
REG_WRITE(PIN_REG_ADDR_DATA0, 0x501);
REG_WRITE(PIN_REG_ADDR_DATA1, 0x501);
REG_WRITE(PIN_REG_ADDR_DATA2, 0x501);
REG_WRITE(PIN_REG_ADDR_DATA3, 0x501);
return HDF_SUCCESS;
}
HDF_LOGE("%s: SDIO bus ID %d not supportted!", __func__, busId);
return HDF_FAILURE;
}
3.2.2、ProbeDevice()
初始化 HdfWlanDevice结构体,并调用HdfWlanDevice的方法初始化 硬件wifi芯片,如上电、复位、连接总线。
static struct HdfWlanDevice *ProbeDevice(struct HdfConfigWlanDevInst *deviceConfig)
{
struct HdfWlanDevice *device = NULL;
device = (struct HdfWlanDevice *)OsalMemCalloc(sizeof(struct HdfWlanDevice));
do {
//create PowerManage and ResetManage
device->powers = HdfWlanCreatePowerManager(&deviceConfig->powers);
device->reset = HdfWlanCreateResetManager(&deviceConfig->reset, deviceConfig->bootUpTimeOut);
//上电
ret = HdfWlanPowerOnProcess(device->powers);
//复位
ret = HdfWlanResetProcess(device->reset);
//init sdio bus
ret = HdfWlanBusInit(device, &deviceConfig->bus);
} while (false);
}
HdfWlanDevice 是来描述所有wlan设备的硬件属性:例如驱动名称,芯片名称、电源、复位、连接到主控的总线
struct HdfWlanDevice {
uint8_t id;
const char *driverName; /**< Driver name */
const char *chipName; /**< Chip name */
uint32_t netIfMap; /**< WLAN device bitmap */
struct HdfWlanManufacturer manufacturer; /**< WLAN device manufacturer */
struct ResetManager *reset; /**< Chip reset management API */
struct PowerManager *powers; /**< Chip power management APIs */
struct BusDev *bus;
};
struct ResetManager {
int32_t (*Reset)(struct ResetManager *resetManager);//Resets the WLAN module using a specified reset manager
int32_t (*Release)(struct ResetManager *resetMgr); //Releases a specified reset manager.
};
struct PowerManager {
int32_t (*On)(struct PowerManager *powerMgr); //Powers on the device using a specified power manager.
int32_t (*Off)(struct PowerManager *powerMgr); //Powers off the device using a specified power manager.
int32_t (*Release)(struct PowerManager *powerMgr); //Releases power using a specified power manager.
};
struct BusDev {
void *devBase;
struct DevOps ops;
struct PrivateData priData;
};
调用HdfWlanCreatePowerManager()会初始化PowerManager,HdfWlanPowerOnProcess 会调用PowerManager->on(),即HdfWlanChipPowerOn(),通过设置gpio引脚来使能wlan芯片。
static int32_t HdfWlanChipPowerOn(struct PowerManager* powerMgr)
{
powerMgrimpl = (struct PowerManagerImpl*)powerMgr;
ret = HdfWlanSinglePowerActive(&powerMgrimpl->powerDatas.power0);
ret = HdfWlanSinglePowerActive((struct HdfConfigWlanPower*)&powerMgrimpl->powerDatas.power1);
return HDF_SUCCESS;
}
static int32_t HdfWlanSinglePowerActive(struct HdfConfigWlanPower* powerDate)
{
//set gpio pin
ret = GpioSetDir(powerDate->gpioId, 1);
OsalMSleep(powerDate->powerSeqDelay);
ret = GpioWrite(powerDate->gpioId, powerDate->activeLevel);
return HDF_SUCCESS;
}
ResetManager的实现也是类似的
3.2.3、HdfWifiInitDevice()
获取 HdfChipDriverFactory,并调用其InitChip()方法来初始化芯片硬件,调用HdfWlanInitInterfaces()初始化HdfChipDriver ;
int32_t HdfWifiInitDevice(struct HdfWlanDevice *device)
{
struct HdfChipDriverFactory *chipDriverFact = NULL;
//获取 HdfChipDriverFactory 管理所有驱动程序
chipDriverFact = HdfWlanGetDriverFactory(device->driverName);
if (chipDriverFact->InitChip != NULL) {
//初始化芯片
ret = chipDriverFact->InitChip(device);
}
//创建wifi芯片的接口
ret = HdfWlanInitInterfaces(device, chipDriverFact);
}
HdfChipDriverFactory结构体由硬件厂商实现,其最终目的是为了创建chip driver.
chip driver
HdfWlanInitInterfaces 创建对应芯片的HdfChipDriver ,创建netdevice,调用chipDriver->init()初始化芯片驱动程序(即由驱动开发者根据具体芯片实现的)
static int32_t HdfWlanInitInterface(struct HdfWlanDevice *device, struct HdfChipDriverFactory *factory, uint8_t index)
{
NetDevice *netDev = NULL;
struct HdfChipDriver *chipDriver = NULL;
do {
//创建 chip driver
chipDriver = factory->Build(device, index);
//创建 NetDev
netDev = AllocPlatformNetDevice(device);
data = GetPlatformData(netDev);
data->device = device;
//call chipdriver to init the chip
ret = chipDriver->init(chipDriver, netDev);
//将netdev和chip driver 绑定
data->chipDriver = chipDriver;
chipDriver = NULL;
} while (false);
}
HdfChipDriver 是直接操作wifi 芯片硬件的驱动,也必须由驱动厂商实现,其中HdfMac80211BaseOps、HdfMac80211STAOps、HdfMac80211STAOps都需要实现具体的硬件操作。
struct HdfChipDriver {
uint16_t type; /**< Chip type */
char name[MAX_WIFI_COMPONENT_NAME_LEN]; /**< Chip name */
struct HdfMac80211BaseOps *ops;
struct HdfMac80211STAOps *staOps;
struct HdfMac80211STAOps *apOps;
void *priv;
//Initializes a chip driver.
int32_t (*init)(struct HdfChipDriver *chipDriver, NetDevice *netDev);
//Deinitializes a chip driver.
int32_t (*deinit)(struct HdfChipDriver *chipDriver, NetDevice *netDev);
};
struct HdfMac80211BaseOps {
//设置wifi模式
int32_t (*SetMode)(NetDevice *netDev, enum WlanWorkMode mode);
//添加key
int32_t (*AddKey)(struct NetDevice *netDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr,
struct KeyParams *params);
int32_t (*DelKey)(struct NetDevice *netDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr);
int32_t (*SetDefaultKey)(struct NetDevice *netDev, uint8_t keyIndex, bool unicast, bool multicas);
int32_t (*GetDeviceMacAddr)(NetDevice *netDev, int32_t type, uint8_t *mac, uint8_t len);
int32_t (*SetMacAddr)(NetDevice *netDev, uint8_t *mac, uint8_t len);
int32_t (*SetTxPower)(NetDevice *netDev, int32_t power);
//获取芯片支持的带宽
int32_t (*GetValidFreqsWithBand)(NetDevice *netDev, int32_t band, int32_t *freqs, uint32_t *num);
//获取芯片的能力
int32_t (*GetHwCapability)(NetDevice *netDev, struct WlanHwCapability **capability);
int32_t (*RemainOnChannel)(NetDevice *netDev, WifiOnChannel *onChannel);
int32_t (*CancelRemainOnChannel)(NetDevice *netDev);
int32_t (*ProbeReqReport)(NetDevice *netDev, int32_t report);
int32_t (*AddIf)(NetDevice *netDev, WifiIfAdd *ifAdd);
int32_t (*RemoveIf)(NetDevice *netDev, WifiIfRemove *ifRemove);
int32_t (*SetApWpsP2pIe)(NetDevice *netDev, WifiAppIe *appIe);
int32_t (*GetDriverFlag)(struct NetDevice *netDev, WifiGetDrvFlags **params);
int32_t (*SendAction)(struct NetDevice *netDev, WifiActionData *actionData);
int32_t (*GetIftype)(struct NetDevice *netDev, uint8_t *iftype);
};