Merge branch 'meier_eiveobsw' into meier/acuHkTable

This commit is contained in:
Jakob Meier 2021-02-14 11:40:49 +01:00
commit 29fb3cb9b8
23 changed files with 396 additions and 125 deletions

View File

@ -43,6 +43,7 @@ set(LIB_CSP_NAME libcsp)
set(FSFW_PATH fsfw) set(FSFW_PATH fsfw)
set(MISSION_PATH mission) set(MISSION_PATH mission)
set(CSPLIB_PATH libcsp) set(CSPLIB_PATH libcsp)
set(TEST_PATH test/testtasks)
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF) set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
@ -84,6 +85,7 @@ endif()
add_subdirectory(${BSP_PATH}) add_subdirectory(${BSP_PATH})
add_subdirectory(${FSFW_PATH}) add_subdirectory(${FSFW_PATH})
add_subdirectory(${MISSION_PATH}) add_subdirectory(${MISSION_PATH})
add_subdirectory(${TEST_PATH})
################################################################################ ################################################################################
# Post-Sources preparation # Post-Sources preparation
@ -162,16 +164,18 @@ else()
set(TARGET_STRING "Target BSP: Hosted") set(TARGET_STRING "Target BSP: Hosted")
endif() endif()
string(CONCAT POST_BUILD_COMMENT
"Build directory: ${CMAKE_BINARY_DIR}\n"
"Target OSAL: ${OS_FSFW}\n"
"Target Build Type: ${CMAKE_BUILD_TYPE}\n"
"${TARGET_STRING}"
)
add_custom_command( add_custom_command(
TARGET ${TARGET_NAME} TARGET ${TARGET_NAME}
POST_BUILD POST_BUILD
#COMMAND echo "Build directory: ${CMAKE_BINARY_DIR}"
#COMMAND echo "Target OSAL: ${OS_FSFW}"
#COMMAND echo "Target Build Type: ${CMAKE_BUILD_TYPE}"
#COMMAND echo "${TARGET_STRING}"
COMMAND ${CMAKE_SIZE} ${TARGET_NAME}${FILE_SUFFIX} COMMAND ${CMAKE_SIZE} ${TARGET_NAME}${FILE_SUFFIX}
COMMENT "Build directory: ${CMAKE_BINARY_DIR}\nTarget OSAL: ${OS_FSFW}\n" COMMENT ${POST_BUILD_COMMENT}
"Target Build Type: ${CMAKE_BUILD_TYPE}\n${TARGET_STRING}"
) )
include (${CMAKE_SCRIPT_PATH}/BuildType.cmake) include (${CMAKE_SCRIPT_PATH}/BuildType.cmake)

View File

@ -500,3 +500,30 @@ GET out_en[0] = 1
* Local File Path: Path to eiveobsw-linux.elf (in _bin\linux\devel) * Local File Path: Path to eiveobsw-linux.elf (in _bin\linux\devel)
* Remote File Path: /tmp/eive_obsw.elf * Remote File Path: /tmp/eive_obsw.elf
## Libgpiod
Detect all gpio device files:
````
gpiodetect
````
Get info about a specific gpio group:
````
gpioinfo <name of gpio group>
````
The following sets the gpio 18 from gpio group gpiochip7 to high level.
````
gpioset gpiochip7 18=1
````
Setting the gpio to low.
````
gpioset gpiochip7 18=0
````
Show options for setting gpios.
````
gpioset -h
````
To get the state of a gpio:
````
gpioget <gpiogroup> <offset>
````
Example to get state:
gpioget gpiochip7 14

View File

@ -137,6 +137,7 @@ void InitMission::initTasks(){
<< std::endl; << std::endl;
} }
#if TE0720 == 0
FixedTimeslotTaskIF* GomSpacePstTask = TaskFactory::instance()-> FixedTimeslotTaskIF* GomSpacePstTask = TaskFactory::instance()->
createFixedTimeslotTask("GS_PST_TASK", 50, createFixedTimeslotTask("GS_PST_TASK", 50,
PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, nullptr); PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, nullptr);
@ -145,18 +146,16 @@ void InitMission::initTasks(){
sif::error << "InitMission::initTasks: GomSpace PST initialization " sif::error << "InitMission::initTasks: GomSpace PST initialization "
<< "failed!" << std::endl; << "failed!" << std::endl;
} }
#endif
#if TE0720 == 1 && TEST_LIBGPIOD == 1
#if OBSW_ADD_TEST_CODE == 1 PeriodicTaskIF* TestTask = TaskFactory::instance()->
// FixedTimeslotTaskIF* TestTimeslotTask = TaskFactory::instance()-> createPeriodicTask("Libgpiod Test Task", 60,
// createFixedTimeslotTask("PST_TEST_TASK", 10, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, nullptr);
// PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); result = TestTask->addComponent(objects::LIBGPIOD_TEST);
// result = pst::pollingSequenceTestFunction(TestTimeslotTask); if(result != HasReturnvaluesIF::RETURN_OK){
// if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Object add component libgpiod test task object" << std::endl;
// sif::error << "InitMission::createTasks: Test PST initialization " }
// << "failed!" << std::endl;
// }
#endif #endif
//Main thread sleep //Main thread sleep
@ -165,7 +164,9 @@ void InitMission::initTasks(){
UdpBridgeTask->startTask(); UdpBridgeTask->startTask();
UdpPollingTask->startTask(); UdpPollingTask->startTask();
#if TE0720 == 0
GomSpacePstTask->startTask(); GomSpacePstTask->startTask();
#endif
PollingSequenceTableTaskDefault->startTask(); PollingSequenceTableTaskDefault->startTask();
PusVerification->startTask(); PusVerification->startTask();
@ -174,8 +175,8 @@ void InitMission::initTasks(){
PusMedPrio->startTask(); PusMedPrio->startTask();
PusLowPrio->startTask(); PusLowPrio->startTask();
#if OBSW_ADD_TEST_CODE == 1 #if TE0720 == 1 && TEST_LIBGPIOD == 1
// TestTimeslotTask->startTask(); TestTask->startTask();
#endif #endif
sif::info << "Tasks started.." << std::endl; sif::info << "Tasks started.." << std::endl;
} }

View File

@ -33,6 +33,10 @@
#include <bsp_q7s/gpio/LinuxLibgpioIF.h> #include <bsp_q7s/gpio/LinuxLibgpioIF.h>
#include <bsp_q7s/gpio/cookies/GpioCookie.h> #include <bsp_q7s/gpio/cookies/GpioCookie.h>
# if TEST_LIBGPIOD == 1
#include "LibgpiodTest.h"
#endif
void Factory::setStaticFrameworkObjectIds() { void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
PusServiceBase::packetDestination = objects::TM_FUNNEL; PusServiceBase::packetDestination = objects::TM_FUNNEL;
@ -56,15 +60,6 @@ void ObjectFactory::produce(){
Factory::setStaticFrameworkObjectIds(); Factory::setStaticFrameworkObjectIds();
ObjectFactory::produceGenericObjects(); ObjectFactory::produceGenericObjects();
/* Cookies */
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH,
addresses::P60DOCK);
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH,
addresses::PDU1);
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH,
addresses::PDU2);
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH,
addresses::ACU);
#if TE0720 == 1 #if TE0720 == 1
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1, I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0")); TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
@ -80,12 +75,31 @@ void ObjectFactory::produce(){
new CspComIF(objects::CSP_COM_IF); new CspComIF(objects::CSP_COM_IF);
new I2cComIF(objects::I2C_COM_IF); new I2cComIF(objects::I2C_COM_IF);
#if TE0720 == 0
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH,
addresses::P60DOCK);
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH,
addresses::PDU1);
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH,
addresses::PDU2);
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH,
addresses::ACU);
/* Device Handler */ /* Device Handler */
new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie); P60DockHandler* p60dockhandler = new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie);
new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie); PDU1Handler* pdu1handler = new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie);
new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie); PDU2Handler* pdu2handler = new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie);
new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie); ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie);
new PCDUHandler(objects::PCDU_HANDLER, 50); new PCDUHandler(objects::PCDU_HANDLER, 50);
/**
* Setting PCDU devices to mode normal immediately after start up because PCDU is always
* running.
*/
p60dockhandler->setModeNormal();
pdu1handler->setModeNormal();
pdu2handler->setModeNormal();
acuhandler->setModeNormal();
#endif
/* Temperature sensors */ /* Temperature sensors */
Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler( Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler(
objects::TMP1075_HANDLER_1, objects::I2C_COM_IF, objects::TMP1075_HANDLER_1, objects::I2C_COM_IF,
@ -96,24 +110,65 @@ void ObjectFactory::produce(){
i2cCookieTmp1075tcs2); i2cCookieTmp1075tcs2);
tmp1075Handler_2->setStartUpImmediately(); tmp1075Handler_2->setStartUpImmediately();
/* Thermal objects */
GpioCookie* gpioCookie = new GpioCookie; GpioCookie* gpioCookie = new GpioCookie;
#if TE0720 == 1
// Configuration for MIO0 on TE0720-03-1CFA
GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0,
std::string("Heater0"), Gpio::OUT);
gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater);
#else
GpioConfig_t gpioConfigHeater0(std::string("gpiochip5"), 6,
std::string("Heater0"), Gpio::OUT);
gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0);
#endif
new LinuxLibgpioIF(objects::GPIO_IF); new LinuxLibgpioIF(objects::GPIO_IF);
#if TE0720 == 0
/* Pin H2-11 on stack connector */
GpioConfig_t gpioConfigHeater0(std::string("gpiochip7"), 18,
std::string("Heater0"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0);
/* Pin H2-12 on stack connector */
GpioConfig_t gpioConfigHeater1(std::string("gpiochip7"), 14,
std::string("Heater1"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_1, gpioConfigHeater1);
/* Pin H2-13 on stack connector */
GpioConfig_t gpioConfigHeater2(std::string("gpiochip7"), 20,
std::string("Heater2"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_2, gpioConfigHeater2);
GpioConfig_t gpioConfigHeater3(std::string("gpiochip7"), 16,
std::string("Heater3"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_3, gpioConfigHeater3);
GpioConfig_t gpioConfigHeater4(std::string("gpiochip7"), 24,
std::string("Heater4"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_4, gpioConfigHeater4);
GpioConfig_t gpioConfigHeater5(std::string("gpiochip7"), 26,
std::string("Heater5"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_5, gpioConfigHeater5);
GpioConfig_t gpioConfigHeater6(std::string("gpiochip7"), 22,
std::string("Heater6"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_6, gpioConfigHeater6);
GpioConfig_t gpioConfigHeater7(std::string("gpiochip7"), 28,
std::string("Heater7"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_7, gpioConfigHeater7);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER, new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER,
pcduSwitches::TCS_BOARD_8V_HEATER_IN); pcduSwitches::TCS_BOARD_8V_HEATER_IN);
#endif
new TmTcUnixUdpBridge(objects::UDP_BRIDGE, new TmTcUnixUdpBridge(objects::UDP_BRIDGE,
objects::CCSDS_PACKET_DISTRIBUTOR, objects::CCSDS_PACKET_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE); objects::TM_STORE, objects::TC_STORE);
new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
#if TE0720 == 1 && TEST_LIBGPIOD == 1
/* Configure MIO0 as input */
GpioConfig_t gpioConfigMio0(std::string("gpiochip0"), 0,
std::string("MIO0"), Gpio::IN, 0);
gpioCookie->addGpio(gpioIds::Test_ID, gpioConfigMio0);
new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie);
#elif TE0720 == 1
// Configuration for MIO0 on TE0720-03-1CFA
GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0,
std::string("Heater0"), Gpio::OUT, 0);
gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER,
pcduSwitches::TCS_BOARD_8V_HEATER_IN);
#endif
} }

View File

@ -187,7 +187,6 @@ ReturnValue_t CspComIF::cspTransfer(uint8_t cspAddress, uint8_t cspPort,
reply = csp_read(conn, timeout_ms); reply = csp_read(conn, timeout_ms);
if (reply == NULL) { if (reply == NULL) {
sif::error << "CspComIF::cspTransfer: Failed to read csp packet" << std::endl; sif::error << "CspComIF::cspTransfer: Failed to read csp packet" << std::endl;
csp_buffer_free(reply);
csp_close(conn); csp_close(conn);
return RETURN_FAILED; return RETURN_FAILED;
} }

View File

@ -3,4 +3,9 @@ target_sources(${TARGET_NAME} PUBLIC
LinuxLibgpioIF.cpp LinuxLibgpioIF.cpp
) )
target_include_directories(${TARGET_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/cookies
)

View File

@ -38,6 +38,15 @@ public:
* @param gpioId A unique number which specifies the GPIO to drive. * @param gpioId A unique number which specifies the GPIO to drive.
*/ */
virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0; virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0;
/**
* @brief This function requires a child to implement the functionaliy to read the state of
* an ouput or input gpio.
*
* @param gpioId A unique number which specifies the GPIO to read.
* @param gpioState State of GPIO will be written to this pointer.
*/
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
}; };
#endif /* BSP_Q7S_GPIO_GPIOIF_H_ */ #endif /* BSP_Q7S_GPIO_GPIOIF_H_ */

View File

@ -14,7 +14,6 @@ LinuxLibgpioIF::~LinuxLibgpioIF() {
ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){
ReturnValue_t result; ReturnValue_t result;
GpioMap mapToAdd; GpioMap mapToAdd;
GpioMapIter mapToAddIter;
if(cookie == nullptr) { if(cookie == nullptr) {
sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl; sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl;
@ -30,14 +29,87 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){
mapToAdd = gpioCookie->getGpioMap(); mapToAdd = gpioCookie->getGpioMap();
result = checkForConflicts(mapToAdd); result = checkForConflicts(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){ if (result != RETURN_OK){
return result; return result;
} }
result = configureGpios(&mapToAdd);
if (result != RETURN_OK) {
return RETURN_FAILED;
}
/* Register new GPIOs in gpioMap*/ /* Register new GPIOs in gpioMap*/
gpioMap.insert(mapToAdd.begin(), mapToAdd.end()); gpioMap.insert(mapToAdd.begin(), mapToAdd.end());
return HasReturnvaluesIF::RETURN_OK; return RETURN_OK;
}
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) {
GpioMapIter mapToAddIter;
std::string chipname;
unsigned int lineNum;
struct gpiod_chip *chip;
Gpio::Direction direction;
std::string consumer;
struct gpiod_line *lineHandle;
int result;
mapToAddIter = mapToAdd->begin();
for (; mapToAddIter != mapToAdd->end(); mapToAddIter++) {
chipname = mapToAddIter->second.chipname;
chip = gpiod_chip_open_by_name(chipname.c_str());
if (!chip) {
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip "
<< chipname << ". Gpio ID: " << mapToAddIter->first << std::endl;
return RETURN_FAILED;
}
lineNum = mapToAddIter->second.lineNum;
lineHandle = gpiod_chip_get_line(chip, lineNum);
if (!lineHandle) {
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line" << std::endl;
gpiod_chip_close(chip);
return RETURN_FAILED;
}
direction = mapToAddIter->second.direction;
consumer = mapToAddIter->second.consumer;
/* Configure direction and add a description to the GPIO */
switch (direction) {
case Gpio::OUT:
result = gpiod_line_request_output(lineHandle, consumer.c_str(),
mapToAddIter->second.initValue);
if (result < 0) {
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line "
<< lineNum << " from GPIO instance with ID: " << mapToAddIter->first
<< std::endl;
gpiod_line_release(lineHandle);
return RETURN_FAILED;
}
break;
case Gpio::IN:
result = gpiod_line_request_input(lineHandle, consumer.c_str());
if (result < 0) {
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line "
<< lineNum << " from GPIO instance with ID: " << mapToAddIter->first
<< std::endl;
gpiod_line_release(lineHandle);
return RETURN_FAILED;
}
break;
default:
sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified"
<< std::endl;
return RETURN_FAILED;
}
/**
* Write line handle to GPIO configuration instance so it can later be used to set or
* read states of GPIOs.
*/
mapToAddIter->second.lineHandle = lineHandle;
}
return RETURN_OK;
} }
ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId){ ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId){
@ -50,60 +122,39 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId){
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId,
unsigned int logiclevel) { unsigned int logiclevel) {
GpioMapIter gpioMapIter = gpioMap.find(gpioId);
std::string chipname;
unsigned int lineNum;
struct gpiod_chip *chip;
struct gpiod_line *line;
int result; int result;
Gpio::Direction direction; struct gpiod_line *lineHandle;
std::string consumer;
/* Verify if GPIO has been configured as output */ gpioMapIter = gpioMap.find(gpioId);
direction = gpioMapIter->second.direction; if (gpioMapIter == gpioMap.end()){
if (direction != Gpio::OUT) { sif::debug << "LinuxLibgpioIF::driveGpio: Unknown gpio id " << gpioId << std::endl;
sif::error << "LinuxLibgpioIF::driveGpio: GPIO with ID " << gpioId return RETURN_FAILED;
<< "not configured as output" << std::endl;
return CONFIGURATION_FAILURE;
} }
chipname = gpioMapIter->second.chipname; lineHandle = gpioMapIter->second.lineHandle;
chip = gpiod_chip_open_by_name(chipname.c_str()); result = gpiod_line_set_value(lineHandle, logiclevel);
if (!chip) {
sif::error << "LinuxLibgpioIF::driveGpio: Failed to open chip "
<< chipname << ". Gpio ID: " << gpioId << std::endl;
return OPEN_CHIP_FAILURE;
}
lineNum = gpioMapIter->second.lineNum;
line = gpiod_chip_get_line(chip, lineNum);
if (!line) {
sif::error << "LinuxLibgpioIF::driveGpio: Failed to open line. Gpio ID "
<< gpioId << std::endl;
gpiod_chip_close(chip);
return OPEN_LINE_FAILURE;
}
consumer = gpioMapIter->second.consumer;
result = gpiod_line_request_output(line, consumer.c_str(), 0);
if (result < 0) {
sif::error << "LinuxLibgpioIF::driveGpio: Failed to request line "
<< line << " from GPIO instance with ID: " << gpioId
<< std::endl;
gpiod_line_release(line);
return REQUEST_LINE_FAILURE;
}
result = gpiod_line_set_value(line, logiclevel);
if (result < 0) { if (result < 0) {
sif::error << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " sif::error << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID "
<< gpioId << "to low" << std::endl; << gpioId << " to logic level " << logiclevel << std::endl;
gpiod_line_release(line); return DRIVE_GPIO_FAILURE;
return PULLING_HIGH_FAILURE;
} }
gpiod_line_release(line);
return HasReturnvaluesIF::RETURN_OK; return RETURN_OK;
}
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) {
struct gpiod_line *lineHandle;
gpioMapIter = gpioMap.find(gpioId);
if (gpioMapIter == gpioMap.end()){
sif::debug << "LinuxLibgpioIF::readGpio: Unknown gpio id " << gpioId << std::endl;
return RETURN_FAILED;
}
lineHandle = gpioMapIter->second.lineHandle;
*gpioState = gpiod_line_get_value(lineHandle);
return RETURN_OK;
} }
ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap mapToAdd){ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap mapToAdd){
@ -118,12 +169,12 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap mapToAdd){
if (mapToAddIter->second.direction != gpioMapIter->second.direction){ if (mapToAddIter->second.direction != gpioMapIter->second.direction){
sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict " sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict "
<< "for GPIO " << mapToAddIter->first << std::endl; << "for GPIO " << mapToAddIter->first << std::endl;
return HasReturnvaluesIF::RETURN_OK; return RETURN_OK;
} }
/* Remove element from map to add because a entry for this GPIO /* Remove element from map to add because a entry for this GPIO
* already exists */ * already exists */
mapToAdd.erase(mapToAddIter); mapToAdd.erase(mapToAddIter);
} }
} }
return HasReturnvaluesIF::RETURN_OK; return RETURN_OK;
} }

View File

@ -18,11 +18,7 @@ public:
static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF; static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF;
static const ReturnValue_t CONFIGURATION_FAILURE = MAKE_RETURN_CODE(0x1); static const ReturnValue_t DRIVE_GPIO_FAILURE = MAKE_RETURN_CODE(0x2);
static const ReturnValue_t OPEN_CHIP_FAILURE = MAKE_RETURN_CODE(0x2);
static const ReturnValue_t OPEN_LINE_FAILURE = MAKE_RETURN_CODE(0x3);
static const ReturnValue_t REQUEST_LINE_FAILURE = MAKE_RETURN_CODE(0x4);
static const ReturnValue_t PULLING_HIGH_FAILURE = MAKE_RETURN_CODE(0x5);
LinuxLibgpioIF(object_id_t objectId); LinuxLibgpioIF(object_id_t objectId);
virtual ~LinuxLibgpioIF(); virtual ~LinuxLibgpioIF();
@ -30,6 +26,7 @@ public:
ReturnValue_t initialize(CookieIF * cookie) override; ReturnValue_t initialize(CookieIF * cookie) override;
ReturnValue_t pullHigh(gpioId_t gpioId) override; ReturnValue_t pullHigh(gpioId_t gpioId) override;
ReturnValue_t pullLow(gpioId_t gpioId) override; ReturnValue_t pullLow(gpioId_t gpioId) override;
ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override;
private: private:
@ -56,6 +53,11 @@ private:
* @return RETURN_OK if successful, otherwise RETURN_FAILED * @return RETURN_OK if successful, otherwise RETURN_FAILED
*/ */
ReturnValue_t checkForConflicts(GpioMap mapToAdd); ReturnValue_t checkForConflicts(GpioMap mapToAdd);
/**
* @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd.
*/
ReturnValue_t configureGpios(GpioMap* mapToAdd);
}; };
#endif /* BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ */ #endif /* BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ */

View File

@ -21,19 +21,25 @@ namespace Gpio {
* the GPIO to access. E.g. gpiochip0. To detect names of * the GPIO to access. E.g. gpiochip0. To detect names of
* GPIO groups run gpiodetect on the linux command line. * GPIO groups run gpiodetect on the linux command line.
* @param lineNum The offset of the GPIO within the GPIO group. * @param lineNum The offset of the GPIO within the GPIO group.
* @param consumer Name of the consumer currently accessing the GPIO. * @param consumer Name of the consumer. Simply a description of the GPIO configuration.
* @param direction Specifies whether the GPIO should be used as in- or output. * @param direction Specifies whether the GPIO should be used as in- or output.
* @param initValue Defines the initial state of the GPIO when configured as output. Only required
* for output GPIOs.
* @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this
* pointer.
*/ */
typedef struct GpioConfig { typedef struct GpioConfig {
GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, GpioConfig(std::string chipname_, int lineNum_, std::string consumer_,
Gpio::Direction direction_) : Gpio::Direction direction_, int initValue_) :
chipname(chipname_), lineNum(lineNum_), consumer(consumer_), direction( chipname(chipname_), lineNum(lineNum_), consumer(consumer_), direction(
direction_) { direction_), initValue(initValue_) {
} }
std::string chipname; std::string chipname;
int lineNum; int lineNum;
std::string consumer; std::string consumer;
Gpio::Direction direction; Gpio::Direction direction;
int initValue;
struct gpiod_line* lineHandle;
} GpioConfig_t; } GpioConfig_t;
using GpioMap = std::unordered_map<gpioId_t, GpioConfig_t>; using GpioMap = std::unordered_map<gpioId_t, GpioConfig_t>;
using GpioMapIter = GpioMap::iterator; using GpioMapIter = GpioMap::iterator;

View File

@ -1,3 +1,4 @@
#!/bin/sh
export PATH=$PATH:"/c/Xilinx/SDK/2018.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" export PATH=$PATH:"/c/Xilinx/SDK/2018.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin"
export CROSS_COMPILE="arm-linux-gnueabihf" export CROSS_COMPILE="arm-linux-gnueabihf"

View File

@ -6,7 +6,8 @@
#ifndef FSFWCONFIG_OBSWCONFIG_H_ #ifndef FSFWCONFIG_OBSWCONFIG_H_
#define FSFWCONFIG_OBSWCONFIG_H_ #define FSFWCONFIG_OBSWCONFIG_H_
#define OBSW_ADD_TEST_CODE 0 #define TEST_LIBGPIOD 0
#define ADD_TEST_TAST 0
// These defines should be disabled for mission code but are useful for // These defines should be disabled for mission code but are useful for
// debugging. // debugging.
@ -14,7 +15,7 @@
#define TE0720 0 #define TE0720 0
#define P60DOCK_DEBUG 1 #define P60DOCK_DEBUG 0
#define PDU1_DEBUG 0 #define PDU1_DEBUG 0
#define PDU2_DEBUG 0 #define PDU2_DEBUG 0
#define ACU_DEBUG 0 #define ACU_DEBUG 0

View File

@ -5,7 +5,15 @@
namespace gpioIds { namespace gpioIds {
enum gpioId_t { enum gpioId_t {
HEATER_0 HEATER_0,
HEATER_1,
HEATER_2,
HEATER_3,
HEATER_4,
HEATER_5,
HEATER_6,
HEATER_7,
Test_ID
}; };
} }

View File

@ -3,7 +3,14 @@
namespace heaterSwitches { namespace heaterSwitches {
enum switcherList: uint8_t { enum switcherList: uint8_t {
PAYLOAD_CAMERA, HEATER_0,
HEATER_1,
HEATER_2,
HEATER_3,
HEATER_4,
HEATER_5,
HEATER_6,
HEATER_7,
NUMBER_OF_SWITCHES NUMBER_OF_SWITCHES
}; };
} }

View File

@ -50,6 +50,7 @@ namespace objects {
/* 0x54 ('T') for test handlers */ /* 0x54 ('T') for test handlers */
TEST_TASK = 0x54694269, TEST_TASK = 0x54694269,
LIBGPIOD_TEST = 0x54123456,
SPI_TEST = 0x54000010, SPI_TEST = 0x54000010,
DUMMY_INTERFACE = 0x5400CAFE, DUMMY_INTERFACE = 0x5400CAFE,
DUMMY_HANDLER = 0x5400AFFE, DUMMY_HANDLER = 0x5400AFFE,

View File

@ -6,7 +6,6 @@ GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t c
uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset) : uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset) :
DeviceHandlerBase(objectId, comIF, comCookie), maxConfigTableAddress(maxConfigTableAddress), DeviceHandlerBase(objectId, comIF, comCookie), maxConfigTableAddress(maxConfigTableAddress),
maxHkTableAddress(maxHkTableAddress), hkTableReplySize(hkTableReplySize), hkTableDataset(hkTableDataset) { maxHkTableAddress(maxHkTableAddress), hkTableReplySize(hkTableReplySize), hkTableDataset(hkTableDataset) {
mode = MODE_NORMAL;
if (comCookie == NULL) { if (comCookie == NULL) {
sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid com cookie" sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid com cookie"
<< std::endl; << std::endl;
@ -392,3 +391,7 @@ LocalPoolDataSetBase* GomspaceDeviceHandler::getDataSetHandle(sid_t sid) {
return nullptr; return nullptr;
} }
} }
void GomspaceDeviceHandler::setModeNormal() {
mode = MODE_NORMAL;
}

View File

@ -36,6 +36,12 @@ public:
uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset); uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset);
virtual ~GomspaceDeviceHandler(); virtual ~GomspaceDeviceHandler();
/**
* @brief This function can be used to set a gomspace device to normal mode immediately after
* object creation.
*/
void setModeNormal();
protected: protected:
static const uint8_t MAX_PACKET_LEN = 36; static const uint8_t MAX_PACKET_LEN = 36;

View File

@ -212,10 +212,9 @@ void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) {
if (mainSwitchState == PowerSwitchIF::SWITCH_ON) { if (mainSwitchState == PowerSwitchIF::SWITCH_ON) {
if (!checkSwitchState(switchNr)) { if (!checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr); gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
// result = gpioInterface->pullHigh(gpioId); result = gpioInterface->pullHigh(gpioId);
result = RETURN_OK;
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id" sif::error << "HeaterHandler::handleSwitchOnCommand: Failed to pull gpio with id "
<< gpioId << " high" << std::endl; << gpioId << " high" << std::endl;
triggerEvent(GPIO_PULL_HIGH_FAILED, result); triggerEvent(GPIO_PULL_HIGH_FAILED, result);
} }
@ -263,8 +262,7 @@ void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) {
/* Check whether switch is already off */ /* Check whether switch is already off */
if (checkSwitchState(switchNr)) { if (checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr); gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
// result = gpioInterface->pullLow(gpioId); result = gpioInterface->pullLow(gpioId);
result = RETURN_OK;
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id" sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id"
<< gpioId << " low" << std::endl; << gpioId << " low" << std::endl;
@ -305,9 +303,30 @@ bool HeaterHandler::allSwitchesOff() {
gpioId_t HeaterHandler::getGpioIdFromSwitchNr(int switchNr) { gpioId_t HeaterHandler::getGpioIdFromSwitchNr(int switchNr) {
gpioId_t gpioId = 0xFFFF; gpioId_t gpioId = 0xFFFF;
switch(switchNr) { switch(switchNr) {
case heaterSwitches::PAYLOAD_CAMERA: case heaterSwitches::HEATER_0:
gpioId = gpioIds::HEATER_0; gpioId = gpioIds::HEATER_0;
break; break;
case heaterSwitches::HEATER_1:
gpioId = gpioIds::HEATER_1;
break;
case heaterSwitches::HEATER_2:
gpioId = gpioIds::HEATER_2;
break;
case heaterSwitches::HEATER_3:
gpioId = gpioIds::HEATER_3;
break;
case heaterSwitches::HEATER_4:
gpioId = gpioIds::HEATER_4;
break;
case heaterSwitches::HEATER_5:
gpioId = gpioIds::HEATER_5;
break;
case heaterSwitches::HEATER_6:
gpioId = gpioIds::HEATER_6;
break;
case heaterSwitches::HEATER_7:
gpioId = gpioIds::HEATER_7;
break;
default: default:
sif::error << "HeaterHandler::getGpioIdFromSwitchNr: Unknown heater switch number" sif::error << "HeaterHandler::getGpioIdFromSwitchNr: Unknown heater switch number"
<< std::endl; << std::endl;

View File

@ -267,7 +267,7 @@ ReturnValue_t PCDUHandler::getFuseState( uint8_t fuseNr ) const {
} }
uint32_t PCDUHandler::getSwitchDelayMs(void) const { uint32_t PCDUHandler::getSwitchDelayMs(void) const {
return 15000; return 20000;
} }
object_id_t PCDUHandler::getObjectId() const { object_id_t PCDUHandler::getObjectId() const {

View File

@ -1,3 +0,0 @@
CXXSRC += $(wildcard $(CURRENTPATH)/testdevices/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/testinterfaces/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/testtasks/*.cpp)

View File

@ -0,0 +1,8 @@
target_sources(${TARGET_NAME} PUBLIC
LibgpiodTest.cpp
TestTask.cpp
)
target_include_directories(${TARGET_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -0,0 +1,36 @@
#include "LibgpiodTest.h"
#include "devices/gpioIds.h"
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/objectmanager/ObjectManagerIF.h>
LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie) :
TestTask(objectId) {
gpioInterface = objectManager->get<GpioIF>(gpioIfobjectId);
if (gpioInterface == nullptr) {
sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl;
}
gpioInterface->initialize(gpioCookie);
}
LibgpiodTest::~LibgpiodTest() {
}
ReturnValue_t LibgpiodTest::performPeriodicAction() {
int gpioState;
ReturnValue_t result;
result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState);
if (result != RETURN_OK) {
sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio "
<< std::endl;
return RETURN_FAILED;
}
else {
sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState
<< std::endl;
}
return RETURN_OK;
}

View File

@ -0,0 +1,25 @@
#ifndef TEST_TESTTASKS_LIBGPIODTEST_H_
#define TEST_TESTTASKS_LIBGPIODTEST_H_
#include "TestTask.h"
#include "GpioIF.h"
#include "GpioCookie.h"
#include <fsfw/objectmanager/SystemObject.h>
/**
* @brief Test for the GPIO read implementation of the LinuxLibgpioIF.
* @author J. Meier
*/
class LibgpiodTest: public TestTask {
public:
LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie);
virtual ~LibgpiodTest();
protected:
virtual ReturnValue_t performPeriodicAction() override;
private:
GpioIF* gpioInterface;
};
#endif /* TEST_TESTTASKS_LIBGPIODTEST_H_ */