Я занимаюсь разработкой программного драйвера для внутреннего аналого-цифрового преобразователя на эта платформа. Периферийное устройство аналого-цифрового преобразователя описано ниже. документ. Драйвер написан на C ++ и основан на существующем драйвере, который был разработан производителем платформы на языке C. Причина, по которой я решил обернуть существующий драйвер в C ++, заключается в том, что я хотел бы достичь состояния, в котором этот драйвер представляет собой согласованный уровень аппаратной абстракции с другими моими драйверами, уже написанными на C ++. Во время разработки драйвера я имел в виду приведенную ниже схему оборудования, которая описывает, как внутренний аналого-цифровой преобразователь будет использоваться в моем приложении.
Что касается дизайна драйвера, я выбрал следующий подход:
Я решил инкапсулировать драйвер в класс
AdcInt
который предлагает интерфейс для использования аналого-цифрового преобразователя с верхнего уровня программного обеспечения. Предполагаемое использование драйвера следующее. После создания драйвераinitialize
вызывается метод. Вupdate
метод должен вызываться периодически (например, из задачи RTOS) с соответствующим периодом относительно выбранных физических величин. Как только метод isReady вернет true, клиентский код может начать считывать образцы a / d черезgetValue
метод или отслеживать возникновение тревоги черезisAlarmActive
методв связи с тем, что периферийное устройство a / d может быть сконфигурировано разнообразным образом, я решил определить специальный класс
AdcIntCfgManager
который управляет этой конфигурацией, т.е. работает на
AdcIntCfg
struct (которая заполняется программистом более высокого уровня) и предлагает набор методов для получения данных конфигурации
AdcInt.h
#include "AdcIntCfgManager.h"
#include "xsysmon.h"
#include <cstdint>
class AdcInt
{
public:
enum class Input
{
kChannel00,
kChannel01,
kChannel02,
kChannel03,
kChannel04,
kChannel05,
kChannel06,
kChannel07,
kChannel08,
kChannel09,
kChannel10,
kChannel11,
kChannel12,
kNoChannels,
kOnChipTemp,
kVccInt,
kVccAux,
kVrefP,
kVrefN,
kVBram,
kVccPInt,
kVccPAux,
kVccOddr,
kNoInputs
};
AdcInt(AdcIntCfgManager *_configuration_manager, uint16_t _xadc_device_id,
uint8_t _xadc_interrupt_id);
void initialize();
void update();
bool isReady();
bool getValue(Input input, float &var);
bool isAlarmActive(AdcIntCfgManager::Alarm alarm);
void handle_interrupt();
private:
class AnalogInput
{
public:
AnalogInput();
void initialize(XSysMon *_xadc_driver, uint8_t _addr, bool _enable,
float _norm);
bool isEnabled();
float getValue();
bool isReady();
void notify();
private:
uint8_t addr;
uint16_t value;
float norm;
bool enabled;
bool ready;
AdcIntCfgManager::ChannelType type;
XSysMon *xadc_driver;
};
class Sensor
{
public:
Sensor();
void initialize(XSysMon *_xadc_driver, uint8_t _addr, bool _enable,
AdcIntCfgManager::OnChipSensorType _type);
bool isEnabled();
float getValue();
bool isReady();
void notify();
private:
uint8_t addr;
AdcIntCfgManager::OnChipSensorType type;
uint16_t value;
bool enabled;
bool ready;
XSysMon *xadc_driver;
};
class Alarm
{
public:
Alarm();
void initialize(bool _enable, uint32_t _activate_mask,
uint32_t _deactivate_mask);
bool isEnabled();
bool isActive();
void notify(uint32_t status);
private:
uint32_t activate_mask;
uint32_t deactivate_mask;
bool enabled;
bool active;
};
class ChannelAddressMonitor
{
public:
ChannelAddressMonitor();
void refreshAddress();
uint8_t getChannelAddress();
private:
uint8_t channel_address;
};
static const uint32_t NON_EXISTING_ALARM_ACTIVE_MASK = 0x00000000;
static const uint32_t NON_EXISTING_ALARM_DEACTIVE_MASK = 0x00000000;
static const uint64_t sensor_masks[static_cast<uint8_t>(
AdcIntCfgManager::OnChipSensor::kNoOnChipSensors)];
static const uint16_t calibration_masks[static_cast<uint8_t>(
AdcIntCfgManager::Calibration::kNoCalibrations)];
static const uint32_t
alarm_masks[static_cast<uint8_t>(AdcIntCfgManager::Alarm::kNoAlarms)];
static const uint16_t threshold_masks[static_cast<uint8_t>(
AdcIntCfgManager::AlarmThresholdName::kNoAlarmThresholdNames)];
static const uint8_t sensors_address[static_cast<uint8_t>(
AdcIntCfgManager::OnChipSensor::kNoOnChipSensors)];
static const uint32_t alarm_activate_masks[static_cast<uint8_t>(
AdcIntCfgManager::Alarm::kNoAlarms)];
static const uint32_t alarm_deactivate_masks[static_cast<uint8_t>(
AdcIntCfgManager::Alarm::kNoAlarms)];
static bool isEndOfSequenceInterrupt(uint32_t status);
static bool isAlarmInterrupt(uint32_t status);
static float temperatureRawToC(uint16_t raw_temp);
static uint16_t temperatureCToRaw(float temp);
static float voltageRawToV(uint16_t raw_voltage);
static uint16_t voltageVToRaw(float voltage);
AdcIntCfgManager *configuration_manager;
AnalogInput analog_inputs[static_cast<uint8_t>(
AdcIntCfgManager::Channel::kNoChannels)];
Sensor sensors[static_cast<uint8_t>(
AdcIntCfgManager::OnChipSensor::kNoOnChipSensors)];
Alarm alarms[static_cast<uint8_t>(AdcIntCfgManager::Alarm::kNoAlarms)];
ChannelAddressMonitor channel_address_monitor;
XSysMon xadc_driver;
uint16_t xadc_device_id;
uint8_t xadc_interrupt_id;
void startConversion();
bool isBusy();
bool getChannelValue(AdcIntCfgManager::Channel channel, float &var);
bool getOnChipSensorValue(AdcIntCfgManager::OnChipSensor sensor, float &var);
int configureSequencerChannels(uint64_t channels_mask);
int configureSettlingTime(uint64_t channels_mask);
void configureCalibration();
void configureAlarms();
void configureLowerAlarmThreshold(AdcIntCfgManager::Alarm alarm);
void configureUpperAlarmThreshold(AdcIntCfgManager::Alarm alarm);
void configureOperMode();
void configureInterrupts();
void initializeAnalogInputs();
void initializeSensors();
void initializeAlarms();
void notifySensors();
void notifyAlarms(uint32_t status);
uint64_t getChannelsMask();
uint16_t getCalibrationMask();
uint32_t getAlarmMask();
uint16_t getAlarmThresholdLowerMask(AdcIntCfgManager::Alarm alarm);
uint16_t getAlarmThresholdUpperMask(AdcIntCfgManager::Alarm alarm);
uint32_t getAlarmActivateMask(AdcIntCfgManager::Alarm alarm);
uint32_t getAlarmDeactivateMask(AdcIntCfgManager::Alarm alarm);
uint32_t getAlarmsInterruptEnableMask();
uint8_t getOnChipSensorAddress(AdcIntCfgManager::OnChipSensor sensor);
};
AdcInt.cpp
#include "AdcInt.h"
#include <iostream>
using namespace std;
const uint64_t AdcInt::sensor_masks[static_cast<uint8_t>(
AdcIntCfgManager::OnChipSensor::kNoOnChipSensors)] = {
XSM_SEQ_CH_TEMP, XSM_SEQ_CH_VCCINT, XSM_SEQ_CH_VCCAUX,
XSM_SEQ_CH_VREFP, XSM_SEQ_CH_VREFN, XSM_SEQ_CH_VBRAM,
XSM_SEQ_CH_VCCPINT, XSM_SEQ_CH_VCCPAUX, XSM_SEQ_CH_VCCPDRO};
const uint16_t AdcInt::calibration_masks[static_cast<uint8_t>(
AdcIntCfgManager::Calibration::kNoCalibrations)] = {
XSM_CFR1_CAL_ADC_OFFSET_MASK, XSM_CFR1_CAL_ADC_GAIN_OFFSET_MASK,
XSM_CFR1_CAL_PS_OFFSET_MASK, XSM_CFR1_CAL_PS_GAIN_OFFSET_MASK};
const uint32_t AdcInt::alarm_masks[static_cast<uint8_t>(
AdcIntCfgManager::Alarm::kNoAlarms)] = {
XSM_CFR_OT_MASK, XSM_CFR_ALM_TEMP_MASK, XSM_CFR_ALM_VCCINT_MASK,
XSM_CFR_ALM_VCCAUX_MASK, XSM_CFR_ALM_VBRAM_MASK, XSM_CFR_ALM_VCCPINT_MASK,
XSM_CFR_ALM_VCCPAUX_MASK, XSM_CFR_ALM_VCCPDRO_MASK};
const uint16_t AdcInt::threshold_masks[static_cast<uint8_t>(
AdcIntCfgManager::AlarmThresholdName::kNoAlarmThresholdNames)] = {
XSM_ATR_TEMP_UPPER, XSM_ATR_VCCINT_UPPER, XSM_ATR_VCCAUX_UPPER,
XSM_ATR_OT_UPPER, XSM_ATR_TEMP_LOWER, XSM_ATR_VCCINT_LOWER,
XSM_ATR_VCCAUX_LOWER, XSM_ATR_OT_LOWER, XSM_ATR_VBRAM_UPPER,
XSM_ATR_VCCPINT_UPPER, XSM_ATR_VCCPAUX_UPPER, XSM_ATR_VCCPDRO_UPPER,
XSM_ATR_VBRAM_LOWER, XSM_ATR_VCCPINT_LOWER, XSM_ATR_VCCPAUX_LOWER,
XSM_ATR_VCCPDRO_LOWER};
const uint8_t AdcInt::sensors_address[static_cast<uint8_t>(
AdcIntCfgManager::OnChipSensor::kNoOnChipSensors)] = {
XSM_CH_TEMP, XSM_CH_VCCINT, XSM_CH_VCCAUX, XSM_CH_VREFP, XSM_CH_VREFN,
XSM_CH_VBRAM, XSM_CH_VCCLPINT, XSM_CH_VCCPAUX, XSM_CH_VCCPDRO};
const uint32_t AdcInt::alarm_activate_masks[static_cast<uint8_t>(
AdcIntCfgManager::Alarm::kNoAlarms)] = {XSM_IPIXR_OT_MASK,
XSM_IPIXR_TEMP_MASK,
XSM_IPIXR_VCCINT_MASK,
XSM_IPIXR_VCCAUX_MASK,
XSM_IPIXR_VBRAM_MASK,
NON_EXISTING_ALARM_ACTIVE_MASK,
NON_EXISTING_ALARM_ACTIVE_MASK,
NON_EXISTING_ALARM_ACTIVE_MASK};
const uint32_t AdcInt::alarm_deactivate_masks[static_cast<uint8_t>(
AdcIntCfgManager::Alarm::kNoAlarms)] = {
XSM_IPIXR_OT_DEACTIVE_MASK, XSM_IPIXR_TEMP_DEACTIVE_MASK,
NON_EXISTING_ALARM_DEACTIVE_MASK, NON_EXISTING_ALARM_DEACTIVE_MASK,
NON_EXISTING_ALARM_DEACTIVE_MASK, NON_EXISTING_ALARM_DEACTIVE_MASK,
NON_EXISTING_ALARM_DEACTIVE_MASK, NON_EXISTING_ALARM_DEACTIVE_MASK};
AdcInt::AdcInt(AdcIntCfgManager *_configuration_manager,
uint16_t _xadc_device_id, uint8_t _xadc_interrupt_id)
{
configuration_manager = _configuration_manager;
xadc_device_id = _xadc_device_id;
xadc_interrupt_id = _xadc_interrupt_id;
}
void AdcInt::initialize()
{
XSysMon_Config *xadc_cfg;
int oper_result;
uint64_t channels_mask;
xadc_cfg = XSysMon_LookupConfig(xadc_device_id);
if (xadc_cfg == NULL) {
cout << "xadc device id hasn't been found" << endl;
} else {
oper_result =
XSysMon_CfgInitialize(&xadc_driver, xadc_cfg, xadc_cfg->BaseAddress);
if (oper_result != XST_SUCCESS) {
cout << "xadc driver initialization failed" << endl;
} else {
channels_mask = getChannelsMask();
oper_result = configureSequencerChannels(channels_mask);
if (oper_result != XST_SUCCESS) {
cout << "xadc sequencer channels configuration failed" << endl;
} else {
XSysMon_SetAdcClkDivisor(&xadc_driver,
configuration_manager->getClkDivRatio());
XSysMon_SetAvg(&xadc_driver,
configuration_manager->getNoAveragedSamples());
oper_result = configureSettlingTime(channels_mask);
if (oper_result != XST_SUCCESS) {
cout << "xadc settling time configuration failed" << endl;
} else {
configureCalibration();
configureAlarms();
configureOperMode();
initializeAnalogInputs();
initializeSensors();
initializeAlarms();
configureInterrupts();
}
}
}
}
}
void AdcInt::update()
{
if (isBusy() == false) {
startConversion();
}
}
bool AdcInt::isReady()
{
for (AnalogInput &input : analog_inputs) {
if (input.isReady() == false) {
return false;
}
}
for (Sensor &sensor : sensors) {
if (sensor.isReady() == false) {
return false;
}
}
return true;
}
bool AdcInt::getValue(Input input, float &var)
{
if (static_cast<uint8_t>(input) < static_cast<uint8_t>(Input::kNoChannels)) {
return getChannelValue(static_cast<AdcIntCfgManager::Channel>(input), var);
} else if ((static_cast<uint8_t>(input) >
static_cast<uint8_t>(Input::kNoChannels)) &&
(static_cast<uint8_t>(input) <
static_cast<uint8_t>(Input::kNoInputs))) {
uint8_t sensor_index = static_cast<uint8_t>(input) -
static_cast<uint8_t>(Input::kNoChannels) - 1;
return getOnChipSensorValue(
static_cast<AdcIntCfgManager::OnChipSensor>(sensor_index), var);
} else {
return false;
}
}
bool AdcInt::isAlarmActive(AdcIntCfgManager::Alarm alarm)
{
return alarms[static_cast<uint8_t>(alarm)].isActive();
}
void AdcInt::handle_interrupt()
{
uint32_t status = XSysMon_IntrGetStatus(&xadc_driver);
if (isEndOfSequenceInterrupt(status)) {
analog_inputs[channel_address_monitor.getChannelAddress()].notify();
notifySensors();
channel_address_monitor.refreshAddress();
} else if (isAlarmInterrupt(status)) {
notifyAlarms(status);
}
}
AdcInt::AnalogInput::AnalogInput()
{
value = 0;
ready = true;
enabled = false;
}
void AdcInt::AnalogInput::initialize(XSysMon *_xadc_driver, uint8_t _addr,
bool _enable, float _norm)
{
addr = _addr;
enabled = _enable;
norm = _norm;
xadc_driver = _xadc_driver;
}
bool AdcInt::AnalogInput::isEnabled()
{
return enabled;
}
float AdcInt::AnalogInput::getValue()
{
return (value / 4096.0 * norm);
}
bool AdcInt::AnalogInput::isReady()
{
return ready;
}
void AdcInt::AnalogInput::notify()
{
if (enabled) {
value = XSysMon_GetAdcData(xadc_driver, addr);
}
}
AdcInt::Sensor::Sensor()
{
value = 0;
ready = true;
enabled = false;
}
void AdcInt::Sensor::initialize(XSysMon *_xadc_driver, uint8_t _addr,
bool _enable,
AdcIntCfgManager::OnChipSensorType _type)
{
addr = _addr;
type = _type;
enabled = _enable;
xadc_driver = _xadc_driver;
}
bool AdcInt::Sensor::isEnabled()
{
return enabled;
}
float AdcInt::Sensor::getValue()
{
float ret_val;
if (type == AdcIntCfgManager::OnChipSensorType::kVoltageSensor) {
ret_val = voltageRawToV(value);
} else if (type == AdcIntCfgManager::OnChipSensorType::kTemperatureSensor) {
ret_val = temperatureRawToC(value);
}
return ret_val;
}
bool AdcInt::Sensor::isReady()
{
return ready;
}
void AdcInt::Sensor::notify()
{
if (enabled) {
value = XSysMon_GetAdcData(xadc_driver, addr);
}
}
AdcInt::Alarm::Alarm()
{
active = false;
enabled = false;
}
void AdcInt::Alarm::initialize(bool _enable, uint32_t _activate_mask,
uint32_t _deactivate_mask)
{
activate_mask = _activate_mask;
deactivate_mask = _deactivate_mask;
enabled = _enable;
}
bool AdcInt::Alarm::isEnabled()
{
return enabled;
}
bool AdcInt::Alarm::isActive()
{
return active;
}
void AdcInt::Alarm::notify(uint32_t status)
{
if (enabled) {
if (status & activate_mask) {
active = true;
} else if (status & deactivate_mask) {
active = false;
}
}
}
AdcInt::ChannelAddressMonitor::ChannelAddressMonitor()
{
channel_address = 0;
}
void AdcInt::ChannelAddressMonitor::refreshAddress()
{
if (++channel_address ==
static_cast<uint8_t>(AdcIntCfgManager::Channel::kNoChannels)) {
channel_address = 0;
}
}
uint8_t AdcInt::ChannelAddressMonitor::getChannelAddress()
{
return channel_address;
}
void AdcInt::startConversion()
{
XSysMon_StartAdcConversion(&xadc_driver);
}
bool AdcInt::isBusy()
{
return ((XSysMon_GetStatus(&xadc_driver) & XSM_SR_BUSY_MASK) != 0);
}
bool AdcInt::getChannelValue(AdcIntCfgManager::Channel channel, float &var)
{
bool enabled = false;
uint8_t index = static_cast<uint8_t>(channel);
if (analog_inputs[index].isEnabled()) {
var = analog_inputs[index].getValue();
enabled = true;
}
return enabled;
}
bool AdcInt::getOnChipSensorValue(AdcIntCfgManager::OnChipSensor sensor,
float &var)
{
bool enabled = false;
uint8_t index = static_cast<uint8_t>(sensor);
if (sensors[index].isEnabled()) {
var = sensors[index].getValue();
enabled = true;
}
return enabled;
}
bool AdcInt::isEndOfSequenceInterrupt(uint32_t status)
{
if (status & XSM_IPIXR_EOS_MASK) {
return true;
} else {
return false;
}
}
bool AdcInt::isAlarmInterrupt(uint32_t status)
{
if ((status & XSM_IPIXR_VBRAM_MASK) |
(status & XSM_IPIXR_TEMP_DEACTIVE_MASK) |
(status & XSM_IPIXR_OT_DEACTIVE_MASK) | (status & XSM_IPIXR_VCCAUX_MASK) |
(status & XSM_IPIXR_VCCINT_MASK) | (status & XSM_IPIXR_TEMP_MASK) |
(status & XSM_IPIXR_OT_MASK)) {
return true;
} else {
return false;
}
}
float AdcInt::temperatureRawToC(uint16_t raw_temp)
{
// see ug480 on page 33
return ((raw_temp * 503.975) / 4096.0 - 273.15);
}
uint16_t AdcInt::temperatureCToRaw(float temp)
{
// see ug480 on page 33
return (4096.0 * (temp + 273.15) / 503.975);
}
float AdcInt::voltageRawToV(uint16_t raw_voltage)
{
// see ug480 on page 34
return (raw_voltage * 3.0 / 4096.0);
}
uint16_t AdcInt::voltageVToRaw(float voltage)
{
// see ug480 on page 34
return (voltage * 4096.0 / 3.0);
}
int AdcInt::configureSequencerChannels(uint64_t channels_mask)
{
// disable sequencer before configuration (please see the xsysmon_extmux_example.c from Xilinx)
XSysMon_SetSequencerMode(&xadc_driver, XSM_SEQ_MODE_SAFE);
int oper_result = XSysMon_SetSeqChEnables(&xadc_driver, channels_mask);
return oper_result;
}
int AdcInt::configureSettlingTime(uint64_t channels_mask)
{
int oper_result = XST_SUCCESS;
if (configuration_manager->isIncreasedSettlingTimeEnabled()) {
oper_result = XSysMon_SetSeqAcqTime(&xadc_driver, channels_mask);
}
return oper_result;
}
void AdcInt::configureCalibration()
{
uint16_t calibration_mask = getCalibrationMask();
XSysMon_SetCalibEnables(&xadc_driver, calibration_mask);
}
void AdcInt::configureAlarms()
{
uint32_t alarms_mask = getAlarmMask();
XSysMon_SetAlarmEnables(&xadc_driver, alarms_mask);
for (uint8_t alarm = 0;
alarm < static_cast<uint8_t>(AdcIntCfgManager::Alarm::kNoAlarms);
alarm++) {
if (configuration_manager->isAlarmEnabled(
static_cast<AdcIntCfgManager::Alarm>(alarm))) {
configureLowerAlarmThreshold(static_cast<AdcIntCfgManager::Alarm>(alarm));
configureUpperAlarmThreshold(static_cast<AdcIntCfgManager::Alarm>(alarm));
}
}
}
void AdcInt::configureLowerAlarmThreshold(AdcIntCfgManager::Alarm alarm)
{
float threshold;
uint8_t threshold_mask;
uint16_t raw_threshold;
threshold = configuration_manager->getAlarmThresholdLower(alarm);
threshold_mask = getAlarmThresholdLowerMask(alarm);
if (configuration_manager->getAlarmType(alarm) ==
AdcIntCfgManager::AlarmType::kTemperatureAlarm) {
raw_threshold = temperatureCToRaw(threshold);
} else if (configuration_manager->getAlarmType(alarm) ==
AdcIntCfgManager::AlarmType::kVoltageAlarm) {
raw_threshold = voltageVToRaw(threshold);
}
XSysMon_SetAlarmThreshold(&xadc_driver, threshold_mask, raw_threshold);
}
void AdcInt::configureUpperAlarmThreshold(AdcIntCfgManager::Alarm alarm)
{
float threshold;
uint8_t threshold_mask;
uint16_t raw_threshold;
threshold = configuration_manager->getAlarmThresholdUpper(alarm);
threshold_mask = getAlarmThresholdUpperMask(alarm);
if (configuration_manager->getAlarmType(alarm) ==
AdcIntCfgManager::AlarmType::kTemperatureAlarm) {
raw_threshold = temperatureCToRaw(threshold);
} else if (configuration_manager->getAlarmType(alarm) ==
AdcIntCfgManager::AlarmType::kVoltageAlarm) {
raw_threshold = voltageVToRaw(threshold);
}
XSysMon_SetAlarmThreshold(&xadc_driver, threshold_mask, raw_threshold);
}
void AdcInt::configureOperMode()
{
// external multiplexer connection
XSysMon_SetExtenalMux(&xadc_driver, XSM_CH_VPVN);
// single pass mode of operation
XSysMon_SetSequencerMode(&xadc_driver, XSM_SEQ_MODE_ONEPASS);
}
void AdcInt::configureInterrupts()
{
XSysMon_IntrEnable(&xadc_driver,
XSM_IPIXR_EOS_MASK | getAlarmsInterruptEnableMask());
XSysMon_IntrGlobalEnable(&xadc_driver);
platform::drivers::InterruptController::instance().connect(xadc_interrupt_id,
*this);
}
void AdcInt::initializeAnalogInputs()
{
for (uint8_t input = 0;
input < static_cast<uint8_t>(AdcIntCfgManager::Channel::kNoChannels);
input++) {
analog_inputs[input].initialize(
&xadc_driver, XSM_CH_VPVN,
configuration_manager->isChannelEnabled(
static_cast<AdcIntCfgManager::Channel>(input)),
configuration_manager->getChannelNorm(
static_cast<AdcIntCfgManager::Channel>(input)));
}
}
void AdcInt::initializeSensors()
{
for (uint8_t sensor = 0;
sensor <
static_cast<uint8_t>(AdcIntCfgManager::OnChipSensor::kNoOnChipSensors);
sensor++) {
sensors[sensor].initialize(
&xadc_driver,
getOnChipSensorAddress(
static_cast<AdcIntCfgManager::OnChipSensor>(sensor)),
configuration_manager->isOnChipSensorEnabled(
static_cast<AdcIntCfgManager::OnChipSensor>(sensor)),
configuration_manager->getSensorType(
static_cast<AdcIntCfgManager::OnChipSensor>(sensor)));
}
}
void AdcInt::initializeAlarms()
{
for (uint8_t alarm = 0;
alarm < static_cast<uint8_t>(AdcIntCfgManager::Alarm::kNoAlarms);
alarm++) {
alarms[alarm].initialize(
configuration_manager->isAlarmEnabled(
static_cast<AdcIntCfgManager::Alarm>(alarm)),
getAlarmActivateMask(static_cast<AdcIntCfgManager::Alarm>(alarm)),
getAlarmDeactivateMask(static_cast<AdcIntCfgManager::Alarm>(alarm)));
}
}
void AdcInt::notifySensors()
{
for (Sensor &sensor : sensors) {
sensor.notify();
}
}
void AdcInt::notifyAlarms(uint32_t status)
{
for (Alarm &alarm : alarms) {
alarm.notify(status);
}
}
uint64_t AdcInt::getChannelsMask()
{
uint64_t channels_mask = 0;
if (configuration_manager->isCalibrationEnabled()) {
channels_mask |= XSM_SEQ_CH_CALIB;
}
for (uint8_t sensor = 0;
sensor <
static_cast<uint8_t>(AdcIntCfgManager::OnChipSensor::kNoOnChipSensors);
sensor++) {
if (configuration_manager->isOnChipSensorEnabled(
static_cast<AdcIntCfgManager::OnChipSensor>(sensor))) {
channels_mask |= sensor_masks[sensor];
}
}
// external multiplexer connection
channels_mask |= XSM_SEQ_CH_VPVN;
return channels_mask;
}
uint16_t AdcInt::getCalibrationMask()
{
uint16_t calibration_mask = 0;
for (uint8_t calibration = 0;
calibration <
static_cast<uint8_t>(AdcIntCfgManager::Calibration::kNoCalibrations);
calibration++) {
if (configuration_manager->isCalibrationTypeEnabled(
static_cast<AdcIntCfgManager::Calibration>(calibration))) {
calibration_mask |= calibration_masks[calibration];
}
}
return calibration_mask;
}
uint32_t AdcInt::getAlarmMask()
{
uint32_t alarm_mask = 0;
for (uint8_t alarm = 0;
alarm < static_cast<uint8_t>(AdcIntCfgManager::Alarm::kNoAlarms);
alarm++) {
if (configuration_manager->isAlarmEnabled(
static_cast<AdcIntCfgManager::Alarm>(alarm))) {
alarm_mask |= alarm_masks[alarm];
}
}
return alarm_mask;
}
uint16_t AdcInt::getAlarmThresholdLowerMask(AdcIntCfgManager::Alarm alarm)
{
return (threshold_masks[static_cast<uint8_t>(
configuration_manager->getAlarmLowerThresholdName(alarm))]);
}
uint16_t AdcInt::getAlarmThresholdUpperMask(AdcIntCfgManager::Alarm alarm)
{
return (threshold_masks[static_cast<uint8_t>(
configuration_manager->getAlarmUpperThresholdName(alarm))]);
}
uint32_t AdcInt::getAlarmActivateMask(AdcIntCfgManager::Alarm alarm)
{
return alarm_activate_masks[static_cast<uint8_t>(alarm)];
}
uint32_t AdcInt::getAlarmDeactivateMask(AdcIntCfgManager::Alarm alarm)
{
return alarm_deactivate_masks[static_cast<uint8_t>(alarm)];
}
uint32_t AdcInt::getAlarmsInterruptEnableMask()
{
uint32_t alarms_interrupt_enable_mask = 0;
for (uint8_t alarm = 0;
alarm < static_cast<uint8_t>(AdcIntCfgManager::Alarm::kNoAlarms);
alarm++) {
if (configuration_manager->isAlarmEnabled(
static_cast<AdcIntCfgManager::Alarm>(alarm))) {
alarms_interrupt_enable_mask |= alarm_activate_masks[alarm];
}
}
return alarms_interrupt_enable_mask;
}
uint8_t AdcInt::getOnChipSensorAddress(AdcIntCfgManager::OnChipSensor sensor)
{
return sensors_address[static_cast<uint8_t>(sensor)];
}
AdcIntCfgManager.h
#include <cstdint>
class AdcIntCfgManager
{
public:
enum class Channel {
kChannel00,
kChannel01,
kChannel02,
kChannel03,
kChannel04,
kChannel05,
kChannel06,
kChannel07,
kChannel08,
kChannel09,
kChannel10,
kChannel11,
kChannel12,
kNoChannels
};
enum class OnChipSensor {
kOnChipTemp,
kVccInt,
kVccAux,
kVrefP,
kVrefN,
kVBram,
kVccPInt,
kVccPAux,
kVccOddr,
kNoOnChipSensors
};
enum class ChannelType { kUnipolar, kBipolar };
enum class ChannelEnable { kChannelDisabled, kChannelEnabled };
struct ChannelCfg
{
Channel channel;
ChannelType type;
ChannelEnable enable;
float norm;
};
enum class AdcClockDivRatio {
kADCCLK_DCLK_DIV_002,
kADCCLK_DCLK_DIV_003 = 3,
kADCCLK_DCLK_DIV_004 = 4,
kADCCLK_DCLK_DIV_255 = 255
};
enum class OnChipSensorType { kVoltageSensor, kTemperatureSensor };
enum class OnChipSensorEnable { kSensorDisabled, kSensorEnabled };
struct OnChipSensorsCfg
{
OnChipSensor sensor;
OnChipSensorType type;
OnChipSensorEnable enable;
};
enum class Averaging {
kAveragingFrom_0_Samples,
kAveragingFrom_16_Samples,
kAveragingFrom_64_Samples,
kAveragingFrom_256_Samples
};
enum class Calibration {
kAdcOffsetCorrection,
kAdcOffsetGainCorrection,
kSupplySensorOffsetCorrection,
kSupplySensorOffsetGainCorrection,
kNoCalibrations
};
enum class CalibrationEnable { kCalibrationDisabled, kCalibrationEnabled };
struct CalibrationCfg
{
Calibration calibration;
CalibrationEnable enable;
};
enum class SettlingTime { kSettlingTime_4_ADCCLK, kSettlingTime_10_ADCCLK };
enum class Alarm {
kOverTemperature,
kOnChipTemperature,
kVccInt,
kVccAux,
kVBram,
kVccPInt,
kVccPAux,
kVccOddr,
kNoAlarms
};
enum class AlarmType { kTemperatureAlarm, kVoltageAlarm };
enum class AlarmEnable { kAlarmDisabled, kAlarmEnabled };
enum class AlarmThresholdName {
kOnChipTemperatureUpper,
kVccIntUpper,
kVccAuxUpper,
kOverTemperatureSet,
kOnChipTemperatureLower,
kVccIntLower,
kVccAuxLower,
kOverTemperatureReset,
kVBramUpper,
kVccPIntUpper,
kVccPAuxUpper,
kVccOddrUpper,
kVBramLower,
kVccPIntLower,
kVccPAuxLower,
kVccOddrLower,
kNoAlarmThresholdNames
};
struct AlarmThreshold
{
AlarmThresholdName name;
float value;
};
struct AlarmsCfg
{
Alarm alarm;
AlarmType type;
AlarmEnable enable;
AlarmThreshold lower_threshold;
AlarmThreshold upper_threshold;
};
struct AdcIntCfg
{
ChannelCfg channels_cfg[static_cast<uint8_t>(
Channel::
kNoChannels)];
OnChipSensorsCfg sensors_cfg[static_cast<uint8_t>(
OnChipSensor::kNoOnChipSensors)];
AdcClockDivRatio
clock_div_ratio;
SettlingTime settling_time;
Averaging averaging;
CalibrationCfg calibration_cfg[static_cast<uint8_t>(
Calibration::kNoCalibrations)];
AlarmsCfg alarms_cfg[static_cast<uint8_t>(
Alarm::
kNoAlarms)];
};
AdcIntCfgManager(const AdcIntCfg *_configuration);
uint8_t getClkDivRatio();
bool isIncreasedSettlingTimeEnabled();
uint8_t getNoAveragedSamples();
bool isCalibrationEnabled();
bool isCalibrationTypeEnabled(Calibration type);
bool isAlarmEnabled(Alarm alarm);
float getAlarmThresholdLower(Alarm alarm);
float getAlarmThresholdUpper(Alarm alarm);
AlarmType getAlarmType(Alarm alarm);
AlarmThresholdName getAlarmLowerThresholdName(Alarm alarm);
AlarmThresholdName getAlarmUpperThresholdName(Alarm alarm);
bool isChannelEnabled(Channel channel);
ChannelType getChannelType(Channel channel);
float getChannelNorm(Channel channel);
bool isOnChipSensorEnabled(OnChipSensor sensor);
OnChipSensorType getSensorType(OnChipSensor sensor);
private:
const AdcIntCfg *configuration;
};
AdcIntCfgManager.cpp
#include "AdcIntCfgManager.h"
AdcIntCfgManager::AdcIntCfgManager(const AdcIntCfg *_configuration)
{
configuration = _configuration;
}
uint8_t AdcIntCfgManager::getClkDivRatio()
{
return static_cast<uint8_t>(configuration->clock_div_ratio);
}
bool AdcIntCfgManager::isIncreasedSettlingTimeEnabled()
{
return (configuration->settling_time ==
SettlingTime::kSettlingTime_10_ADCCLK);
}
uint8_t AdcIntCfgManager::getNoAveragedSamples()
{
return static_cast<uint8_t>(configuration->averaging);
}
bool AdcIntCfgManager::isCalibrationEnabled()
{
bool ret_val = false;
for (uint8_t i = 0; i < static_cast<uint8_t>(Calibration::kNoCalibrations);
i++) {
if (configuration->calibration_cfg[i].enable ==
CalibrationEnable::kCalibrationEnabled) {
ret_val = true;
break;
}
}
return ret_val;
}
bool AdcIntCfgManager::isCalibrationTypeEnabled(Calibration type)
{
if (configuration->calibration_cfg[static_cast<uint8_t>(type)].enable ==
CalibrationEnable::kCalibrationEnabled) {
return true;
} else {
return false;
}
}
bool AdcIntCfgManager::isAlarmEnabled(Alarm alarm)
{
return (configuration->alarms_cfg[static_cast<uint8_t>(alarm)].enable ==
AlarmEnable::kAlarmEnabled);
}
float AdcIntCfgManager::getAlarmThresholdLower(Alarm alarm)
{
return (configuration->alarms_cfg[static_cast<uint8_t>(alarm)]
.lower_threshold.value);
}
float AdcIntCfgManager::getAlarmThresholdUpper(Alarm alarm)
{
return (configuration->alarms_cfg[static_cast<uint8_t>(alarm)]
.upper_threshold.value);
}
AdcIntCfgManager::AlarmType AdcIntCfgManager::getAlarmType(Alarm alarm)
{
return (configuration->alarms_cfg[static_cast<uint8_t>(alarm)].type);
}
AdcIntCfgManager::AlarmThresholdName
AdcIntCfgManager::getAlarmLowerThresholdName(Alarm alarm)
{
return (configuration->alarms_cfg[static_cast<uint8_t>(alarm)]
.lower_threshold.name);
}
AdcIntCfgManager::AlarmThresholdName
AdcIntCfgManager::getAlarmUpperThresholdName(Alarm alarm)
{
return (configuration->alarms_cfg[static_cast<uint8_t>(alarm)]
.upper_threshold.name);
}
bool AdcIntCfgManager::isChannelEnabled(Channel channel)
{
if (configuration->channels_cfg[static_cast<uint8_t>(channel)].enable ==
ChannelEnable::kChannelEnabled) {
return true;
} else {
return false;
}
}
float AdcIntCfgManager::getChannelNorm(Channel channel)
{
return (configuration->channels_cfg[static_cast<uint8_t>(channel)].norm);
}
AdcIntCfgManager::ChannelType AdcIntCfgManager::getChannelType(Channel channel)
{
return (configuration->channels_cfg[static_cast<uint8_t>(channel)].type);
}
bool AdcIntCfgManager::isOnChipSensorEnabled(OnChipSensor sensor)
{
if (configuration->sensors_cfg[static_cast<uint8_t>(sensor)].enable ==
OnChipSensorEnable::kSensorEnabled) {
return true;
} else {
return false;
}
}
AdcIntCfgManager::OnChipSensorType
AdcIntCfgManager::getSensorType(OnChipSensor sensor)
{
return (configuration->sensors_cfg[static_cast<uint8_t>(sensor)].type);
}
Предполагаемое использование драйвера следующее:
- вся информация о конфигурации находится в
FpgaPeripheralsCfg
класс - экземпляр AdcInt находится вместе с экземплярами других драйверов в «контейнере»
FpgaDrivers
FpgaPeripheralsCfg.h
#include "AdcIntCfgManager.h"
class FpgaPeripheralsCfg
{
public:
AdcIntCfgManager adc_int_cfg_manager;
FpgaPeripheralsCfg() :
adc_int_cfg_manager(&adc_int_cfg)
{
}
private:
AdcIntCfgManager::AdcIntCfg adc_int_cfg = {
{{AdcIntCfgManager::Channel::kChannel00,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel01,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel02,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel03,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel04,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel05,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel06,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel07,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel08,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel09,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel10,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel11,
AdcIntCfgManager::ChannelType::kBipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 100.0},
{AdcIntCfgManager::Channel::kChannel12,
AdcIntCfgManager::ChannelType::kUnipolar,
AdcIntCfgManager::ChannelEnable::kChannelEnabled, 3.0}},
{{AdcIntCfgManager::OnChipSensor::kOnChipTemp,
AdcIntCfgManager::OnChipSensorType::kTemperatureSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled},
{AdcIntCfgManager::OnChipSensor::kVccInt,
AdcIntCfgManager::OnChipSensorType::kVoltageSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled},
{AdcIntCfgManager::OnChipSensor::kVccAux,
AdcIntCfgManager::OnChipSensorType::kVoltageSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled},
{AdcIntCfgManager::OnChipSensor::kVrefP,
AdcIntCfgManager::OnChipSensorType::kVoltageSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled},
{AdcIntCfgManager::OnChipSensor::kVrefN,
AdcIntCfgManager::OnChipSensorType::kVoltageSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled},
{AdcIntCfgManager::OnChipSensor::kVBram,
AdcIntCfgManager::OnChipSensorType::kVoltageSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled},
{AdcIntCfgManager::OnChipSensor::kVccPInt,
AdcIntCfgManager::OnChipSensorType::kVoltageSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled},
{AdcIntCfgManager::OnChipSensor::kVccPAux,
AdcIntCfgManager::OnChipSensorType::kVoltageSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled},
{AdcIntCfgManager::OnChipSensor::kVccOddr,
AdcIntCfgManager::OnChipSensorType::kVoltageSensor,
AdcIntCfgManager::OnChipSensorEnable::kSensorEnabled}},
.clock_div_ratio =
AdcIntCfgManager::AdcClockDivRatio::kADCCLK_DCLK_DIV_002,
.settling_time = AdcIntCfgManager::SettlingTime::kSettlingTime_4_ADCCLK,
.averaging = AdcIntCfgManager::Averaging::kAveragingFrom_16_Samples,
{{AdcIntCfgManager::Calibration::kAdcOffsetCorrection,
AdcIntCfgManager::CalibrationEnable::kCalibrationEnabled},
{AdcIntCfgManager::Calibration::kAdcOffsetGainCorrection,
AdcIntCfgManager::CalibrationEnable::kCalibrationEnabled},
{AdcIntCfgManager::Calibration::kSupplySensorOffsetCorrection,
AdcIntCfgManager::CalibrationEnable::kCalibrationEnabled},
{AdcIntCfgManager::Calibration::kSupplySensorOffsetGainCorrection,
AdcIntCfgManager::CalibrationEnable::kCalibrationEnabled}},
{{AdcIntCfgManager::Alarm::kOverTemperature,
AdcIntCfgManager::AlarmType::kTemperatureAlarm,
AdcIntCfgManager::AlarmEnable::kAlarmEnabled,
{AdcIntCfgManager::AlarmThresholdName::kOverTemperatureReset, 90.0},
{AdcIntCfgManager::AlarmThresholdName::kOverTemperatureSet, 125.0}},
{AdcIntCfgManager::Alarm::kOnChipTemperature,
AdcIntCfgManager::AlarmType::kTemperatureAlarm,
AdcIntCfgManager::AlarmEnable::kAlarmEnabled,
{AdcIntCfgManager::AlarmThresholdName::kOnChipTemperatureLower, 100.0},
{AdcIntCfgManager::AlarmThresholdName::kOnChipTemperatureUpper, 125.0}},
{AdcIntCfgManager::Alarm::kVccInt,
AdcIntCfgManager::AlarmType::kVoltageAlarm,
AdcIntCfgManager::AlarmEnable::kAlarmEnabled,
{AdcIntCfgManager::AlarmThresholdName::kVccIntLower, 2.7},
{AdcIntCfgManager::AlarmThresholdName::kVccIntUpper, 2.9}},
{AdcIntCfgManager::Alarm::kVccAux,
AdcIntCfgManager::AlarmType::kVoltageAlarm,
AdcIntCfgManager::AlarmEnable::kAlarmEnabled,
{AdcIntCfgManager::AlarmThresholdName::kVccAuxLower, 2.7},
{AdcIntCfgManager::AlarmThresholdName::kVccAuxUpper, 2.9}},
{AdcIntCfgManager::Alarm::kVBram,
AdcIntCfgManager::AlarmType::kVoltageAlarm,
AdcIntCfgManager::AlarmEnable::kAlarmEnabled,
{AdcIntCfgManager::AlarmThresholdName::kVBramLower, 2.7},
{AdcIntCfgManager::AlarmThresholdName::kVBramUpper, 2.9}},
{AdcIntCfgManager::Alarm::kVccPInt,
AdcIntCfgManager::AlarmType::kVoltageAlarm,
AdcIntCfgManager::AlarmEnable::kAlarmEnabled,
{AdcIntCfgManager::AlarmThresholdName::kVccPIntLower, 2.7},
{AdcIntCfgManager::AlarmThresholdName::kVccPIntUpper, 2.9}},
{AdcIntCfgManager::Alarm::kVccPAux,
AdcIntCfgManager::AlarmType::kVoltageAlarm,
AdcIntCfgManager::AlarmEnable::kAlarmEnabled,
{AdcIntCfgManager::AlarmThresholdName::kVccPAuxLower, 2.7},
{AdcIntCfgManager::AlarmThresholdName::kVccPAuxUpper, 2.9}},
{AdcIntCfgManager::Alarm::kVccOddr,
AdcIntCfgManager::AlarmType::kVoltageAlarm,
AdcIntCfgManager::AlarmEnable::kAlarmEnabled,
{AdcIntCfgManager::AlarmThresholdName::kVccOddrLower, 2.7},
{AdcIntCfgManager::AlarmThresholdName::kVccOddrUpper, 2.9}}}};
};
FpgaDrivers.h
#include "AdcInt.h"
class FpgaDrivers
{
public:
AdcInt adc_int;
FpgaDrivers(FpgaPeripheralsCfg &cfg);
void initialize(void);
private:
};
FpgaDrivers.cpp
#include "FpgaDrivers.h"
FpgaDrivers::FpgaDrivers(FpgaPeripheralsCfg &cfg) :
adc_int(&(cfg.adc_int_cfg_manager), 0, 62)
{
}
void FpgaDrivers::initialize(void)
{
adc_int.initialize();
}
главный
int main(int argc, char** argv) {
float adc_value;
FpgaPeripheralsCfg fpga_peripherals_cfg;
FpgaDrivers drivers(fpga_peripherals_cfg);
drivers.initialize();
drivers.adc_int.update();
if(drivers.adc_int.isReady()) {
drivers.adc_int.getValue(platform::drivers::fpga::AdcInt::Input::kChannel00, adc_value);
}
return 0;
}
Я хотел бы попросить вас в основном оценить дизайн драйвера в целом, т.е. как драйвер разделен на классы C ++ и как эти классы взаимодействуют.
1 ответ
const
Вам нужно больше в нескольких местах. Подобные методы:
bool isReady();
bool getValue(Input input, float &var);
bool isAlarmActive(AdcIntCfgManager::Alarm alarm);
bool isEnabled();
float getValue();
bool isReady();
все должны получить const
суффикс формы
bool isReady() const;
как обещание, что метод не изменяет this
. Если что-либо из вышеперечисленного делать модифицировать this
, то это означает, что метод необходимо переработать или хотя бы переименовать.
Членам нравится это:
AdcIntCfgManager::ChannelType type;
XSysMon *xadc_driver;
вероятно должно быть
const AdcIntCfgManager::ChannelType type;
XSysMon *const xadc_driver;
чтобы указать гарантию того, что они не изменятся в течение срока службы экземпляра, даже если это сделают другие члены.
Логическая избыточность
if (isBusy() == false) {
должно быть
if (!isBusy()) {
и
if (status & XSM_IPIXR_EOS_MASK) {
return true;
} else {
return false;
}
должно быть
return status & XSM_IPIXR_EOS_MASK != 0;
его родитель
return (value / 4096.0 * norm);
не требует внешних скобок.
Комбинированное сравнение масок
if ((status & XSM_IPIXR_VBRAM_MASK) |
(status & XSM_IPIXR_TEMP_DEACTIVE_MASK) |
(status & XSM_IPIXR_OT_DEACTIVE_MASK) | (status & XSM_IPIXR_VCCAUX_MASK) |
(status & XSM_IPIXR_VCCINT_MASK) | (status & XSM_IPIXR_TEMP_MASK) |
(status & XSM_IPIXR_OT_MASK)) {
можно упростить, сохранив константу комбинированной маски в другом месте:
const int INTERRUPT_MASK =
XSM_IPIXR_VBRAM_MASK
| XSM_IPIXR_TEMP_DEACTIVE_MASK
| XSM_IPIXR_OT_DEACTIVE_MASK
| XSM_IPIXR_VCCAUX_MASK
| XSM_IPIXR_VCCINT_MASK
| XSM_IPIXR_TEMP_MASK
| XSM_IPIXR_OT_MASK;
// ...
return status & INTERRUPT_MASK != 0;
Раннее возвращение
Скорее, чем
int oper_result = XST_SUCCESS;
if (configuration_manager->isIncreasedSettlingTimeEnabled()) {
oper_result = XSysMon_SetSeqAcqTime(&xadc_driver, channels_mask);
}
return oper_result;
Я обычно предпочитаю стиль
if (configuration_manager->isIncreasedSettlingTimeEnabled()) {
return XSysMon_SetSeqAcqTime(&xadc_driver, channels_mask);
}
return XST_SUCCESS;
Так же,
bool AdcIntCfgManager::isCalibrationEnabled()
{
for (uint8_t i = 0; i < static_cast<uint8_t>(Calibration::kNoCalibrations);
i++) {
if (configuration->calibration_cfg[i].enable ==
CalibrationEnable::kCalibrationEnabled) {
return true;
}
}
return false;
}
Недействительные аргументы
В то время как (void)
— предпочтительный способ указания функций без аргументов в C, в C ++ это избыточно и может быть просто ()
в строках вроде
void initialize(void);
Отступ
Подумайте о переходе к более распространенному отступу с четырьмя пробелами вместо двух.
Инициализация
Имея initialize()
Метод, отделенный от вашего конструктора, является чем-то вроде анти-шаблона в C ++. Подразумевается, что между временем создания вашего класса и до его инициализации он будет в недопустимом состоянии. Попытайтесь устранить это, выполнив работу initialize()
в самом конструкторе. Поскольку ни одна из ваших процедур инициализации, похоже, не способна обнаружить сбой, это легко отображается в конструкторе. Если вам нужно было указать сбой, либо используйте исключения, которые гарантировали бы отсутствие недопустимого экземпляра, либо, что менее идеально, установите флаг сбоя.
Большое спасибо за ваши комментарии. Они мне очень помогают, но можно сказать, что они более или менее косметические. Мне больше интересно ваше мнение по поводу архитектуры драйвера. Могу я узнать ваше мнение по этому поводу?
— L3sek
Правильное использование
const
не является косметическим и будет иметь прямое влияние на то, насколько вы можете быть уверены в правильности программы. В противном случае, еще одна вещь в моем недавнем редактировании.— Райндериен