feature:Add adc user mode interface

Signed-off-by: mahai <mahai5@h-partners.com>
This commit is contained in:
mahai
2022-01-26 15:14:31 +08:00
parent 63e8fd0c45
commit 091dbc218d
6 changed files with 357 additions and 93 deletions
+10
View File
@@ -28,6 +28,16 @@ void AdcClose(DevHandle handle);
int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val);
/**
* @brief Enumerates ADC I/O commands.
*
* @since 1.0
*/
enum AdcIoCmd {
ADC_IO_READ = 0, /**< Read the A/D data. */
ADC_IO_OPEN, /**< Open the ADC device. */
ADC_IO_CLOSE, /**< Close the ADC device. */
};
#ifdef __cplusplus
#if __cplusplus
}
-6
View File
@@ -46,12 +46,6 @@ struct AdcLockMethod {
void (*unlock)(struct AdcDevice *device);
};
enum AdcIoCmd {
ADC_IO_READ = 0,
ADC_IO_OPEN,
ADC_IO_CLOSE,
};
int32_t AdcDeviceAdd(struct AdcDevice *device);
void AdcDeviceRemove(struct AdcDevice *device);
+169 -83
View File
@@ -18,6 +18,8 @@
#define LOCK_WAIT_SECONDS_M 1
#define ADC_BUFF_SIZE 4
#define ADC_HANDLE_SHIFT 0xFF00U
struct AdcManager {
struct IDeviceIoService service;
struct HdfDeviceObject *device;
@@ -48,6 +50,69 @@ static const struct AdcLockMethod g_adcLockOpsDefault = {
.unlock = AdcDeviceUnlockDefault,
};
static inline int32_t AdcDeviceLock(struct AdcDevice *device)
{
if (device->lockOps == NULL || device->lockOps->lock == NULL) {
return HDF_ERR_NOT_SUPPORT;
}
return device->lockOps->lock(device);
}
static inline void AdcDeviceUnlock(struct AdcDevice *device)
{
if (device->lockOps != NULL && device->lockOps->unlock != NULL) {
device->lockOps->unlock(device);
}
}
int32_t AdcDeviceStart(struct AdcDevice *device)
{
int32_t ret;
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_OBJECT;
}
if (device->ops == NULL || device->ops->start == NULL) {
HDF_LOGE("%s: ops or start is null", __func__);
return HDF_ERR_NOT_SUPPORT;
}
if (AdcDeviceLock(device) != HDF_SUCCESS) {
HDF_LOGE("%s: lock add device failed", __func__);
return HDF_ERR_DEVICE_BUSY;
}
ret = device->ops->start(device);
AdcDeviceUnlock(device);
return ret;
}
int32_t AdcDeviceStop(struct AdcDevice *device)
{
int32_t ret;
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_OBJECT;
}
if (device->ops == NULL || device->ops->stop == NULL) {
HDF_LOGE("%s: ops or stop is null", __func__);
return HDF_ERR_NOT_SUPPORT;
}
if (AdcDeviceLock(device) != HDF_SUCCESS) {
HDF_LOGE("%s: lock add device failed", __func__);
return HDF_ERR_DEVICE_BUSY;
}
ret = device->ops->stop(device);
AdcDeviceUnlock(device);
return ret;
}
static int32_t AdcManagerAddDevice(struct AdcDevice *device)
{
int32_t ret;
@@ -134,6 +199,45 @@ static struct AdcDevice *AdcManagerFindDevice(uint32_t number)
return device;
}
struct AdcDevice *AdcDeviceGet(uint32_t number)
{
return AdcManagerFindDevice(number);
}
void AdcDevicePut(struct AdcDevice *device)
{
(void)device;
}
static struct AdcDevice *AdcDeviceOpen(uint32_t number)
{
int32_t ret;
struct AdcDevice *device = NULL;
device = AdcDeviceGet(number);
if (device == NULL) {
return NULL;
}
ret = AdcDeviceStart(device);
if (ret != HDF_SUCCESS) {
return NULL;
}
return device;
}
static void AdcDeviceClose(struct AdcDevice *device)
{
if (device == NULL) {
HDF_LOGE("%s: close adc device fail", __func__);
return;
}
(void)AdcDeviceStop(device);
AdcDevicePut(device);
}
int32_t AdcDeviceAdd(struct AdcDevice *device)
{
int32_t ret;
@@ -173,31 +277,6 @@ void AdcDeviceRemove(struct AdcDevice *device)
(void)OsalSpinDestroy(&device->spin);
}
struct AdcDevice *AdcDeviceGet(uint32_t number)
{
return AdcManagerFindDevice(number);
}
void AdcDevicePut(struct AdcDevice *device)
{
(void)device;
}
static inline int32_t AdcDeviceLock(struct AdcDevice *device)
{
if (device->lockOps == NULL || device->lockOps->lock == NULL) {
return HDF_ERR_NOT_SUPPORT;
}
return device->lockOps->lock(device);
}
static inline void AdcDeviceUnlock(struct AdcDevice *device)
{
if (device->lockOps != NULL && device->lockOps->unlock != NULL) {
device->lockOps->unlock(device);
}
}
int32_t AdcDeviceRead(struct AdcDevice *device, uint32_t channel, uint32_t *val)
{
int32_t ret;
@@ -227,73 +306,36 @@ int32_t AdcDeviceRead(struct AdcDevice *device, uint32_t channel, uint32_t *val)
return ret;
}
int32_t AdcDeviceStart(struct AdcDevice *device)
{
int32_t ret;
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_OBJECT;
}
if (device->ops == NULL || device->ops->start == NULL) {
HDF_LOGE("%s: ops or start is null", __func__);
return HDF_ERR_NOT_SUPPORT;
}
if (AdcDeviceLock(device) != HDF_SUCCESS) {
HDF_LOGE("%s: lock add device failed", __func__);
return HDF_ERR_DEVICE_BUSY;
}
ret = device->ops->start(device);
AdcDeviceUnlock(device);
return ret;
}
int32_t AdcDeviceStop(struct AdcDevice *device)
{
int32_t ret;
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_OBJECT;
}
if (device->ops == NULL || device->ops->stop == NULL) {
HDF_LOGE("%s: ops or stop is null", __func__);
return HDF_ERR_NOT_SUPPORT;
}
if (AdcDeviceLock(device) != HDF_SUCCESS) {
HDF_LOGE("%s: lock add device failed", __func__);
return HDF_ERR_DEVICE_BUSY;
}
ret = device->ops->stop(device);
AdcDeviceUnlock(device);
return ret;
}
static int32_t AdcManagerIoOpen(struct HdfSBuf *data, struct HdfSBuf *reply)
{
uint32_t number;
if (data == NULL || reply == NULL) {
HDF_LOGE("%s: invalid data or reply!", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (!HdfSbufReadUint32(data, &number)) {
HDF_LOGE("%s: read data failed!", __func__);
return HDF_ERR_IO;
}
if (number < 0 || number >= ADC_DEVICES_MAX || reply == NULL) {
HDF_LOGE("%s: invalid number!", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (AdcDeviceGet(number) == NULL) {
if (AdcDeviceOpen(number) == NULL) {
HDF_LOGE("%s: get device %u failed", __func__, number);
return HDF_ERR_NOT_SUPPORT;
}
if (!HdfSbufWriteUint32(reply, number)) {
number = (uint32_t)(number + ADC_HANDLE_SHIFT);
if (!HdfSbufWriteUint32(reply, (uint32_t)(uintptr_t)number)) {
HDF_LOGE("%s: write reply failed!", __func__);
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
@@ -301,28 +343,66 @@ static int32_t AdcManagerIoClose(struct HdfSBuf *data, struct HdfSBuf *reply)
{
uint32_t number;
if (data == NULL) {
HDF_LOGE("%s: invalid data!", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (!HdfSbufReadUint32(data, &number)) {
HDF_LOGE("%s: read data failed!", __func__);
return HDF_ERR_IO;
}
number = (uint32_t)(number - ADC_HANDLE_SHIFT);
if (number < 0 || number >= ADC_DEVICES_MAX) {
HDF_LOGE("%s: get device %u failed", __func__, number);
return HDF_ERR_INVALID_PARAM;
}
AdcDevicePut(AdcManagerFindDevice(number));
AdcDeviceClose(AdcManagerFindDevice(number));
return HDF_SUCCESS;
}
static int32_t AdcManagerIoRead(struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)data;
(void)reply;
return HDF_SUCCESS;
int32_t ret;
uint32_t number;
uint32_t channel;
uint32_t val;
if (data == NULL || reply == NULL) {
HDF_LOGE("%s: invalid data or reply!", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (!HdfSbufReadUint32(data, &number)) {
HDF_LOGE("AdcManagerIoRead: read handle failed!");
return HDF_ERR_IO;
}
if (!HdfSbufReadUint32(data, &channel)) {
HDF_LOGE("AdcManagerIoRead: read handle failed!");
return HDF_ERR_IO;
}
number = (uint32_t)(number - ADC_HANDLE_SHIFT);
ret = AdcDeviceRead(AdcManagerFindDevice(number), channel, &val);
if(ret != HDF_SUCCESS) {
HDF_LOGE("AdcManagerIoRead: read val failed!");
return HDF_ERR_IO;
}
if (!HdfSbufWriteUint32(reply, val)) {
HDF_LOGE("%s: write val fail!", __func__);
return HDF_ERR_IO;
}
return ret;
}
static int32_t AdcManagerDispatch(struct HdfDeviceIoClient *client, int cmd,
struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret;
switch (cmd) {
case ADC_IO_OPEN:
@@ -332,10 +412,15 @@ static int32_t AdcManagerDispatch(struct HdfDeviceIoClient *client, int cmd,
case ADC_IO_READ:
return AdcManagerIoRead(data, reply);
default:
ret = HDF_ERR_NOT_SUPPORT;
break;
return HDF_ERR_NOT_SUPPORT;
}
return ret;
return HDF_SUCCESS;
}
static int32_t AdcManagerBind(struct HdfDeviceObject *device)
{
(void)device;
return HDF_SUCCESS;
}
static int32_t AdcManagerInit(struct HdfDeviceObject *device)
@@ -391,6 +476,7 @@ static void AdcManagerRelease(struct HdfDeviceObject *device)
struct HdfDriverEntry g_adcManagerEntry = {
.moduleVersion = 1,
.Bind = AdcManagerBind,
.Init = AdcManagerInit,
.Release = AdcManagerRelease,
.moduleName = "HDF_PLATFORM_ADC_MANAGER",
+158
View File
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_io_service_if.h"
#include "hdf_log.h"
#include "adc_if.h"
#define HDF_LOG_TAG adc_if_u_c
#define ADC_SERVICE_NAME "HDF_PLATFORM_ADC_MANAGER"
static void *AdcManagerGetService(void)
{
static void *manager = NULL;
if (manager != NULL) {
return manager;
}
manager = (void *)HdfIoServiceBind(ADC_SERVICE_NAME);
if (manager == NULL) {
HDF_LOGE("%s: fail to get adc manager!", __func__);
}
return manager;
}
DevHandle AdcOpen(uint32_t number)
{
int32_t ret;
struct HdfIoService *service = NULL;
struct HdfSBuf *data = NULL;
struct HdfSBuf *reply = NULL;
uint32_t handle;
service = (struct HdfIoService *)AdcManagerGetService();
if (service == NULL) {
return NULL;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("%s: malloc data fail!", __func__);
return NULL;
}
reply = HdfSbufObtainDefaultSize();
if (reply == NULL) {
HDF_LOGE("%s: malloc reply fail!", __func__);
HdfSbufRecycle(data);
return NULL;
}
if (!HdfSbufWriteUint32(data, (uint32_t)number)) {
HDF_LOGE("%s: write number fail!", __func__);
goto ERR;
}
ret = service->dispatcher->Dispatch(&service->object, ADC_IO_OPEN, data, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: service call open fail:%d", __func__, ret);
goto ERR;
}
if (!HdfSbufReadUint32(reply, &handle)) {
HDF_LOGE("%s: read handle fail!", __func__);
goto ERR;
}
HdfSbufRecycle(data);
HdfSbufRecycle(reply);
return (DevHandle)(uintptr_t)handle;
ERR:
HdfSbufRecycle(data);
HdfSbufRecycle(reply);
return NULL;
}
void AdcClose(DevHandle handle)
{
int32_t ret;
struct HdfIoService *service = NULL;
struct HdfSBuf *data = NULL;
service = (struct HdfIoService *)AdcManagerGetService();
if (service == NULL) {
return;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
return;
}
if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) {
HDF_LOGE("%s: write handle fail!", __func__);
HdfSbufRecycle(data);
return;
}
ret = service->dispatcher->Dispatch(&service->object, ADC_IO_CLOSE, data, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: close handle fail:%d", __func__, ret);
}
HdfSbufRecycle(data);
}
int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val)
{
int32_t ret;
struct HdfSBuf *data = NULL;
struct HdfSBuf *reply = NULL;
struct HdfIoService *service = NULL;
service = (struct HdfIoService *)AdcManagerGetService();
if (service == NULL) {
return HDF_PAL_ERR_DEV_CREATE;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("%s: failed to obtain data!", __func__);
return HDF_ERR_MALLOC_FAIL;
}
reply = HdfSbufObtainDefaultSize();
if (reply == NULL) {
HdfSbufRecycle(data);
return HDF_ERR_MALLOC_FAIL;
}
if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) {
HDF_LOGE("%s: write handle fail!", __func__);
ret = HDF_ERR_IO;
goto EXIT;
}
if (!HdfSbufWriteUint32(data, (uint32_t)channel)) {
HDF_LOGE("%s: write adc number failed!", __func__);
ret = HDF_ERR_IO;
goto EXIT;
}
ret = service->dispatcher->Dispatch(&service->object, ADC_IO_READ, data, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: failed to send service call:%d", __func__, ret);
goto EXIT;
}
if (!HdfSbufReadUint32(reply, val)) {
HDF_LOGE("%s: read sbuf failed", __func__);
ret = HDF_ERR_IO;
goto EXIT;
}
goto EXIT;
EXIT:
HdfSbufRecycle(data);
HdfSbufRecycle(reply);
return ret;
}
@@ -55,6 +55,11 @@ HWTEST_F(HdfLiteAdcTest, AdcTestRead001, TestSize.Level1)
{
struct HdfTestMsg msg = {TEST_PAL_ADC_TYPE, ADC_TEST_CMD_READ, -1};
EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
printf("%s: kernel test done, then for user...\n", __func__);
EXPECT_EQ(0, AdcTestExecute(ADC_TEST_CMD_READ));
printf("%s: exit!\n", __func__);
}
/**
@@ -67,6 +72,11 @@ HWTEST_F(HdfLiteAdcTest, AdcTestMultiThread001, TestSize.Level1)
{
struct HdfTestMsg msg = {TEST_PAL_ADC_TYPE, ADC_TEST_CMD_MULTI_THREAD, -1};
EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
printf("%s: kernel test done, then for user...\n", __func__);
EXPECT_EQ(0, AdcTestExecute(ADC_TEST_CMD_MULTI_THREAD));
printf("%s: exit!\n", __func__);
}
/**
@@ -79,5 +89,10 @@ HWTEST_F(HdfLiteAdcTest, AdcTestReliability001, TestSize.Level1)
{
struct HdfTestMsg msg = {TEST_PAL_ADC_TYPE, ADC_TEST_CMD_RELIABILITY, -1};
EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
printf("%s: kernel test done, then for user...\n", __func__);
EXPECT_EQ(0, AdcTestExecute(ADC_TEST_CMD_RELIABILITY));
printf("%s: exit!\n", __func__);
}
+5 -4
View File
@@ -37,7 +37,7 @@ static int32_t AdcTestGetConfig(struct AdcTestConfig *config)
return HDF_ERR_NOT_SUPPORT;
}
reply = HdfSBufObtain(sizeof(*config) + sizeof(uint64_t));
reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t));
if (reply == NULL) {
HDF_LOGE("%s: failed to obtain reply", __func__);
return HDF_ERR_MALLOC_FAIL;
@@ -113,7 +113,7 @@ int32_t AdcTestRead(void)
value[i] = 0;
ret = AdcRead(tester->handle, tester->config.channel, &value[i]);
if (ret != HDF_SUCCESS || value[i] >= (1U << tester->config.dataWidth)) {
HDF_LOGE("%s: read value invalid:%u, ret:%d", __func__, value[i], ret);
HDF_LOGE("%s: read value failed, ret:%d", __func__, ret);
return HDF_ERR_IO;
}
}
@@ -141,6 +141,7 @@ static int AdcTestThreadFunc(void *param)
ret = AdcRead(tester->handle, tester->config.channel, &val);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: AdcRead failed, ret:%d", __func__, ret);
*((int32_t *)param) = 1;
return HDF_ERR_IO;
}
}
@@ -155,9 +156,9 @@ int32_t AdcTestMultiThread(void)
int32_t ret;
struct OsalThread thread1, thread2;
struct OsalThreadParam cfg1, cfg2;
int32_t count1, count2;
int32_t count1 = 0;
int32_t count2 = 0;
count1 = count2 = 0;
HDF_LOGI("%s: enter", __func__);
ret = OsalThreadCreate(&thread1, (OsalThreadEntry)AdcTestThreadFunc, (void *)&count1);
if (ret != HDF_SUCCESS) {