Compare commits

...

428 Commits

Author SHA1 Message Date
c4b348c97f Merge pull request 'Update to v1.1.0' (#29) from develop into master
Reviewed-on: eive/eive_obsw#29
2021-04-25 12:43:23 +02:00
c19cdaaa16 Merge pull request 'Update v1.2 - MGT - RTD - PUSC' (#28) from mueller/mgt-rtd-pusc into develop
Reviewed-on: eive/eive_obsw#28
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-04-25 12:40:38 +02:00
89dbe078c9 Merge remote-tracking branch 'origin/develop' into mueller/mgt-rtd-pusc 2021-04-25 12:38:22 +02:00
38ea091a7f obsw version update 2021-04-25 12:37:59 +02:00
e1c7ed419f OBSW VERsion 2021-04-25 12:35:24 +02:00
76c31a4d13 Merge pull request 'Added FSFW HAL, some GPIO modules moved, FSFW update' (#27) from mueller/added-fsfw-hal into develop
Reviewed-on: eive/eive_obsw#27
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-04-25 12:34:26 +02:00
b042335ed1 Merge remote-tracking branch 'origin/meier/mgtHandler' into mueller/master 2021-04-25 12:25:55 +02:00
9fd7943e2e tmtc update 2021-04-25 12:23:34 +02:00
1472c3754d fsfw update 2021-04-25 11:33:32 +02:00
4580a4ef37 tmtc update 2021-04-25 11:32:49 +02:00
132acf0dd3 tmtc and obj factory update 2021-04-25 11:32:21 +02:00
4ec2454542 added modgen submodule 2021-04-25 11:10:05 +02:00
c2a366e449 fixed merge conflicts 2021-04-25 10:51:59 +02:00
053e5f6e92 merged mueller master 2021-04-25 09:33:21 +02:00
076c00717c deleted faulty header includes 2021-04-25 09:24:41 +02:00
3902951a70 Merge branch 'mueller/master' into meier/mgtHandler 2021-04-25 00:06:04 +02:00
b3054baccf fsfw update 2021-04-25 00:00:17 +02:00
24a3b11d62 everything seems to work now 2021-04-24 23:41:27 +02:00
962b267454 added dns name 2021-04-24 23:17:45 +02:00
5cf2338f09 adaptions for new fsfw, using pus c now 2021-04-24 23:04:17 +02:00
1e1446c40e issue with poolManager.subscribe in max handler 2021-04-24 22:55:26 +02:00
c276c11e21 updated fsfw and tmtc submodule 2021-04-24 22:51:04 +02:00
cbbc501039 typo fix 2021-04-24 14:55:15 +02:00
fa2c9344d6 mgt debugging 2021-04-24 13:01:49 +02:00
0c892982ae cs gyro 1 change 2021-04-12 10:22:13 +02:00
c6171a6c2a merged origin 2021-04-11 15:21:15 +02:00
97e5eb7319 spi chipselects changes 2021-04-11 15:18:55 +02:00
0b9ae5e4ec common versioning file 2021-04-11 12:25:23 +02:00
0677852cfc Merge branch 'develop' into mueller/added-fsfw-hal 2021-04-10 22:49:14 +02:00
3046b62ddb resolved merge conflicts 2021-04-10 22:22:39 +02:00
c4a6a680c8 fsfw and fsfw_hal update 2021-04-10 21:59:19 +02:00
5fbaca9b9f non block almostr eworking 2021-04-02 16:44:25 +02:00
14b69ed7e9 minor formatting stuff 2021-04-02 15:26:57 +02:00
1647b8a98e hal update 2021-04-02 15:16:41 +02:00
437f4573b5 added more spi test code, preprocessor defines
and various bugfixes
2021-04-02 15:14:08 +02:00
2dbe893197 added device handler 2021-04-02 13:25:37 +02:00
ffa11ce253 pushed stuff 2021-04-01 17:19:12 +02:00
62834bebcc small form improvements 2021-04-01 17:06:35 +02:00
e79a8e0926 now its compiling 2021-04-01 16:33:30 +02:00
bcc2f89f12 Merge branch 'meier/max13865pt1000Handler' into mueller/master 2021-04-01 16:22:25 +02:00
aa606b031a fixes 2021-04-01 16:21:24 +02:00
e1454db4b9 some adaptions 2021-04-01 15:42:51 +02:00
248c381ade Merge branch 'mueller/master' into meier/max13865pt1000Handler 2021-04-01 15:34:28 +02:00
29d8c8c0c8 one missing zeros 2021-04-01 15:22:16 +02:00
af48c6528d compiling 2021-04-01 15:14:50 +02:00
0027a43315 polling sequence table entries for acs devices 2021-04-01 15:32:43 +02:00
12be9bf7e4 added rpi acs board code to q7s 2021-04-01 14:06:56 +02:00
e86106615a updated default Q7S sysroot 2021-04-01 13:31:10 +02:00
1a4830aea9 deleted folder which was moved 2021-04-01 11:07:56 +02:00
fb7abbc82b moved i2c to fsfw_hal as well 2021-04-01 11:06:26 +02:00
2b3d531e5d moved spi code to fsfw_hal 2021-04-01 10:59:36 +02:00
4e2d8bdc5c updated host osal 2021-04-01 10:37:34 +02:00
5f6479d193 added unix path helper 2021-04-01 10:24:21 +02:00
1eb487a84b Merge remote-tracking branch 'origin/mueller/added-fsfw-hal' into mueller/master 2021-04-01 10:14:01 +02:00
f13b86379f updated to new fsfw 2021-04-01 10:12:57 +02:00
c5406951ad Merge remote-tracking branch 'origin/develop' into mueller/master 2021-04-01 10:11:36 +02:00
93daabab73 fsfw update 2021-04-01 10:09:37 +02:00
b062be78db Merge branch 'meier/mgtHandler' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into meier/mgtHandler 2021-03-29 16:54:22 +02:00
eee73f46c5 fixes in imqt 2021-03-29 16:40:14 +02:00
103c12052c corrections ofr updated common udp code 2021-03-29 14:42:33 +02:00
25b5734186 fsfw updated 2021-03-29 14:37:08 +02:00
ebfda75e34 added way to supply definesto cmake 2021-03-29 14:31:55 +02:00
77bd1ea50d merged origin mgtHandler 2021-03-26 14:07:13 +01:00
0e614aa163 submodules add 2021-03-26 14:05:56 +01:00
be9d11afff imqt handler compiled 2021-03-26 13:55:32 +01:00
1492d168d8 fixed merge conflicts 2021-03-26 12:30:24 +01:00
887a47f7f5 imtq instantiation 2021-03-26 12:08:37 +01:00
fed2d56e20 Merge branch 'meier/max13865pt1000Handler' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into meier/max13865pt1000Handler 2021-03-25 17:15:59 +01:00
515d56e423 transition delay set to 5000 again 2021-03-25 17:15:54 +01:00
04d0beac4c added all max handler 2021-03-25 13:10:48 +01:00
df723b26a1 rtd handler improvements 2021-03-24 12:53:25 +01:00
1ad03cef9e fixed q7s 2021-03-23 16:52:19 +01:00
ced80ce4d0 updated project files again 2021-03-23 16:47:35 +01:00
4bf1206fbd using new fsfw_hal now 2021-03-23 16:45:07 +01:00
f6fb7f4c4b integrating fsfw_hal 2021-03-23 16:15:31 +01:00
8d30c83d42 added fsfw hal 2021-03-23 16:06:23 +01:00
8331b76ea8 updated tmtc submodule 2021-03-23 13:44:45 +01:00
5bdd4dad28 fixed merge conflicts 2021-03-23 09:09:50 +01:00
af3231f405 minor changes in object factory 2021-03-22 13:57:21 +01:00
e44773fee3 solved all merge conflicts 2021-03-22 13:09:06 +01:00
862a546637 deleted polling sequence file 2021-03-22 12:47:45 +01:00
5439305b8c added fsfw 2021-03-22 12:17:00 +01:00
19abeadf74 IMTQHandler wip 2021-03-21 17:35:14 +01:00
682cdb3ce9 readem update 2021-03-20 16:09:11 +01:00
4e6fa7f5ac Merge branch 'mueller/master' into develop 2021-03-20 15:55:38 +01:00
cb2a3636df updated fsfw and obj factory 2021-03-20 15:55:15 +01:00
66375ab0cd corrected project files for host build 2021-03-20 15:07:04 +01:00
1fed42e3dc submodule update 2021-03-20 15:00:47 +01:00
88537fabc7 Merge pull request 'FSFW Update' (#26) from mueller/fsfw-update into develop
Reviewed-on: eive/eive_obsw#26
2021-03-19 16:13:02 +01:00
52a9807f4d Merge remote-tracking branch 'origin/develop' into mueller/fsfw-update 2021-03-19 15:54:12 +01:00
b33c38941e fixed for fsfw update 2021-03-19 15:52:39 +01:00
9404346722 Merge pull request 'Update package' (#25) from mueller/update-package into develop
Reviewed-on: eive/eive_obsw#25
2021-03-19 15:48:22 +01:00
f140eb4154 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into mueller/master 2021-03-19 15:44:22 +01:00
703eb5a1e1 fsfw update 2021-03-19 15:42:11 +01:00
6ec4d22a14 IMTQ dipole actuation command, wip 2021-03-19 15:33:43 +01:00
c3a3394c8a IMQT wip 2021-03-17 11:14:48 +01:00
e048d6d7ec rtd handler compiled 2021-03-13 14:42:30 +01:00
cbe55a605d lowered transition times and changed pst to 1sec 2021-03-07 14:11:13 +01:00
cdcb049736 disabled acs board test 2021-03-07 14:07:17 +01:00
dfec824222 L3DG20H device handler tested 2021-03-07 14:06:29 +01:00
5c04ddea1d doc added 2021-03-07 12:55:22 +01:00
b1dc0122b7 using big endian now for gyro 2021-03-07 12:53:10 +01:00
a581ce8bd6 added l3g handler 2021-03-07 12:50:41 +01:00
9ddbdbe19e both magnetic sensors working at once now 2021-03-06 20:49:22 +01:00
88f84c4393 rm3100 tested now as well 2021-03-06 20:37:17 +01:00
32670f4a81 simple rm3100 test working now 2021-03-06 20:21:23 +01:00
5f3d2b1516 started rm3100 testing 2021-03-06 18:12:50 +01:00
bf56ac90ad added additional build config RPI flag 2021-03-06 15:13:28 +01:00
9bf581a528 updated project files 2021-03-06 14:06:46 +01:00
7ed19866b0 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into mueller/master 2021-03-06 14:01:55 +01:00
271c7ce7ec made shell scripts executable 2021-03-06 14:01:18 +01:00
602097f1ed lwgps 2021-03-05 21:47:44 +01:00
57d46ca612 fsfw update 2021-03-05 21:12:57 +01:00
a6504e941d adaptions for fsfw api changes 2021-03-05 19:31:45 +01:00
6cc071f8ee removed make launch configs and updated shell scripts 2021-03-05 19:17:03 +01:00
fcda3bd2ea fsfw update 2021-03-05 18:55:58 +01:00
b75eef7c51 fixed merge conflict and copied max13865 code 2021-03-05 12:57:42 +01:00
93636426b6 moved some files 2021-03-04 18:29:28 +01:00
94ad41abb4 Merge pull request 'lwgps library integrated' (#23) from mueller/lwgps-integrated into develop
Reviewed-on: eive/eive_obsw#23
2021-03-04 18:24:01 +01:00
12f0c91342 Merge pull request 'SPI update, Version bump' (#22) from mueller/spi-com-if-tested into develop
Reviewed-on: eive/eive_obsw#22
2021-03-04 18:23:43 +01:00
189c35eb8d commented out setting pcdu to normal mode 2021-03-04 18:22:04 +01:00
be4977df68 syrlinks hk handler complete 2021-03-01 12:23:39 +01:00
f435238699 lwgps update 2021-02-28 16:16:22 +01:00
3cff08f644 lwgps update 2021-02-27 21:49:15 +01:00
02ac9b1fa5 updated init mission of hosted bsp
and executed lwGPS test
2021-02-27 21:39:32 +01:00
da30b270c4 added lwgps config 2021-02-27 21:24:19 +01:00
30c9d2dc0f solar array depl moved to bsp folder
hosted build working again
2021-02-27 19:46:13 +01:00
6518a7f244 moved all third-party lib to separate folder 2021-02-27 19:32:58 +01:00
b5650033d8 moved etl to thirdparty folder 2021-02-27 19:24:30 +01:00
581aa689ed added lwgps library 2021-02-27 19:22:18 +01:00
705a6d880a tmtc update 2021-02-27 19:21:22 +01:00
e4f3eb0172 added readout of some tx registers 2021-02-27 11:07:42 +01:00
c076ec5487 readme update 2021-02-25 18:18:47 +01:00
1ef873098f added hex string to int functions 2021-02-25 18:15:57 +01:00
4c09e973be hex to int wip 2021-02-25 15:53:28 +01:00
5d24627c91 adapter size of rx registers reply 2021-02-25 15:25:49 +01:00
8243db74ce tab replacements 2021-02-24 11:40:45 +01:00
561893a6b9 small form improvements 2021-02-24 11:36:35 +01:00
8b0ce0c5ec tab replacements 2021-02-24 11:35:22 +01:00
b108c73d35 printf support added 2021-02-24 11:32:24 +01:00
e7d4d7b4ee who am i reg is now checked 2021-02-24 11:24:31 +01:00
1416a56ae7 spi com if basic verification complete 2021-02-24 11:16:33 +01:00
2cc22b2233 added some testcode, zero init spi struct 2021-02-24 10:36:23 +01:00
6b982ce5cd lis 3 basic test code 2021-02-24 00:24:14 +01:00
93aafb4344 version is 1.0 now (i think were post alpha state..) 2021-02-23 22:11:42 +01:00
c5552bbc32 testing mgm handler 2021-02-23 22:07:39 +01:00
d7f8e11563 disabled tests by default 2021-02-23 18:19:11 +01:00
aa69b2f492 added stopwatch include 2021-02-23 18:18:12 +01:00
02c4cae12f removed obsolete printout 2021-02-23 18:14:23 +01:00
84ebc71b23 spi bugfixes 2021-02-23 18:01:28 +01:00
cb0fa384ca continued test class 2021-02-23 17:05:48 +01:00
a47c8d91a0 continued test task 2021-02-23 17:01:25 +01:00
178c3e2540 more bugfixes 2021-02-23 16:58:22 +01:00
673cfc8747 gpio bugfix 2021-02-23 16:47:34 +01:00
4248657680 fsfw update 2021-02-23 14:47:38 +01:00
09ff131133 libgpiod test 2021-02-23 14:44:16 +01:00
f65e28d33b fsfw update 2021-02-23 14:41:57 +01:00
e25e473c32 fsfw update 2021-02-23 14:41:40 +01:00
bbd6a36332 redordered includes 2021-02-23 13:39:01 +01:00
06173eeb03 small fixes for Q7S 2021-02-23 13:38:43 +01:00
46495dd123 deleted unused code 2021-02-23 13:34:34 +01:00
dfe2c81ecd cleaned up includes 2021-02-23 13:34:02 +01:00
c406133ae6 printf supportt 2021-02-23 13:33:12 +01:00
ed40ed70cc bugfix 2021-02-23 13:27:02 +01:00
434d0586b3 refactored GPIO to support callbacks 2021-02-23 13:24:05 +01:00
c042bbea63 source file for utility now 2021-02-23 12:13:04 +01:00
e1e0c07746 spi com if finished 2021-02-23 11:56:48 +01:00
3550fb6ca7 spi com if almost finished 2021-02-23 11:31:50 +01:00
a2e6634208 fsfw update 2021-02-22 18:48:58 +01:00
e9ffa930de better missed deadline handling 2021-02-22 18:46:45 +01:00
b03420c706 added service 20 2021-02-22 17:36:44 +01:00
ac250cb4cb bugfix 2021-02-22 14:25:46 +01:00
e6c75c54ea explicit cast so it compiles 2021-02-22 13:01:46 +01:00
7f05285803 heater handler moved 2021-02-22 12:59:50 +01:00
1ffcc8e5f6 Merge remote-tracking branch 'origin/develop' into mueller/master 2021-02-22 12:59:05 +01:00
400d5710d4 added link library gpiod 2021-02-22 12:57:41 +01:00
ab1b4271ec updated cmake lists 2021-02-22 12:45:10 +01:00
86e527882c added loopback test mode 2021-02-22 12:40:12 +01:00
7c71e2b067 separate folder for RPi builds 2021-02-22 12:36:28 +01:00
9bdc2096b0 syrlinks handler ready for testing 2021-02-22 09:24:42 +01:00
13c75ed9c2 save before removing approach with rememberCommandId 2021-02-19 15:41:50 +01:00
6e0e840c3a included crc for syrlinks 2021-02-19 12:10:02 +01:00
d8c1ad7f71 syrlinks handler wip 2021-02-19 11:02:27 +01:00
effb703d14 syrlinks handler wip 2021-02-18 16:16:38 +01:00
3bc5d1abce Merge branch 'develop' into meier/syrlinksHkHandler 2021-02-17 16:03:31 +01:00
32d17b9f03 improved s/a deployment handler 2021-02-17 16:02:49 +01:00
5179f165da syrlinks handler wip 2021-02-17 15:54:48 +01:00
4d4cf3f694 fixed merge conflicts 2021-02-17 10:33:19 +01:00
4d64897640 read acu hk table complete 2021-02-16 17:02:03 +01:00
c9947bbccc deployment handler 2021-02-16 15:32:24 +01:00
967618f687 new linux boardtest folder 2021-02-14 19:22:58 +01:00
aa5690687a small form stuff 2021-02-14 19:06:26 +01:00
83f080abe9 removed newlines 2021-02-14 18:53:11 +01:00
a8d2557545 added back member iter 2021-02-14 18:52:40 +01:00
0045cd2062 simplified i2c code 2021-02-14 18:45:31 +01:00
101a7696c3 corrected include guards, changed GpioIF prototype 2021-02-14 18:39:50 +01:00
6d2d7ad620 moved heater handler 2021-02-14 18:30:12 +01:00
fc0337af04 some minor improvements 2021-02-14 18:21:59 +01:00
9a995a9b5c reference returned now 2021-02-14 17:44:16 +01:00
e116e0dc64 Merge pull request 'Improved structure' (#17) from mueller/master into develop
Reviewed-on: eive/eive_obsw#17
2021-02-14 16:28:51 +01:00
95ab220f6e corrected p60dock max reply size 2021-02-14 15:49:03 +01:00
c6e145f17d tabs/spaces 2021-02-14 15:01:04 +01:00
313f7f6ec1 repaired q7s build/includes 2021-02-14 14:59:43 +01:00
f64d707f4c moved stuff to linux folder 2021-02-14 14:55:33 +01:00
b4e6edce80 new section for sysroot 2021-02-14 14:48:24 +01:00
37eed4182c readme update 2021-02-14 14:43:25 +01:00
8e9af49574 readme update 2021-02-14 14:41:44 +01:00
b022822113 updated project files 2021-02-14 14:33:53 +01:00
539eb91719 readme update 2021-02-14 14:32:45 +01:00
96a620ccc7 small detail added 2021-02-14 13:26:35 +01:00
be5b189ba0 readme update 2021-02-14 13:24:13 +01:00
38402eac45 compile check succesfull 2021-02-14 13:07:05 +01:00
00fa7fd67e updated project files 2021-02-14 12:57:35 +01:00
f006188814 moved some files 2021-02-14 12:57:09 +01:00
56c89a0751 added new linux folder 2021-02-14 12:35:08 +01:00
ae47acdbbb moved gpiod test to bsp folder 2021-02-14 12:23:29 +01:00
f2b1255b39 fsfw and tmtc update 2021-02-14 12:19:43 +01:00
217c1a6c2a deleted doubled cmake debug folder 2021-02-14 12:08:12 +01:00
9d87b368fb fixed bug with hk table reply size 2021-02-14 12:07:18 +01:00
29fb3cb9b8 Merge branch 'meier_eiveobsw' into meier/acuHkTable 2021-02-14 11:40:49 +01:00
f042572429 little issue with acu hk reply 2021-02-14 11:40:40 +01:00
88f62c5a11 restructured objectfactory and init_mission for libgpio test on te0720 2021-02-14 11:03:53 +01:00
df0e1aa869 fixed merge conflicts 2021-02-14 10:07:31 +01:00
bdc4b1cec5 added gpio read function 2021-02-14 09:25:40 +01:00
1f5504b7f7 Merge pull request 'Small update, Submodule updates' (#15) from mueller/master into develop
Reviewed-on: eive/eive_obsw#15
2021-02-14 08:37:55 +01:00
6cd9d439bc fsfw and tmtc update 2021-02-13 19:00:34 +01:00
5783dfdd06 compilation successful of acu hk table dataset 2021-02-12 22:38:41 +01:00
76e59e3593 improved linux libgpiod interface 2021-02-12 21:23:35 +01:00
b908393b79 added all heater switches 2021-02-12 15:24:37 +01:00
aa70d04730 acu hk tabel local pool, wip 2021-02-12 14:31:43 +01:00
b82e1d72ea added heater 1 2021-02-12 14:18:34 +01:00
7b4949583b enabled gpio switching in heater again 2021-02-12 12:52:40 +01:00
9c02809e10 improved debug messages 2021-02-12 10:51:32 +01:00
78086ebbc7 added p60 dock hk table local pool 2021-02-12 10:20:39 +01:00
95e549e313 init local pool for hktable, wip 2021-02-11 08:49:12 +01:00
5ccb3d1488 heater main switch commanding 2021-02-11 08:19:48 +01:00
1c3d0488e8 fsfw update 2021-02-09 12:43:03 +01:00
64a7532f3f p60 dock init local pool 2021-02-09 10:31:40 +01:00
d602912364 fixed PCDU memory leak 2021-02-08 14:12:36 +01:00
f4249e82e3 issue with PDU Handler 2021-02-08 11:48:58 +01:00
5a70df7bd7 pdu2 hk table periodic request 2021-02-06 16:13:31 +01:00
c3665cbd65 pdu2 dataset update snapshot 2021-02-06 11:57:45 +01:00
015251dab1 fsfw update 2021-02-05 11:17:40 +01:00
00cabbb8e9 save before changing pdu hk table dataset 2021-02-05 07:37:21 +01:00
3d734117e1 pcdu handler pdu2 dataset wip 2021-02-03 19:35:55 +01:00
e33769e654 Merge branch 'develop' into mueller/master 2021-02-03 14:18:24 +01:00
9b8c4fadb1 tmtc update 2021-02-03 14:18:13 +01:00
8e0b38f8db tmtc update 2021-02-03 14:15:06 +01:00
19fb5535f6 fsfw update 2021-02-03 13:41:32 +01:00
75a1db70f4 fsfw update 2021-02-03 13:40:04 +01:00
86df9a9e30 updated eive repo 2021-02-03 13:38:04 +01:00
38d4b28a90 save structs for datasets 2021-02-03 08:09:54 +01:00
26f16995e0 commanding of HeaterHandler and GpioIF working 2021-02-01 11:17:20 +01:00
b9a7a30919 heater handler wip 2021-01-28 14:55:21 +01:00
712b9c83cf Merge pull request 'Updated FSFW' (#14) from mueller/master into develop
Reviewed-on: eive/eive_obsw#14
2021-01-23 17:24:34 +01:00
0a36325371 heater wip 2021-01-23 17:22:40 +01:00
5d354f3526 improved cmake lists 2021-01-19 16:45:33 +01:00
1b44fe3840 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into mueller/master 2021-01-19 16:35:57 +01:00
3345f08c31 updated cmakelists 2021-01-19 16:35:44 +01:00
d913fbb416 old approach gpio lib 2021-01-16 12:22:17 +01:00
d66ac9e4a6 bugfix 2021-01-14 12:26:12 +01:00
fa4e442eac updated fsfw, moved file 2021-01-14 12:23:31 +01:00
84c802baec important fsfw bugfix 2021-01-14 12:17:05 +01:00
5f59a2792f updated fsfwconfig files 2021-01-14 12:07:11 +01:00
7d32303f29 updated cproject f ile 2021-01-14 12:05:49 +01:00
f965b783f9 fsfw update 2021-01-14 12:03:01 +01:00
88959f2208 implemented api change 2021-01-14 11:37:32 +01:00
f6b13546bc fsfw update 2021-01-14 11:33:48 +01:00
df67887926 deprecated wiringPi 2021-01-14 10:52:41 +01:00
0f6395b460 added gpio sysfs if 2021-01-14 00:40:30 +01:00
9eaebd22c0 updated tmtc 2021-01-13 22:42:01 +01:00
50a214e6ff little fix in gs device handler class 2021-01-12 13:26:09 +01:00
677979c2c1 added second tmp1075 2021-01-12 11:17:36 +01:00
fd41c3b4db tmp1075handler and I2cComIF complete 2021-01-12 10:39:24 +01:00
adef6eb188 temperature reading successul, but i2c sometimes hanging up 2021-01-11 16:56:44 +01:00
c73c41b03a fixed merge conflicts 2021-01-08 10:05:36 +01:00
64c3aa5e9d tmp1075 handler, wip 2021-01-08 09:34:43 +01:00
35d6d47bd0 updated fsfw config 2021-01-07 20:41:33 +01:00
78d097e965 updated to new fsfw branch 2021-01-07 20:38:07 +01:00
d426699cc3 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into mueller/master 2021-01-07 20:32:32 +01:00
f8f0226a13 submodule update 2021-01-07 20:32:15 +01:00
7eba60ba29 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into mueller/master 2020-12-30 23:39:15 +01:00
700a7ec2e6 tmtc update 2020-12-30 23:39:05 +01:00
40238caee4 readme update 2020-12-30 16:20:07 +01:00
d387c1ce69 added project files 2020-12-30 14:36:02 +01:00
8d0b87524e updated readme 2020-12-30 14:34:25 +01:00
e216e03897 reamde update 2020-12-30 10:37:01 +01:00
58ab8996bf readme update 2020-12-30 10:22:52 +01:00
43e986de90 added readme and user manual 2020-12-30 10:10:15 +01:00
6687a913fe README update 2020-12-30 09:39:34 +01:00
78b17fdb45 typo 2020-12-29 22:29:02 +01:00
1ca24ae6e0 png capital 2020-12-29 22:24:38 +01:00
9a2b2dd167 one pic not showing,. 2020-12-29 22:23:12 +01:00
c4e57ec818 readme update 2020-12-29 22:21:39 +01:00
af43722ee8 updared readme, added scripts 2020-12-29 22:20:38 +01:00
db4e918649 cmake lists update 2020-12-29 18:12:05 +01:00
ac01d54804 Merge pull request 'Update' (#12) from mueller/master into develop
Reviewed-on: eive/eive_obsw#12
2020-12-29 18:11:11 +01:00
3a9c0f7c9a Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into mueller/master 2020-12-29 18:07:03 +01:00
ffe22036c6 suppressed warning flags 2020-12-29 18:06:52 +01:00
8f6afda279 Merge pull request 'CMake update' (#11) from mueller/cmake-update into develop
Reviewed-on: eive/eive_obsw#11
2020-12-29 17:55:34 +01:00
d07294980a reamde update 2020-12-29 15:04:08 +01:00
6995d52a9a added launch config 2020-12-29 14:59:14 +01:00
9bedc302f4 added linux release launch config 2020-12-29 14:57:19 +01:00
326c595bbe deleted make luanch config 2020-12-29 14:55:10 +01:00
a8edb34931 some fixes, launch configs added 2020-12-29 14:53:34 +01:00
7afd80d0ab includes formal correction 2020-12-29 14:39:03 +01:00
3f41fc181c include fix 2020-12-29 14:37:39 +01:00
dd211f23cb added cmake launch config 2020-12-29 14:31:10 +01:00
bc5f340e2b renamed launch configs for clear distrinction 2020-12-29 14:29:38 +01:00
455ad12fec updated project files 2020-12-29 14:28:38 +01:00
df355652e0 restructured build system support 2020-12-29 14:21:52 +01:00
dd37efd34d fsfw points to eive/develop now 2020-12-29 14:14:11 +01:00
9a6fbbaff6 added cmake support for csp lib 2020-12-29 13:59:31 +01:00
96ea535242 Merge remote-tracking branch 'origin/develop' into mueller/master 2020-12-29 12:37:03 +01:00
e7f34185f4 Merge pull request 'meier/pcduhandler' (#10) from meier/pcduhandler into develop
Reviewed-on: eive/eive_obsw#10
2020-12-29 12:35:44 +01:00
6666ae0e3e small bugfix 2020-12-29 12:22:35 +01:00
33b48e97a3 fsfw update 2020-12-29 12:16:38 +01:00
fe9364550d fsfw points to devel now 2020-12-29 12:15:55 +01:00
d0114d53c2 correction in factoryx 2020-12-29 02:16:39 +01:00
d4c4c6dd40 project name corrected 2020-12-29 02:15:04 +01:00
9ee2e4e1da added q7s xcompile file 2020-12-29 01:40:47 +01:00
4c30deb6cb including taspbery pi bsp 2020-12-29 01:28:21 +01:00
be82cd472e added rpi support 2020-12-29 01:26:22 +01:00
e2d7905334 bugfix 2020-12-29 01:15:35 +01:00
c1e9604977 added cmake support 2020-12-29 01:09:59 +01:00
5fe0ea5fc9 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive_obsw into mueller/master 2020-12-28 23:54:16 +01:00
647126863c fixed merge conflict 2020-12-28 11:16:58 +01:00
2b09baad4f merged mueller/tmtc-dh-update 2020-12-28 11:14:08 +01:00
abf53527b3 Merge pull request 'Device Handler Updates' (#9) from mueller/tmtc-dh-update into develop
Reviewed-on: eive/eive_obsw#9
2020-12-28 11:09:08 +01:00
aa33d23563 added polling sequence table slot for PERFORM_OPERATION 2020-12-28 11:02:24 +01:00
d97f0aaed0 adapted GomspaceDeviceHandler to new DeviceHandlerBase 2020-12-28 09:49:50 +01:00
de433e06a1 now compiling 2020-12-27 17:31:38 +01:00
13a83a2f16 Merge branch 'hotfix/fsfwconfig' into mueller/master 2020-12-27 17:16:53 +01:00
4e90612d34 fix 2020-12-27 17:15:59 +01:00
c60457cf57 another fix 2020-12-27 17:14:26 +01:00
cb01bcd97d Merge branch 'hotfix/fsfwconfig' into meier/pcduhandler 2020-12-27 17:07:37 +01:00
9c42b40cc1 tmtc update 2020-12-27 17:04:15 +01:00
4737fc4f6e Merge remote-tracking branch 'origin/hotfix/fsfwconfig' into mueller/master 2020-12-27 17:01:57 +01:00
64972f1e43 more fixes 2020-12-27 17:00:38 +01:00
c3833c4a4c Merge branch 'hotfix/fsfwconfig' into meier/pcduhandler 2020-12-27 16:57:55 +01:00
3df7a6d23e another fix 2020-12-27 16:56:51 +01:00
86b36352dc Merge branch 'hotfix/fsfwconfig' into meier/pcduhandler 2020-12-27 16:48:34 +01:00
d359222b45 another fix 2020-12-27 16:46:01 +01:00
025337227c fsfwconfig fix 2020-12-27 16:45:37 +01:00
52a2973291 updated config 2020-12-27 16:29:49 +01:00
6dbafec3ad fixed merge conflict 2020-12-27 15:32:16 +01:00
14ae300363 Merge branch 'develop' into mueller/master 2020-12-27 15:31:01 +01:00
4636a809f4 tmtc p60dock 2020-12-27 15:27:16 +01:00
fdf72f2fb3 Merge pull request 'TMTC updated' (#7) from mueller/tmtc-update into develop
Reviewed-on: eive/eive_obsw#7
2020-12-27 15:22:45 +01:00
0a86fab520 valid fsfw now 2020-12-23 20:26:37 +01:00
8421c5de0d fsfw update 2020-12-23 20:20:22 +01:00
7e0c56edcb gyro handler finished 2020-12-23 20:17:39 +01:00
76a6db18ab started with l3dg20h definitions 2020-12-22 13:44:32 +01:00
2203b8ed53 started gyro handler, renamed 2020-12-22 13:41:01 +01:00
7aceb6a658 added top comment block 2020-12-22 13:36:10 +01:00
421ac0e1fe added top comment 2020-12-22 13:32:40 +01:00
e817a38f92 replaced last sent command with
getPendingCommand()
2020-12-22 00:36:39 +01:00
de0f8f5c41 added gps handler stub 2020-12-22 00:32:11 +01:00
88d357fe4d added gyro handler stub 2020-12-22 00:30:50 +01:00
f692993954 rm3100 finished, lis3 set normal datapool entries
invalid removed, will be replaced by default implementation
2020-12-22 00:24:19 +01:00
8ecd0ec551 rm3100 continued 2020-12-21 23:09:35 +01:00
24cf9a661f rm3100 continued 2020-12-21 19:52:00 +01:00
1e33f810cf type correction 2020-12-21 19:50:50 +01:00
1cf278e23e started rm3100 handler 2020-12-21 19:50:01 +01:00
bb1735d0fe updated project file 2020-12-21 18:15:27 +01:00
b0434a3d72 reparied arduino stuff 2020-12-21 18:14:03 +01:00
2372ddef78 makefile hosted update 2020-12-21 17:52:53 +01:00
042d014148 disabled LTO for host release build on windows 2020-12-21 17:32:51 +01:00
dce00e9b53 resolved merge conflict 2020-12-21 10:29:44 +01:00
f330650b55 cspcomif removed commented lines 2020-12-21 10:27:29 +01:00
f573d15830 p60dock, acu and pdu handler completed 2020-12-21 10:26:28 +01:00
c9fbd2c048 working pdu2handler 2020-12-20 17:35:03 +01:00
23fd408e08 issue with makefile 2020-12-20 13:31:44 +01:00
208fd889f7 added eclipse project and launch files 2020-12-17 19:50:11 +01:00
39ff3f6c9b deleted linux bsp arduino files 2020-12-17 19:47:21 +01:00
26ffc5a470 additional include for win compileation 2020-12-17 19:45:20 +01:00
2450d2240e updated gitignore file 2020-12-17 19:43:20 +01:00
4e11eafd28 c++ include used 2020-12-17 19:38:26 +01:00
688ada173e tmtc update 2020-12-17 19:38:09 +01:00
c74405d4a8 tmtc update 2020-12-17 18:43:27 +01:00
90c06122f2 tmtc update 2020-12-17 18:16:49 +01:00
20fffd8b48 tmtc points to new commit 2020-12-17 18:11:40 +01:00
8d99dd6021 tmtc update 2020-12-17 18:04:33 +01:00
2881d4e7b2 tmtc update 2020-12-17 18:04:04 +01:00
a59432f41f added new tmtc submodule 2020-12-17 17:47:40 +01:00
b2a460d77f removed tmtc submodule, will be replaced 2020-12-17 17:46:11 +01:00
b19cfbfc2b tmtc update 2020-12-17 17:45:42 +01:00
0ebd9e2c43 fsfw update 2020-12-17 17:44:54 +01:00
a9f2c98f8d tmtc p60dock 2020-12-17 15:49:11 +01:00
d69e79ce07 Merge branch 'master' into meier_eiveobsw
update meier_eiveobsw
2020-12-17 14:28:22 +01:00
009850273b added tmtc 2020-12-17 14:27:49 +01:00
5f46e4ab6a updated tmtc 2020-12-17 14:19:05 +01:00
5fac6424ca p60 dock handler completed 2020-12-17 13:26:00 +01:00
32bd57d6d1 ping test 2020-12-16 15:17:10 +01:00
f022504fe4 fsfw update 2020-12-16 14:05:38 +01:00
380543756d successful change of endian swapping in p60dock param set 2020-12-16 11:02:49 +01:00
f778292d8e working parameter getting and setting of p60dock 2020-12-16 10:56:32 +01:00
e0c57f5d5d updated obsw config 2020-12-14 22:52:53 +01:00
48386a8e3f stuff stored in local poo lnow 2020-12-14 22:50:15 +01:00
29c07461b3 Merge branch 'mueller/master' into develop 2020-12-14 22:30:35 +01:00
ccf9770172 formatting 2020-12-14 22:23:28 +01:00
20911a15a2 again, indentation.. 2020-12-14 22:21:47 +01:00
512cf58579 indentation 2020-12-14 22:18:25 +01:00
7db8914c32 tmtc update 2020-12-14 22:15:07 +01:00
45283131e3 Merge branch 'master' into develop 2020-12-14 22:12:42 +01:00
e539d63293 updated submodules 2020-12-14 22:09:18 +01:00
fd75183590 hosted build working again 2020-12-14 22:03:57 +01:00
9b990f86fd fsfw update 2020-12-14 21:57:52 +01:00
bdc506a54c some fixes 2020-12-14 13:03:47 +01:00
c88bc6508d successful temperature reading 2020-12-14 09:46:59 +01:00
551a8f021b wip CspComIF 2020-12-14 08:42:48 +01:00
c502ee1172 wip CspComIF 2020-12-14 08:42:21 +01:00
fa0cdcf399 read module config and read hk working 2020-12-10 10:01:45 +01:00
b8dd7b74cd timeout error in hk read 2020-12-09 12:24:34 +01:00
ed77c97432 read module cfg and read hk from p60 dock, intermediate state 2020-12-09 12:00:24 +01:00
a195f63acb some changes for P60Dock cookie 2020-12-05 14:52:18 +01:00
47b6485e29 p60dock read config table compiling 2020-12-04 20:08:58 +01:00
2f4421b904 parts of p60dock handler 2020-12-04 14:14:08 +01:00
12d5db0ec0 device definition adaptions taken over 2020-12-03 12:57:44 +01:00
7edaba4d5d taken over source lis3mdl device 2020-12-03 12:49:14 +01:00
c68566a1e1 read temperature test 2020-11-28 13:41:30 +01:00
338857efc3 p60 dock test task get parameters incomplete 2020-11-27 12:07:33 +01:00
a8e9a6f0de extended p60 dock test task 2020-11-26 18:13:20 +01:00
17fc4b0de1 save failed integration state 2020-11-26 10:24:23 +01:00
77970418d8 resolved merge conflicts 2020-11-25 16:17:16 +01:00
81ae5ea167 bring up can, readme 2020-11-25 09:19:51 +01:00
9d092edda4 pdock 60 test task 2020-11-23 11:42:22 +01:00
6c23b00c22 failed approach 2020-11-19 18:24:03 +01:00
381 changed files with 32965 additions and 1776 deletions

13
.gitignore vendored
View File

@ -2,8 +2,21 @@ _obj
_bin
_dep
Debug
Debug*
Release
Release*
MinSizeRel
MinSizeRel*
RelWithDebInfo
RelWithDebInfo*
.settings
.metadata
.project
.cproject
__pycache__
!misc/eclipse/**/.cproject
!misc/eclipse/**/.project
/eive_obsw cmake debug/

17
.gitmodules vendored
View File

@ -1,12 +1,21 @@
[submodule "etl"]
path = etl
path = thirdparty/etl
url = https://github.com/ETLCPP/etl.git
[submodule "tmtc"]
path = tmtc
url = https://git.ksat-stuttgart.de/Robin.Mueller/tmtc.git
[submodule "arduino"]
path = arduino
url = https://egit.irs.uni-stuttgart.de/eive/eive_arduino_interface.git
[submodule "fsfw"]
path = fsfw
url = https://egit.irs.uni-stuttgart.de/eive/fsfw.git
[submodule "tmtc"]
path = tmtc
url = https://egit.irs.uni-stuttgart.de/eive/eive_tmtc.git
[submodule "thirdparty/lwgps"]
path = thirdparty/lwgps
url = https://github.com/rmspacefish/lwgps.git
[submodule "fsfw_hal"]
path = fsfw_hal
url = https://egit.irs.uni-stuttgart.de/fsfw/fsfw_hal.git
[submodule "generators/modgen"]
path = generators/modgen
url = https://git.ksat-stuttgart.de/source/modgen.git

228
CMakeLists.txt Normal file
View File

@ -0,0 +1,228 @@
################################################################################
# CMake support for the EIVE OBSW
#
# Developed in an effort to replace Make with a modern build system.
#
# Author: R. Mueller
################################################################################
################################################################################
# Pre-Project preparation
################################################################################
cmake_minimum_required(VERSION 3.13)
# set(CMAKE_VERBOSE TRUE)
set(CMAKE_SCRIPT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
option(ADD_ETL_LIB "Add ETL library" ON)
if(NOT OS_FSFW)
set(OS_FSFW host CACHE STRING "OS for the FSFW.")
endif()
# Perform steps like loading toolchain files where applicable.
include(${CMAKE_SCRIPT_PATH}/PreProjectConfig.cmake)
pre_project_config()
# Project Name
project(eive_obsw ASM C CXX)
################################################################################
# Pre-Sources preparation
################################################################################
# Specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Set names and variables
set(TARGET_NAME ${CMAKE_PROJECT_NAME})
set(LIB_FSFW_NAME fsfw)
set(LIB_ETL_NAME etl)
set(LIB_CSP_NAME libcsp)
set(LIB_FSFW_HAL_NAME fsfw_hal)
set(LIB_LWGPS_NAME lwgps)
set(THIRD_PARTY_FOLDER thirdparty)
# Set path names
set(FSFW_PATH fsfw)
set(MISSION_PATH mission)
set(TEST_PATH test/testtasks)
set(LINUX_PATH linux)
set(COMMON_PATH common)
set(FSFW_HAL_LIB_PATH fsfw_hal)
set(CSP_LIB_PATH ${THIRD_PARTY_FOLDER}/libcsp)
set(ETL_LIB_PATH ${THIRD_PARTY_FOLDER}/etl)
set(LWGPS_LIB_PATH ${THIRD_PARTY_FOLDER}/lwgps)
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
set(ADD_LINUX_FILES TRUE)
# Analyse different OS and architecture/target options, determine BSP_PATH,
# display information about compiler etc.
include (${CMAKE_SCRIPT_PATH}/HardwareOsPreConfig.cmake)
pre_source_hw_os_config()
if(TGT_BSP)
if(${TGT_BSP} MATCHES "arm/q7s" OR ${TGT_BSP} MATCHES "arm/raspberrypi")
set(ROOT_CONFIG_FOLDER TRUE)
set(FSFW_CONFIG_PATH "fsfwconfig")
set(ADD_LINUX_FILES TRUE)
set(ADD_CSP_LIB TRUE)
set(FSFW_HAL_ADD_LINUX ON)
endif()
if(${TGT_BSP} MATCHES "arm/raspberrypi")
add_definitions(-DRASPBERRY_PI)
set(FSFW_HAL_ADD_RASPBERRY_PI ON)
endif()
if(${TGT_BSP} MATCHES "arm/q7s")
add_definitions(-DXIPHOS_Q7S)
endif()
else()
# Required by FSFW library
set(FSFW_CONFIG_PATH "${BSP_PATH}/fsfwconfig")
endif()
# Set for lwgps library
set(LWGPS_CONFIG_PATH "${COMMON_PATH}/config")
################################################################################
# Executable and Sources
################################################################################
# Add executable
add_executable(${TARGET_NAME})
# Add subdirectories
if(ROOT_CONFIG_FOLDER)
add_subdirectory(${FSFW_CONFIG_PATH})
endif()
if(ADD_CSP_LIB)
add_subdirectory(${CSP_LIB_PATH})
endif()
if(ADD_ETL_LIB)
add_subdirectory(${ETL_LIB_PATH})
endif()
if(ADD_LINUX_FILES)
add_subdirectory(${LINUX_PATH})
endif()
add_subdirectory(${LWGPS_LIB_PATH})
add_subdirectory(${BSP_PATH})
add_subdirectory(${FSFW_PATH})
add_subdirectory(${MISSION_PATH})
add_subdirectory(${TEST_PATH})
add_subdirectory(${FSFW_HAL_LIB_PATH})
add_subdirectory(${COMMON_PATH})
################################################################################
# Post-Sources preparation
################################################################################
set_property(CACHE OS_FSFW PROPERTY STRINGS host linux)
# Add libraries for all sources.
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_FSFW_NAME}
${LIB_OS_NAME}
${LIB_LWGPS_NAME}
${LIB_FSFW_HAL_NAME}
)
if(ADD_ETL_LIB)
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_ETL_NAME}
)
endif()
if(ADD_CSP_LIB)
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_CSP_NAME}
)
endif()
# Add include paths for all sources.
target_include_directories(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${FSFW_CONFIG_PATH}
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(WARNING_FLAGS
-Wall
-Wextra
-Wimplicit-fallthrough=1
-Wno-unused-parameter
-Wno-psabi
)
# Remove unused sections.
target_compile_options(${TARGET_NAME} PRIVATE
"-ffunction-sections"
"-fdata-sections"
)
# Removed unused sections.
target_link_options(${TARGET_NAME} PRIVATE
"-Wl,--gc-sections"
)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(COMPILER_FLAGS "/permissive-")
endif()
if(CMAKE_VERBOSE)
message(STATUS "Warning flags: ${WARNING_FLAGS}")
endif()
# Compile options for all sources.
target_compile_options(${TARGET_NAME} PRIVATE
${WARNING_FLAGS}
)
if(${CMAKE_CROSSCOMPILING})
include (${CMAKE_SCRIPT_PATH}/HardwareOsPostConfig.cmake)
post_source_hw_os_config()
endif()
if(NOT CMAKE_SIZE)
set(CMAKE_SIZE size)
if(WIN32)
set(FILE_SUFFIX ".exe")
endif()
endif()
if(TGT_BSP)
set(TARGET_STRING "Target BSP: ${TGT_BSP}")
else()
set(TARGET_STRING "Target BSP: Hosted")
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(
TARGET ${TARGET_NAME}
POST_BUILD
COMMAND ${CMAKE_SIZE} ${TARGET_NAME}${FILE_SUFFIX}
COMMENT ${POST_BUILD_COMMENT}
)
include (${CMAKE_SCRIPT_PATH}/BuildType.cmake)
set_build_type()

View File

@ -13,7 +13,7 @@ SHELL = /bin/sh
# Chip & board used for compilation
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
BOARD_FILE_ROOT = bsp_linux
BOARD_FILE_ROOT = bsp_q7s
BOARD = linux
OS_FSFW = linux
CUSTOM_DEFINES += -D$(OS_FSFW)
@ -25,6 +25,7 @@ MISSION_PATH = mission
CONFIG_PATH = fsfwconfig
TEST_PATH = test
UNITTEST_PATH = unittest
LIBCSP_PATH = libcsp
# Board specific paths
BSP_PATH = $(BOARD_FILE_ROOT)
@ -113,7 +114,7 @@ INCLUDES :=
# Directories where $(directoryname).mk files should be included from
SUBDIRS := $(FRAMEWORK_PATH) $(TEST_PATH) $(BSP_PATH) $(UNITTEST_PATH)\
$(CONFIG_PATH) $(MISSION_PATH)
$(CONFIG_PATH) $(MISSION_PATH) $(LIBCSP_PATH)
# INCLUDES += framework/test/catch2
# ETL library include.
@ -278,7 +279,7 @@ cleanbin:
-rm -rf $(BUILDPATH)/$(OUTPUT_FOLDER)
# Build target configuration
release: OPTIMIZATION = -Os $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
release: OPTIMIZATION = -O2 $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
release: LINK_TIME_OPTIMIZATION = -flto
release: TARGET = Release
release: OPTIMIZATION_MESSAGE = On with Link Time Optimization

View File

@ -15,14 +15,14 @@ CUSTOM_DEFINES :=
# Chip & board used for compilation
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
BOARD_FILE_ROOT = hosted
BOARD_FILE_ROOT = bsp_hosted
BOARD = host
OS_FSFW = host
CUSTOM_DEFINES += -D$(OS_FSFW)
DETECTED_OS :=
# Copied from stackoverflow, can be used to differentiate between Windows
# and Linux
ifeq ($(OS),Windows_NT)
DETECTED_OS = WINDOWS
CUSTOM_DEFINES += -DWIN32
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
CUSTOM_DEFINES += -DAMD64
@ -55,6 +55,14 @@ else
endif
endif
ifeq (${DETECTED_OS}, WINDOWS)
OS_FSFW = host
else
OS_FSFW = linux
endif
CUSTOM_DEFINES += -D$(OS_FSFW)
# General folder paths
FRAMEWORK_PATH = fsfw
MISSION_PATH = mission
@ -179,10 +187,10 @@ $(foreach S,$(SUBDIRS),$(eval $(INCLUDE_FILE)))
# VPATH += mission/pus/
ifeq ($(DETECTED_OS), LINUX)
CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TcUnixUdpPollingTask.cpp
CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TmTcUnixUdpBridge.cpp
endif
#ifeq ($(DETECTED_OS), LINUX)
#CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TcUnixUdpPollingTask.cpp
#CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TmTcUnixUdpBridge.cpp
#endif
# All C Sources included by .mk files are assigned here
# Add the objects to sources so dependency handling works
@ -227,7 +235,6 @@ DEAD_CODE_REMOVAL = -Wl,--gc-sections
# Link time is larger and size of object files can not be retrieved
# but resulting binary is smaller. Could be used in mission/deployment build
# Requires -ffunction-section in linker call
LINK_TIME_OPTIMIZATION = -flto
OPTIMIZATION += $(PROTOTYPE_OPTIMIZATION)
endif
@ -261,12 +268,12 @@ ASFLAGS = -Wall -g $(OPTIMIZATION) $(I_INCLUDES) -D__ASSEMBLY__
# LINK_INCLUDES specify the path to used libraries and the linker script
# LINK_LIBRARIES link HCC and HAL library and enable float support
LDFLAGS := -g3 -pthread $(DEAD_CODE_REMOVAL) $(OPTIMIZATION)
LINK_INCLUDES :=
LINK_LIBRARIES :=
ifeq ($(OS),Windows_NT)
LINK_LIBRARIES += -lwsock32 -lws2_32
else
LINK_LIBRARIES += -lrt
endif
# Gnu Coverage Tools Flags
@ -309,7 +316,10 @@ all: executable
# Build target configuration
release: OPTIMIZATION = -Os $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
# Problematic on MinGW
ifneq ($(OS),Windows_NT)
release: LINK_TIME_OPTIMIZATION = -flto
endif
release: TARGET = Release
release: OPTIMIZATION_MESSAGE = On with Link Time Optimization
release: DEBUG_LEVEL = -g0

559
README.md
View File

@ -4,7 +4,7 @@
Target systems:
* OBC
* OBC with Linux OS
* Xiphos Q7S
* Based on Zynq-7020 SoC (xc7z020clg484-2)
* Dual-core ARM Cortex-A9
@ -12,56 +12,157 @@ Target systems:
* Artix-7 FPGA (85K pogrammable logic cells)
* Datasheet at https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/Q7S&fileid=340648
* Also a lot of informatin about the Q7S can be found on the xiphos trac platform: https://trac.xiphos.com/trac/eive-q7/wiki/Q7RevB
* Linux OS
* Built with Yocto 2.5
* Linux OS built with Yocto 2.5
* Linux Kernel https://github.com/XiphosSystemsCorp/linux-xlnx.git
* Host System
* Generic software components which are not dependant on hardware can also
be run. All host code is contained in the hosted folder
be run on a host system. All host code is contained in the `bsp_hosted` folder
* Tested for Linux (Ubuntu 20.04) and Windows 10
* Raspberry Pi
* EIVE OBC can be built for Raspberry Pi as well (either directly on Raspberry Pi or by installing a cross compiler)
The steps in the primary README are related to the main OBC target Q7S.
The CMake build system can be used to generate build systems as well (see helper scripts in `cmake/scripts`:
- Linux (Raspberry Pi): See special section below.
- Linux Host: Uses the `bsp_hosted` BSP folder and the CMake Unix Makefiles generator.
- Windows Host: Uses the `bsp_hosted` BSP folder, the CMake MinGW Makefiles generator and MSYS2.
## Setting up development environment
### Installing Vivado the the Xilinx development tools
It's also possible to perform debugging with a normal Eclipse installation by installing
the TCF plugin. Still, it is necessary to install Vivado to get the toolchain for generating
C++ applications. Alternatively you can download the toolchain
[from the cloud](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/Q7S/Toolchain&fileid=422486).
* Install Vivado 2018.2 and Xilinx SDK from https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive.html.
Install the Vivado Design Suite - HLx Editions - 2018.2 Full Product Installation instead of the updates. It is recommended to use the installer
Install the Vivado Design Suite - HLx Editions - 2018.2 Full Product Installation instead of the updates. It is recommended to use the installer.
* Install settings. In the Devices selection, it is sufficient to pick SoC &rarr; Zynq-7000: <br>
<img src="./doc/img/xilinx-install.PNG" width="50%"> <br>
<img src="./doc/img/vivado-edition.png" width="50%"> <br>
<img src="./doc/img/vivado-hl-design.png" width="50%"> <br>
<img src="./doc/img/xilinx-install.PNG" width="50%"> <br>
* For supported OS refer to https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug973-vivado-release-notes-install-license.pdf
* Add path of linux cross-compiler to environment variables SDK\2018.2\gnu\aarch32\nt\gcc-arm-linux-gnueabi\bin
* Install make (only on windows, SDK on Linux can use the make installed with the SDK)
* Add path of linux cross-compiler to permanent environment variables (`.profile` file in Linux):
`<XilinxInstallation>\SDK\2018.2\gnu\aarch32\nt\gcc-arm-linux-gnueabi\bin`
or set up path each time before debugging.
### Installing make on Windows
1. Install NodeJS LTS
2. Install xpm
```sh
npm install --global xpm
```
### Installing CMake and MSYS2 on Windows
3. Install Windows build tools (after installation also linux commands like mkdir can be used from windows)
1. Install [MSYS2](https://www.msys2.org/) and [CMake](https://cmake.org/download/) first.
```sh
xpm install --global @xpack-dev-tools/windows-build-tools@latest
```
2. Open the MinGW64 console. It is recommended to set up aliases in `.bashrc` to navigate to the
software repository quickly
3. Run the following commands in MinGW64
## Building the software
```sh
pacman -Syuuu
```
It is recommended to install the full base development toolchain
```sh
pacman -S base-devel
```
It is also possible to only install required packages
```sh
pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-make mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb python3
```
### Installing CMake on Linux
1. Run the following command
```sh
sudo apt-get install cmake
````
## Getting the Q7S system root
It is necessary to copy the Q7S system root to your local development machine for libraries
like `libgpio`. You can find the system root [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/Q7S/Toolchain&fileid=422486). Download it and unzip it somewhere in the Xilinx installation folder.
Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path.
## Building the software with CMake
When using Windows, run theses steps in MSYS2.
1. Clone the repository with
```sh
git clone https://egit.irs.uni-stuttgart.de/eive/eive_obsw.git
```
```sh
git clone https://egit.irs.uni-stuttgart.de/eive/eive_obsw.git
```
2. Update all the submodules
```sh
git submodule init
git submodule sync
git submodule update
```
3. Open Xilinx SDK 2018.2
4. Import project
```sh
git submodule init
git submodule sync
git submodule update
```
3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version`.
It is recommended to run the shell script `win_path_helper_xilinx_tools.sh` in `cmake/scripts/Q7S`
or to set up the [PATH and the CROSS_COMPILE variable permanently](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path)
in the `.profile` file.
4. Run the CMake configuration to create the build system in a `Debug` folder.
Navigate into the `eive_obsw` folder first.
```sh
cd cmake/scripts/Q7S
./create_cmake_debug.sh
cd ../../..
```
This will invoke a Python script which in turn invokes CMake with the correct
arguments to configure CMake for Q7S cross-compilation.
5. Build the software with
```sh
cd Debug
cmake --build . -j
```
## Setting up default Eclipse for Q7S projects - TCF agent
The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debugging on the Q7S.
1. Install the TCF agent plugin in Eclipse from the [releases](https://www.eclipse.org/tcf/downloads.php). Go to Help &rarr; Install New Software and use the download page, for example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it.
2. Go to Window &rarr; Perspective &rarr; Open Perspective and open the **Target Explorer Perspective**.
Here, the Q7S should show up if the local port forwarding was set up as explained previously. Please note that you have to connect to `localhost` and port `1534` with port forwaring set up.
3. A launch configuration was provided, but it might be necessary to adapt it for your own needs. Alternatively:
- Create a new **TCF Remote Application** by pressing the cogs button at the top or going to Run &rarr; Debug Configurations &rarr; Remote Application and creating a new one there.
- Set up the correct image in the main tab (it might be necessary to send the image to the Q7S manually once) and file transfer properties
- It is also recommended to link the correct Eclipse project.
After that, comfortable remote debugging should be possible with the Debug button.
A build configuration and a shell helper script has been provided to set up the path variables and
build the Q7S binary on Windows, but a launch configuration needs to be newly created because the
IP address and path settings differ from machine to machine.
## Building in Xilinx SDK 2018.2
1. Open Xilinx SDK 2018.2
2. Import project
* File &rarr; Import &rarr; C/C++ &rarr; Existing Code as Makefile Project
5. Set build command. Replace \<target\> with either debug or release.
3. Set build command. Replace \<target\> with either debug or release.
* When on Linux right click project &rarr; Properties &rarr; C/C++ Build &rarr; Set build command to `make <target> -j`
* -j causes the compiler to use all available cores
* The target is used to either compile the debug or the optimized release build.
@ -70,153 +171,189 @@ git submodule update
* Target name: all
* Uncheck "Same as the target name"
* Uncheck "Use builder settings"
* As build command type: `make -j <target> WINDOWS=1`
6. Run build command by double clicking the created target or by right clicking
* As build command type: `cmake --build .`
* In the Behaviour tab, you can enable build acceleration
4. Run build command by double clicking the created target or by right clicking
the project folder and selecting Build Project.
## Debugging the software (when workstation is directly conncected to Q7S)
1. Assign static IP address to Q7S
* Open serial console of Q7S (Accessible via the micro-USB of the PIM, see also Q7S user maunal chapter 10.3)
* Baudrate 115200
* Login to Q7S:
* user: root
* pw: root
* Set IP address and netmask with
```sh
## TCF-Agent
1. On reboot, some steps have to be taken on the Q7S. Set static IP address and netmask
```sh
ifconfig eth0 192.168.133.10
ifconfig eth0 netmask 255.255.255.0
```
2. Connect Q7S to workstation via ethernet
3. Make sure the netmask of the ehternet interface of the workstation matches the netmask of the Q7S
* When IP address is set to 192.168.133.10 and the netmask is 255.255.255.0, an example IP address for the workstation
is 192.168.133.2
4. Run tcf-agent on Q7S
* Tcf-agent is not yet integrated in the rootfs of the Q7S. Therefore build tcf-agent manually
```sh
git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git
cd org.eclipse.tcf.agent/agent
make CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld MACHINE=arm NO_SSL=1 NO_UUID=1
```
2. `tcfagent` application should run automatically but this can be checked with
```sh
systemctl status tcfagent
```
* Transfer executable agent from org.eclipse.tcf.agent/agent/obj/GNU/Linux/arm/Debug to /tmp of Q7S
```sh
cd obj/GNU/Linux/arm/Debug
scp agent root@192.168.133.10:/tmp
```
* On Q7S
```sh
cd /tmp
chmod +x agent
```
* Run agent
```sh
./agent
```
5. In Xilinx SDK 2018.2 right click on project &rarr; Debug As &rarr; Debug Configurations
6. Right click Xilinx C/C++ applicaton (System Debugger) &rarr; New &rarr;
7. Set Debug Type to Linux Application Debug and Connectin to Linux Agent
8. Click New
9. Give connection a name
10. Set Host to static IP address of Q7S. e.g. 192.168.133.10
11. Test connection (This ensures the TCF Agent is running on the Q7S)
12. Select Application tab
* Project Name: eive_obsw
* Local File Path: Path to eiveobsw-linux.elf (in _bin\linux\devel)
* Remote File Path: /tmp/eive_obsw.elf
3. If the agent is not running, check whether `agent` is located inside `usr/bin`.
You can run it manually there. To perform auto-start on boot, have a look at the start-up
application section.
## Debugging the software via Flatsat PC
Open SSH connection to flatsat PC:
````
```sh
ssh eive@flatsat.eive.absatvirt.lw
```
or
```sh
ssh eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
````
To access the console of the Q7S run the following:
```
or
```sh
ssh eive@192.168.199.227
```
If the static IP address of the Q7S has already been set,
you can access it with ssh
```sh
ssh root@192.168.133.10
```
If this has not been done yet, you can access the serial
console of the Q7S like this to set it
```sh
picocom -b 115200 /dev/ttyUSB0
```
If the serial port is blocked for some reason, you can kill
the process using it with `q7s_kill`.
You can use `AltGr` + `X` to exit the picocom session.
To debug an application, first make sure a static IP address is assigned to the Q7S. Run ifconfig on the Q7S serial console.
````
```sh
ifconfig
````
```
Set IP address and netmask with
````
```sh
ifconfig eth0 192.168.133.10
ifconfig eth0 netmask 255.255.255.0
````
To launch application from Xilinx SDK setup port fowarding on the localhost.
````
ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
````
```
To launch application from Xilinx SDK setup port fowarding on the development machine
(not on the flatsat!)
```sh
ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t bash
```
This forwards any requests to localhost:1534 to the port 1534 of the Q7S with the IP address 192.168.133.10.
This needs to be done every time, so it is recommended to create an alias to do this quickly.
Note: When now setting up a debug session in the Xilinx SDK, the host must be set to localhost instead of the IP address
of the Q7S.
Note: When now setting up a debug session in the Xilinx SDK, the host must be set to localhost instead of the IP address of the Q7S.
## Transfering files via SCP
To transfer files from the local machine to the Q7S, use port forwarding
```sh
ssh -L 1535:192.168.133.10:22 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
```
Then you can copy an `example` file like this
```sh
scp -P 1535 example root@localhost:/tmp
```
Copying a file from Q7S to flatsat PC
````
scp -P 22 root@192.168.133.10:/tmp/kernel-config /tmp
````
From a windows machine files can be copied with putty tools
````
pscp -scp -P 22 eive@192.168.199.227:</directory-to-example-file/>/example-file </windows-machine-path/>
````
## Launching an application at start-up
## Launching an application after boot
Load the root partiton from the flash memory (there are to nor-flash memories and each flash holds two xdi images).
Note: It is not possible to modify the current loaded root partition.
Note: It is not possible to modify the currently loaded root partition, e.g. creating directories. To do this,
the parition needs to be mounted.
1. Disable write protection of the desired root partition
````
writeprotect 0 0 0 # unlocks nominal image on nor-flash 0
````
```sh
writeprotect 0 0 0 # unlocks nominal image on nor-flash 0
```
2. Mount the root partition
````
xsc_mount_copy 0 0 # Mounts the nominal image from nor-flash 0
````
3. Copy the executable to /bin/usr
```sh
xsc_mount_copy 0 0 # Mounts the nominal image from nor-flash 0
```
The mounted partition will be located inside the `/tmp` folder
3. Copy the executable to `/usr/bin`
4. Make sure the permissions to execute the application are set
````
chmod +x application
````
```sh
chmod +x application
```
5. Create systemd service in /lib/systemd/system. The following shows an example service.
````
cat > example.service
[Unit]
Description=Example Service
StartLimitIntervalSec=0
```sh
cat > example.service
[Unit]
Description=Example Service
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/usr/bin/application
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/usr/bin/application
[Install]
WantedBy=multi-user.target
````
[Install]
WantedBy=multi-user.target
```
6. Enable the service. This is normally done with systemctl enable. However, this is not possible when the service is
created for a mounted root partition. Therefore create a symlink as follows.
````
ln -s '/tmp/the-mounted-xdi-image/lib/systemd/system/example.service' '/tmp/the-mounted-xdi-image/etc/systemd/system/multi-user.target.wants/example.service'
````
```sh
ln -s '/tmp/the-mounted-xdi-image/lib/systemd/system/example.service' '/tmp/the-mounted-xdi-image/etc/systemd/system/multi-user.target.wants/example.service'
```
7. The modified root partition is written back when the partion is locked again.
````
writeprotect 0 0 1
````
```sh
writeprotect 0 0 1
```
8. Now verify the application start by booting from the modified image
````
xsc_boot_copy 0 0
````
```sh
xsc_boot_copy 0 0
````
9. After booting verify if the service is running
````
systemctl status example
````
```sh
systemctl status example
```
More detailed information about the used q7s commands can be found in the Q7S user manual.
### Bringing up CAN
````
ip link set can0 down
ip link set can0 type can loopback off
ip link set can0 up type can bitrate 1000000
````
```sh
ip link set can0 down
ip link set can0 type can loopback off
ip link set can0 up type can bitrate 1000000
```
Following command sends 8 bytes to device with id 99 (for petalinux)
````
cansend can0 -i99 99 88 77 11 33 11 22 99
@ -293,17 +430,6 @@ a permanent solution). If running the script before executing the binary does
not help or an warning is issue that the soft real time value is invalid,
the hard real-time limit of the system might not be high enough (see step 1).
## Building and running the software on a host system
The host build can be built with following command
```sh
make -f Makefile-Hosted all -j
```
If compiling on Windows, it is recommended to supply `WINDOWS=1` .
A release build can be built by using the `mission` target.
## Flight Software Framework (FSFW)
An EIVE fork of the FSFW is submodules into this repository.
@ -323,3 +449,134 @@ git merge upstream/master
Alternatively, changes from other upstreams (forks) and branches can be merged like that in
the same way.
## PCDU
Connect to serial console of P60 Dock
````
picocom -b 500000 /dev/ttyUSBx
````
General information
````
cmp ident
````
List parameter table:
x values: 1,2 or 4
````
param list x
````
Table 4 lists HK parameters
Changing parameters
First switch to table where parameter shall be changed (here table id is 1)
````
p60-dock # param mem 1
p60-dock # param set out_en[0] 1
p60-dock # param get out_en[0]
GET out_en[0] = 1
````
## Debugging the software (when workstation is directly conncected to Q7S)
1. Assign static IP address to Q7S
* Open serial console of Q7S (Accessible via the micro-USB of the PIM, see also Q7S user maunal chapter 10.3)
* Baudrate 115200
* Login to Q7S:
* user: root
* pw: root
2. Connect Q7S to workstation via ethernet
3. Make sure the netmask of the ehternet interface of the workstation matches the netmask of the Q7S
* When IP address is set to 192.168.133.10 and the netmask is 255.255.255.0, an example IP address for the workstation
is 192.168.133.2
4. Run tcf-agent on Q7S
* Tcf-agent is not yet integrated in the rootfs of the Q7S. Therefore build tcf-agent manually
```sh
git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git
cd org.eclipse.tcf.agent/agent
make CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld MACHINE=arm NO_SSL=1 NO_UUID=1
```
* Transfer executable agent from org.eclipse.tcf.agent/agent/obj/GNU/Linux/arm/Debug to /tmp of Q7S
```sh
cd obj/GNU/Linux/arm/Debug
scp agent root@192.168.133.10:/tmp
```
* On Q7S
```sh
cd /tmp
chmod +x agent
```
* Run agent
```sh
./agent
```
5. In Xilinx SDK 2018.2 right click on project &rarr; Debug As &rarr; Debug Configurations
6. Right click Xilinx C/C++ applicaton (System Debugger) &rarr; New &rarr;
7. Set Debug Type to Linux Application Debug and Connectin to Linux Agent
8. Click New
9. Give connection a name
10. Set Host to static IP address of Q7S. e.g. 192.168.133.10
11. Test connection (This ensures the TCF Agent is running on the Q7S)
12. Select Application tab
* Project Name: eive_obsw
* Local File Path: Path to eiveobsw-linux.elf (in _bin\linux\devel)
* 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
## Running the EIVE OBSW on a Raspberry Pi
Special section for running the EIVE OBSW on the Raspberry Pi.
The Raspberry Pi build uses the `bsp_rpi` BSP folder, and a very similar cross-compiler.
For running the software on a Raspberry Pi, it is recommended to follow the steps specified in
[the fsfw example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example/src/branch/mueller/master/doc/README-rpi.md#top)
and using the TCF agent to have a similar set-up process also required for the Q7S.
You should run the following command first on your Raspberry Pi
```sh
sudo apt-get install gpiod libgpiod-dev
```
to install the required GPIO libraries before cloning the system root folder.
## Special notes on Eclipse
When using Eclipse, there are two special build variables in the project properties
&rarr; C/C++ Build &rarr; Build Variables called `Q7S_SYSROOT` or `RPI_SYSROOT`. You can set
the sysroot path in those variables to get any additional includes like `gpiod.h` in the
Eclipse indexer.

10
bsp_hosted/CMakeLists.txt Normal file
View File

@ -0,0 +1,10 @@
target_sources(${TARGET_NAME} PUBLIC
InitMission.cpp
main.cpp
ObjectFactory.cpp
)
add_subdirectory(fsfwconfig)
add_subdirectory(boardconfig)

159
bsp_hosted/InitMission.cpp Normal file
View File

@ -0,0 +1,159 @@
#include "InitMission.h"
#include "ObjectFactory.h"
#include <OBSWConfig.h>
#include <fsfw/objectmanager/ObjectManagerIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include <fsfw/tasks/PeriodicTaskIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <mission/utility/InitMission.h>
#include <iostream>
#ifdef LINUX
ServiceInterfaceStream sif::debug("DEBUG");
ServiceInterfaceStream sif::info("INFO");
ServiceInterfaceStream sif::warning("WARNING");
ServiceInterfaceStream sif::error("ERROR", false, false, true);
#else
ServiceInterfaceStream sif::debug("DEBUG", true);
ServiceInterfaceStream sif::info("INFO", true);
ServiceInterfaceStream sif::warning("WARNING", true);
ServiceInterfaceStream sif::error("ERROR", true, false, true);
#endif
ObjectManagerIF *objectManager = nullptr;
void initmission::initMission() {
sif::info << "Building global objects.." << std::endl;
/* Instantiate global object manager and also create all objects */
objectManager = new ObjectManager(ObjectFactory::produce);
sif::info << "Initializing all objects.." << std::endl;
objectManager->initialize();
/* This function creates and starts all tasks */
initTasks();
}
void initmission::initTasks() {
TaskFactory* factory = TaskFactory::instance();
if(factory == nullptr) {
/* Should never happen ! */
return;
}
#if OBSW_PRINT_MISSED_DEADLINES == 1
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
#else
void (*missedDeadlineFunc) (void) = nullptr;
#endif
/* TMTC Distribution */
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
ReturnValue_t result = tmTcDistributor->addComponent(
objects::CCSDS_PACKET_DISTRIBUTOR);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Object add component failed" << std::endl;
}
/* UDP bridge */
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = udpBridgeTask->addComponent(objects::UDP_BRIDGE);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
}
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component UDP Polling failed" << std::endl;
}
/* PUS Services */
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
if(result != HasReturnvaluesIF::RETURN_OK){
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
}
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
}
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
}
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
}
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
}
PeriodicTaskIF* testTask = factory->createPeriodicTask(
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
#if OBSW_ADD_TEST_CODE == 1
result = testTask->addComponent(objects::TEST_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
}
#endif /* OBSW_ADD_TEST_CODE == 1 */
sif::info << "Starting tasks.." << std::endl;
tmTcDistributor->startTask();
udpBridgeTask->startTask();
udpPollingTask->startTask();
pusVerification->startTask();
pusEvents->startTask();
pusHighPrio->startTask();
pusMedPrio->startTask();
pusLowPrio->startTask();
#if OBSW_ADD_TEST_CODE == 1
testTask->startTask();
#endif /* OBSW_ADD_TEST_CODE == 1 */
sif::info << "Tasks started.." << std::endl;
}

View File

@ -1,7 +1,7 @@
#ifndef BSP_LINUX_INITMISSION_H_
#define BSP_LINUX_INITMISSION_H_
namespace InitMission {
namespace initmission {
void initMission();
void initTasks();
};

View File

@ -1,20 +1,27 @@
#include "ObjectFactory.h"
#include <objects/systemObjectList.h>
#include <OBSWConfig.h>
#include <objects/systemObjectList.h>
#include <tmtc/apid.h>
#include <tmtc/pusIds.h>
#include <fsfw/tmtcservices/CommandingServiceBase.h>
#include <fsfw/tmtcservices/PusServiceBase.h>
#include <fsfw/osal/linux/TmTcUnixUdpBridge.h>
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
#include <fsfw/osal/linux/TcUnixUdpPollingTask.h>
#include <mission/core/GenericFactory.h>
#include <mission/utility/TmFunnel.h>
void Factory::setStaticFrameworkObjectIds() {
#include <fsfw/osal/common/UdpTcPollingTask.h>
#include <fsfw/osal/common/UdpTmTcBridge.h>
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
#if OBSW_ADD_TEST_CODE == 1
#include <test/testtasks/TestTask.h>
#endif
void Factory::setStaticFrameworkObjectIds(){
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
PusServiceBase::packetDestination = objects::TM_FUNNEL;
@ -29,14 +36,13 @@ void Factory::setStaticFrameworkObjectIds() {
TmPacketStored::timeStamperId = objects::TIME_STAMPER;
}
void ObjectFactory::produce(){
Factory::setStaticFrameworkObjectIds();
ObjectFactory::produceGenericObjects();
new TmTcUnixUdpBridge(objects::UDP_BRIDGE,
objects::CCSDS_PACKET_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE);
new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
new UdpTmTcBridge(objects::UDP_BRIDGE,
objects::CCSDS_PACKET_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE);
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
}

View File

@ -0,0 +1,10 @@
target_sources(${TARGET_NAME} PRIVATE
print.c
)
target_include_directories(${TARGET_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,4 +1,5 @@
#include "print.h"
#include <stdio.h>
void printChar(const char* character, bool errStream) {

View File

@ -0,0 +1,8 @@
#ifndef BSP_HOSTED_BOARDCONFIG_PRINT_H_
#define BSP_HOSTED_BOARDCONFIG_PRINT_H_
#include <stdbool.h>
void printChar(const char* character, bool errStream);
#endif /* BSP_HOSTED_BOARDCONFIG_PRINT_H_ */

View File

@ -7,4 +7,5 @@ CSRC += $(wildcard $(CURRENTPATH)/boardconfig/*.c)
CXXSRC += $(wildcard $(CURRENTPATH)/comIF/*.cpp)
CSRC += $(wildcard $(CURRENTPATH)/comIF/*.c)
INCLUDES += $(CURRENTPATH)/boardconfig
INCLUDES += $(CURRENTPATH)/boardconfig
INCLUDES += $(CURRENTPATH)/fsfwconfig

View File

@ -8,6 +8,8 @@
// This only works on Linux
#ifdef LINUX
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#elif WIN32
#include <windows.h>
#include <strsafe.h>
@ -255,7 +257,7 @@ ReturnValue_t ArduinoComIF::sendMessage(uint8_t command,
encodedLen = sizeof(sendBuffer) - remainingLen;
#ifdef LINUX
ssize_t writtenlen = write(serialPort, sendBuffer, encodedLen);
ssize_t writtenlen = ::write(serialPort, sendBuffer, encodedLen);
if (writtenlen < 0) {
//we could try to find out what happened...
return RETURN_FAILED;
@ -286,7 +288,7 @@ void ArduinoComIF::handleSerialPortRx() {
rxBuffer.writeData(dataFromSerial, bytesRead);
uint8_t dataReceivedSoFar[rxBuffer.maxSize()];
uint8_t dataReceivedSoFar[rxBuffer.getMaxSize()];
uint32_t dataLenReceivedSoFar = 0;
@ -296,11 +298,11 @@ void ArduinoComIF::handleSerialPortRx() {
//look for STX
size_t firstSTXinRawData = 0;
while ((firstSTXinRawData < dataLenReceivedSoFar)
&& (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX)) {
&& (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR)) {
firstSTXinRawData++;
}
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX) {
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR) {
//there is no STX in our data, throw it away...
rxBuffer.deleteData(dataLenReceivedSoFar);
return;

View File

@ -1,4 +1,4 @@
#include "ArduinoCookie.h"
#include <bsp_hosted/comIF/ArduinoCookie.h>
ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address,
const size_t maxReplySize) :

View File

@ -0,0 +1,8 @@
target_sources(${TARGET_NAME} PUBLIC
ArduinoComIF.cpp
ArduinoCookie.cpp
)

View File

@ -0,0 +1,10 @@
target_sources(${TARGET_NAME} PRIVATE
ipc/MissionMessageTypes.cpp
)
target_include_directories(${TARGET_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,25 +1,27 @@
#ifndef CONFIG_FSFWCONFIG_H_
#define CONFIG_FSFWCONFIG_H_
#include <FSFWVersion.h>
#include <cstddef>
#include <cstdint>
//! Used to determine whether C++ ostreams are used
//! Those can lead to code bloat.
#define FSFW_CPP_OSTREAM_ENABLED 1
//! Used to determine whether C++ ostreams are used which can increase
//! the binary size significantly. If this is disabled,
//! the C stdio functions can be used alternatively
#define FSFW_CPP_OSTREAM_ENABLED 1
//! Reduced printout to further decrese code size
//! Be careful, this also turns off most diagnostic prinouts!
#define FSFW_REDUCED_PRINTOUT 0
//! More FSFW related printouts depending on level. Useful for development.
#define FSFW_VERBOSE_LEVEL 1
//! Can be used to enable debugging printouts for developing the FSFW
#define FSFW_DEBUGGING 0
//! Can be used to completely disable printouts, even the C stdio ones.
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0
#define FSFW_DISABLE_PRINTOUT 0
#endif
//! Defines the FIFO depth of each commanding service base which
//! also determines how many commands a CSB service can handle in one cycle
//! simulataneously. This will increase the required RAM for
//! each CSB service !
#define FSFW_CSB_FIFO_DEPTH 6
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
//! additional output which requires the translation files translateObjects
@ -27,18 +29,19 @@
#define FSFW_OBJ_EVENT_TRANSLATION 0
#if FSFW_OBJ_EVENT_TRANSLATION == 1
#define FSFW_DEBUG_OUTPUT 1
//! Specify whether info events are printed too.
#define FSFW_DEBUG_INFO 1
#include <translateObjects.h>
#include <translateEvents.h>
#include "objects/translateObjects.h"
#include "events/translateEvents.h"
#else
#define FSFW_DEBUG_OUTPUT 0
#endif
//! When using the newlib nano library, C99 support for stdio facilities
//! will not be provided. This define should be set to 1 if this is the case.
#define FSFW_NO_C99_IO 1
#define FSFW_NO_C99_IO 1
//! Specify whether a special mode store is used for Subsystem components.
#define FSFW_USE_MODESTORE 0
namespace fsfwconfig {
//! Default timestamp size. The default timestamp will be an eight byte CDC
@ -49,6 +52,14 @@ static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 8;
static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240;
static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120;
static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
//! Defines the FIFO depth of each commanding service base which
//! also determines how many commands a CSB service can handle in one cycle
//! simulataneously. This will increase the required RAM for
//! each CSB service !
static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124;
}
#endif /* CONFIG_FSFWCONFIG_H_ */

View File

@ -0,0 +1,32 @@
/**
* @brief This file can be used to add preprocessor define for conditional
* code inclusion exclusion or various other project constants and
* properties in one place.
*/
#ifndef CONFIG_OBSWCONFIG_H_
#define CONFIG_OBSWCONFIG_H_
#include "commonConfig.h"
#define OBSW_ADD_TEST_CODE 1
/* These defines should be disabled for mission code but are useful for
debugging. */
#define OBSW_VEBOSE_LEVEL 1
#ifdef __cplusplus
#include "objects/systemObjectList.h"
#include "events/subsystemIdRanges.h"
#include "returnvalues/classIds.h"
namespace config {
#endif
/* Add mission configuration flags here */
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_OBSWCONFIG_H_ */

View File

@ -3,8 +3,8 @@
const char* const SW_NAME = "eive";
#define SW_VERSION 0
#define SW_SUBVERSION 2
#define SW_VERSION 1
#define SW_SUBVERSION 0
#define SW_SUBSUBVERSION 0

View File

@ -0,0 +1,59 @@
#ifndef FSFWCONFIG_DEVICES_GPIOIDS_H_
#define FSFWCONFIG_DEVICES_GPIOIDS_H_
#include <linux/gpio/GpioIF.h>
namespace gpioIds {
enum gpioId_t {
HEATER_0,
HEATER_1,
HEATER_2,
HEATER_3,
HEATER_4,
HEATER_5,
HEATER_6,
HEATER_7,
DEPLSA1,
DEPLSA2,
MGM_0_LIS3_CS,
MGM_1_RM3100_CS,
GYRO_0_ADIS_CS,
GYRO_1_L3G_CS,
GYRO_2_L3G_CS,
MGM_2_LIS3_CS,
MGM_3_RM3100_CS,
TEST_ID_0,
TEST_ID_1,
RTD_IC3,
RTD_IC4,
RTD_IC5,
RTD_IC6,
RTD_IC7,
RTD_IC8,
RTD_IC9,
RTD_IC10,
RTD_IC11,
RTD_IC12,
RTD_IC13,
RTD_IC14,
RTD_IC15,
RTD_IC16,
RTD_IC17,
RTD_IC18,
SPI_MUX_BIT_1,
SPI_MUX_BIT_2,
SPI_MUX_BIT_3,
SPI_MUX_BIT_4,
SPI_MUX_BIT_5,
SPI_MUX_BIT_6
};
}
#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */

View File

@ -0,0 +1,58 @@
#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_
#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_
#include <OBSWConfig.h>
namespace pcduSwitches {
/* Switches are uint8_t datatype and go from 0 to 255 */
enum switcherList {
Q7S,
PAYLOAD_PCDU_CH1,
RW,
TCS_BOARD_8V_HEATER_IN,
SUS_REDUNDANT,
DEPLOYMENT_MECHANISM,
PAYLOAD_PCDU_CH6,
ACS_BOARD_SIDE_B,
PAYLOAD_CAMERA,
TCS_BOARD_3V3,
SYRLINKS,
STAR_TRACKER,
MGT,
SUS_NOMINAL,
SOLAR_CELL_EXP,
PLOC,
ACS_BORAD_SIDE_A,
NUMBER_OF_SWITCHES
};
static const uint8_t ON = 1;
static const uint8_t OFF = 0;
/* Output states after reboot of the PDUs */
static const uint8_t INIT_STATE_Q7S = ON;
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
static const uint8_t INIT_STATE_RW = OFF;
#if TE0720 == 1
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
#else
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
#endif
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF;
static const uint8_t INIT_STATE_SYRLINKS = OFF;
static const uint8_t INIT_STATE_STAR_TRACKER = OFF;
static const uint8_t INIT_STATE_MGT = OFF;
static const uint8_t INIT_STATE_SUS_NOMINAL = OFF;
static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF;
static const uint8_t INIT_STATE_PLOC = OFF;
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF;
}
#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */

View File

@ -10,7 +10,7 @@
*/
namespace SUBSYSTEM_ID {
enum: uint8_t {
SUBSYSTE_ID_START = FW_SUBSYSTEM_ID_RANGE,
SUBSYSTEM_ID_START = FW_SUBSYSTEM_ID_RANGE,
PUS_SERVICE_2,
PUS_SERVICE_3,
PUS_SERVICE_5,
@ -18,6 +18,7 @@ enum: uint8_t {
PUS_SERVICE_8,
PUS_SERVICE_23,
MGM_LIS3MDL,
MGM_RM3100,
DUMMY_DEVICE,
};

View File

@ -0,0 +1,7 @@
CXXSRC += $(wildcard $(CURRENTPATH)/cdatapool/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/ipc/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/objects/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/pollingsequence/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp)
INCLUDES += $(CURRENTPATH)

View File

@ -1,5 +1,5 @@
#include "MissionMessageTypes.h"
#include <fsfw/ipc/CommandMessage.h>
#include <hosted/fsfwconfig/ipc/MissionMessageTypes.h>
void messagetypes::clearMissionMessage(CommandMessage* message) {
switch(message->getMessageType()) {

View File

@ -11,7 +11,7 @@ class CommandMessage;
* <fsfw/ipc/FwMessageTypes.h>
* @param message Generic Command Message
*/
namespace messagetypes{
namespace messagetypes {
enum MESSAGE_TYPE {
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
};

View File

@ -0,0 +1,50 @@
#ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
#include <cstdint>
// The objects will be instantiated in the ID order
namespace objects {
enum sourceObjects: uint32_t {
/* First Byte 0x50-0x52 reserved for PUS Services **/
CCSDS_PACKET_DISTRIBUTOR = 0x50000100,
PUS_PACKET_DISTRIBUTOR = 0x50000200,
UDP_BRIDGE = 0x50000300,
UDP_POLLING_TASK = 0x50000400,
PUS_SERVICE_3 = 0x51000300,
PUS_SERVICE_5 = 0x51000400,
PUS_SERVICE_6 = 0x51000500,
PUS_SERVICE_8 = 0x51000800,
PUS_SERVICE_23 = 0x51002300,
PUS_SERVICE_201 = 0x51020100,
TM_FUNNEL = 0x52000002,
/* Test Task */
TEST_TASK = 0x42694269,
DUMMY_INTERFACE = 0xCAFECAFE,
DUMMY_HANDLER = 0x4400AFFE,
/* 0x44 ('D') for device handlers */
P60DOCK_HANDLER = 0x44000001,
PDU1_HANDLER = 0x44000002,
PDU2_HANDLER = 0x44000003,
ACU_HANDLER = 0x44000004,
TMP1075_HANDLER_1 = 0x44000005,
TMP1075_HANDLER_2 = 0x44000006,
MGM_0_LIS3_HANDLER = 0x4400007,
MGM_1_RM3100_HANDLER = 0x44000008,
MGM_2_LIS3_HANDLER = 0x44000009,
MGM_3_RM3100_HANDLER = 0x44000010,
GYRO_0_ADIS_HANDLER = 0x44000011,
GYRO_1_L3G_HANDLER = 0x44000012,
GYRO_2_L3G_HANDLER = 0x44000013,
/* 0x49 ('I') for Communication Interfaces **/
ARDUINO_COM_IF = 0x49000001
};
}
#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */

View File

@ -11,7 +11,8 @@
namespace CLASS_ID {
enum {
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
MGM_LIS3MDL
MGM_LIS3MDL,
MGM_RM3100
};
}

View File

@ -0,0 +1,19 @@
#ifndef FSFWCONFIG_TMTC_APID_H_
#define FSFWCONFIG_TMTC_APID_H_
#include <stdint.h>
/**
* Application Process Definition: entity, uniquely identified by an
* application process ID (APID), capable of generating telemetry source
* packets and receiving telecommand packets
*
* SOURCE APID: 0x73 / 115 / s
* APID is a 11 bit number
*/
namespace apid {
static const uint16_t EIVE_OBSW = 0x65;
}
#endif /* FSFWCONFIG_TMTC_APID_H_ */

View File

@ -0,0 +1,23 @@
#ifndef CONFIG_TMTC_PUSIDS_HPP_
#define CONFIG_TMTC_PUSIDS_HPP_
namespace pus {
enum Ids{
PUS_SERVICE_1 = 1,
PUS_SERVICE_2 = 2,
PUS_SERVICE_3 = 3,
PUS_SERVICE_3_PSB = 3,
PUS_SERVICE_5 = 5,
PUS_SERVICE_6 = 6,
PUS_SERVICE_8 = 8,
PUS_SERVICE_9 = 9,
PUS_SERVICE_17 = 17,
PUS_SERVICE_19 = 19,
PUS_SERVICE_20 = 20,
PUS_SERVICE_23 = 23,
PUS_SERVICE_200 = 200,
PUS_SERVICE_201 = 201,
};
};
#endif /* CONFIG_TMTC_PUSIDS_HPP_ */

View File

@ -1,7 +1,7 @@
#include <bsp_linux/InitMission.h>
#include <fsfw/tasks/TaskFactory.h>
#include <hosted/fsfwconfig/OBSWVersion.h>
#include "InitMission.h"
#include <OBSWVersion.h>
#include <fsfw/tasks/TaskFactory.h>
#include <iostream>
#ifdef WIN32
@ -24,7 +24,7 @@ int main(void)
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl;
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
InitMission::initMission();
initmission::initMission();
for(;;) {
// suspend main thread by sleeping it.

View File

@ -1,159 +0,0 @@
#include <bsp_linux/InitMission.h>
#include <bsp_linux/ObjectFactory.h>
#include <fsfw/objectmanager/ObjectManagerIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/datapool/DataPool.h>
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include <fsfw/tasks/PeriodicTaskIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfwconfig/objects/systemObjectList.h>
#include <fsfwconfig/OBSWConfig.h>
#include <iostream>
// This is configured for linux without \cr
#ifdef LINUX
ServiceInterfaceStream sif::debug("DEBUG");
ServiceInterfaceStream sif::info("INFO");
ServiceInterfaceStream sif::warning("WARNING");
ServiceInterfaceStream sif::error("ERROR", false, false, true);
#else
ServiceInterfaceStream sif::debug("DEBUG", true);
ServiceInterfaceStream sif::info("INFO", true);
ServiceInterfaceStream sif::warning("WARNING", true);
ServiceInterfaceStream sif::error("ERROR", true, false, true);
#endif
ObjectManagerIF *objectManager = nullptr;
//Initialize Data Pool
DataPool dataPool(nullptr);
void InitMission::initMission() {
sif::info << "Building global objects.." << std::endl;
/* Instantiate global object manager and also create all objects */
objectManager = new ObjectManager(ObjectFactory::produce);
sif::info << "Initializing all objects.." << std::endl;
objectManager->initialize();
/* This function creates and starts all tasks */
initTasks();
}
void InitMission::initTasks(){
/* TMTC Distribution */
PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()->
createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE,
0.100, nullptr);
ReturnValue_t result = TmTcDistributor->addComponent(
objects::CCSDS_PACKET_DISTRIBUTOR);
if(result!=HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = TmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
if(result!=HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = TmTcDistributor->addComponent(objects::TM_FUNNEL);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Object add component failed" << std::endl;
}
/* UDP bridge */
PeriodicTaskIF* UdpBridgeTask = TaskFactory::instance()->createPeriodicTask(
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE,
0.2, nullptr);
result = UdpBridgeTask->addComponent(objects::UDP_BRIDGE);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
}
PeriodicTaskIF* UdpPollingTask = TaskFactory::instance()->
createPeriodicTask("UDP_POLLING", 80,
PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr);
result = UdpPollingTask->addComponent(objects::UDP_POLLING_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component UDP Polling failed" << std::endl;
}
/* PUS Services */
PeriodicTaskIF* PusVerification = TaskFactory::instance()->
createPeriodicTask("PUS_VERIF_1", 40,
PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr);
result = PusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
PeriodicTaskIF* PusEvents = TaskFactory::instance()->
createPeriodicTask("PUS_VERIF_1", 60,
PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr);
result = PusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
PeriodicTaskIF* PusHighPrio = TaskFactory::instance()->
createPeriodicTask("PUS_HIGH_PRIO", 50,
PeriodicTaskIF::MINIMUM_STACK_SIZE,
0.200, nullptr);
result = PusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if(result!=HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = PusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
if(result!=HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
PeriodicTaskIF* PusMedPrio = TaskFactory::instance()->
createPeriodicTask("PUS_HIGH_PRIO", 40,
PeriodicTaskIF::MINIMUM_STACK_SIZE,
0.8, nullptr);
result = PusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
if(result!=HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = PusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
if(result!=HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
PeriodicTaskIF* PusLowPrio = TaskFactory::instance()->
createPeriodicTask("PUSB", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE,
1.6, nullptr);
result = PusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
if(result!=HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
#if ADD_TEST_CODE == 1
FixedTimeslotTaskIF* TestTimeslotTask = TaskFactory::instance()->
createFixedTimeslotTask("PST_TEST_TASK", 10,
PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
result = pst::pollingSequenceTestFunction(TestTimeslotTask);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::createTasks: Test PST initialization "
<< "failed!" << std::endl;
}
#endif
//Main thread sleep
sif::info << "Starting tasks.." << std::endl;
TmTcDistributor->startTask();
UdpBridgeTask->startTask();
UdpPollingTask->startTask();
PusVerification->startTask();
PusEvents->startTask();
PusHighPrio->startTask();
PusMedPrio->startTask();
PusLowPrio->startTask();
#if ADD_TEST_CODE == 1
TestTimeslotTask->startTask();
#endif
sif::info << "Tasks started.." << std::endl;
}

View File

@ -1,4 +0,0 @@
CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp)
CSRC += $(wildcard $(CURRENTPATH)/*.c)
CSRC += $(wildcard $(CURRENTPATH)/boardconfig/*.c)

View File

@ -1,324 +0,0 @@
#include "ArduinoCookie.h"
#include "ArduinoComIF.h"
#include <fsfw/globalfunctions/DleEncoder.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <fsfw/globalfunctions/CRC.h>
#include <termios.h>
ArduinoCommInterface::ArduinoCommInterface(object_id_t setObjectId,
const char *serialDevice) :
spiMap(MAX_NUMBER_OF_SPI_DEVICES), rxBuffer(
MAX_PACKET_SIZE * MAX_NUMBER_OF_SPI_DEVICES*10, true), SystemObject(setObjectId) {
initialized = false;
serialPort = ::open("/dev/ttyUSB0", O_RDWR);
if (serialPort < 0) {
//configuration error
printf("Error %i from open: %s\n", errno, strerror(errno));
return;
}
struct termios tty;
memset(&tty, 0, sizeof tty);
// Read in existing settings, and handle any error
if (tcgetattr(serialPort, &tty) != 0) {
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
return;
}
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
tty.c_cflag |= CS8; // 8 bits per byte
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
tty.c_lflag &= ~ICANON; //Disable Canonical Mode
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
tty.c_cc[VTIME] = 0; // Non Blocking
tty.c_cc[VMIN] = 0;
cfsetispeed(&tty, B9600); //Baudrate
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
//printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
return;
}
initialized = true;
}
ArduinoCommInterface::~ArduinoCommInterface() {
::close(serialPort);
}
ReturnValue_t ArduinoCommInterface::open(Cookie **cookie, uint32_t address,
uint32_t maxReplyLen) {
//This is a hack, will be gone with https://egit.irs.uni-stuttgart.de/fsfw/fsfw/issues/19
switch ((address >> 8) & 0xff) {
case 0:
*cookie = new ArduinoCookie(ArduinoCookie::SPI, address, maxReplyLen);
spiMap.insert(address, (ArduinoCookie*) *cookie); //Yes, I *do* know that it is an ArduinoSpiCookie, I just new'd it
break;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ArduinoCommInterface::reOpen(Cookie *cookie, uint32_t address,
uint32_t maxReplyLen) {
//too lazy right now will be irrelevant with https://egit.irs.uni-stuttgart.de/fsfw/fsfw/issues/19
return HasReturnvaluesIF::RETURN_FAILED;
}
void ArduinoCommInterface::close(Cookie *cookie) {
//too lazy as well, find the correct Map, delete it there, then the cookie...
}
ReturnValue_t ArduinoCommInterface::sendMessage(Cookie *cookie, uint8_t *data,
uint32_t len) {
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie*>(cookie);
if (arduinoCookie == NULL) {
return INVALID_COOKIE_TYPE;
}
return sendMessage(arduinoCookie->command, arduinoCookie->address, data,
len);
}
ReturnValue_t ArduinoCommInterface::getSendSuccess(Cookie *cookie) {
return RETURN_OK;
}
ReturnValue_t ArduinoCommInterface::requestReceiveMessage(Cookie *cookie) {
return RETURN_OK;
}
ReturnValue_t ArduinoCommInterface::readReceivedMessage(Cookie *cookie,
uint8_t **buffer, uint32_t *size) {
handleSerialPortRx();
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie*>(cookie);
if (arduinoCookie == NULL) {
return INVALID_COOKIE_TYPE;
}
*buffer = arduinoCookie->replyBuffer;
*size = arduinoCookie->receivedDataLen;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ArduinoCommInterface::setAddress(Cookie *cookie,
uint32_t address) {
//not implemented
return RETURN_FAILED;
}
uint32_t ArduinoCommInterface::getAddress(Cookie *cookie) {
//not implemented
return 0;
}
ReturnValue_t ArduinoCommInterface::setParameter(Cookie *cookie,
uint32_t parameter) {
//not implemented
return RETURN_FAILED;
}
uint32_t ArduinoCommInterface::getParameter(Cookie *cookie) {
//not implemented
return 0;
}
ReturnValue_t ArduinoCommInterface::sendMessage(uint8_t command,
uint8_t address, const uint8_t *data, size_t dataLen) {
if (dataLen > UINT16_MAX) {
return TOO_MUCH_DATA;
}
//being conservative here
uint8_t sendBuffer[(dataLen + 6) * 2 + 2];
sendBuffer[0] = DleEncoder::STX;
uint8_t *currentPosition = sendBuffer + 1;
size_t remainingLen = sizeof(sendBuffer) - 1;
uint32_t encodedLen;
ReturnValue_t result = DleEncoder::encode(&command, 1, currentPosition,
remainingLen, &encodedLen, false);
if (result != RETURN_OK) {
return result;
}
currentPosition += encodedLen;
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
result = DleEncoder::encode(&address, 1, currentPosition, remainingLen,
&encodedLen, false);
if (result != RETURN_OK) {
return result;
}
currentPosition += encodedLen;
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
uint8_t temporaryBuffer[2];
//note to Lukas: yes we _could_ use Serialize here, but for 16 bit it is a bit too much...
temporaryBuffer[0] = dataLen >> 8; //we checked dataLen above
temporaryBuffer[1] = dataLen;
result = DleEncoder::encode(temporaryBuffer, 2, currentPosition,
remainingLen, &encodedLen, false);
if (result != RETURN_OK) {
return result;
}
currentPosition += encodedLen;
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
//encoding the actual data
result = DleEncoder::encode(data, dataLen, currentPosition, remainingLen,
&encodedLen, false);
if (result != RETURN_OK) {
return result;
}
currentPosition += encodedLen;
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
uint16_t crc = CRC::crc16ccitt(&command, 1);
crc = CRC::crc16ccitt(&address, 1, crc);
//fortunately the length is still there
crc = CRC::crc16ccitt(temporaryBuffer, 2, crc);
crc = CRC::crc16ccitt(data, dataLen, crc);
temporaryBuffer[0] = crc >> 8;
temporaryBuffer[1] = crc;
result = DleEncoder::encode(temporaryBuffer, 2, currentPosition,
remainingLen, &encodedLen, false);
if (result != RETURN_OK) {
return result;
}
currentPosition += encodedLen;
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
if (remainingLen > 0) {
*currentPosition = DleEncoder::ETX;
}
remainingLen -= 1;
encodedLen = sizeof(sendBuffer) - remainingLen;
ssize_t writtenlen = write(serialPort, sendBuffer, encodedLen);
if (writtenlen < 0) {
//we could try to find out what happened...
return RETURN_FAILED;
}
if (writtenlen != encodedLen) {
//the OS failed us, we do not try to block until everything is written, as
//we can not block the whole system here
return RETURN_FAILED;
}
return RETURN_OK;
}
void ArduinoCommInterface::handleSerialPortRx() {
uint32_t availableSpace = rxBuffer.availableWriteSpace();
uint8_t dataFromSerial[availableSpace];
ssize_t bytesRead = read(serialPort, dataFromSerial,
sizeof(dataFromSerial));
if (bytesRead < 0) {
return;
}
rxBuffer.writeData(dataFromSerial, bytesRead);
uint8_t dataReceivedSoFar[rxBuffer.maxSize()];
uint32_t dataLenReceivedSoFar = 0;
rxBuffer.readData(dataReceivedSoFar, sizeof(dataReceivedSoFar), true,
&dataLenReceivedSoFar);
//look for STX
size_t firstSTXinRawData = 0;
while ((firstSTXinRawData < dataLenReceivedSoFar)
&& (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX)) {
firstSTXinRawData++;
}
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX) {
//there is no STX in our data, throw it away...
rxBuffer.deleteData(dataLenReceivedSoFar);
return;
}
uint8_t packet[MAX_PACKET_SIZE];
uint32_t packetLen;
uint32_t readSize;
ReturnValue_t result = DleEncoder::decode(
dataReceivedSoFar + firstSTXinRawData,
dataLenReceivedSoFar - firstSTXinRawData, &readSize, packet,
sizeof(packet), &packetLen);
size_t toDelete = firstSTXinRawData;
if (result == HasReturnvaluesIF::RETURN_OK) {
handlePacket(packet, packetLen);
//after handling the packet, we can delete it from the raw stream, it has been copied to packet
toDelete += readSize;
}
//remove Data which was processed
rxBuffer.deleteData(toDelete);
}
void ArduinoCommInterface::handlePacket(uint8_t *packet, size_t packetLen) {
uint16_t crc = CRC::crc16ccitt(packet, packetLen);
if (crc != 0) {
//CRC error
return;
}
uint8_t command = packet[0];
uint8_t address = packet[1];
uint16_t size = (packet[2] << 8) + packet[3];
if (size != packetLen - 6) {
//Invalid Length
return;
}
switch (command) {
case ArduinoCookie::SPI: {
ArduinoCookie **itsComplicated;
ReturnValue_t result = spiMap.find(address, &itsComplicated);
if (result != RETURN_OK) {
//we do no know this address
return;
}
ArduinoCookie *theActualCookie = *itsComplicated;
if (packetLen > theActualCookie->maxReplySize + 6) {
packetLen = theActualCookie->maxReplySize + 6;
}
memcpy(theActualCookie->replyBuffer, packet + 4, packetLen - 6);
theActualCookie->receivedDataLen = packetLen - 6;
}
break;
default:
return;
}
}

View File

@ -1,73 +0,0 @@
//#ifndef MISSION_ARDUINOCOMMINTERFACE_H_
//#define MISSION_ARDUINOCOMMINTERFACE_H_
//
//#include <bits/stdint-uintn.h>
//#include <framework/container/FixedMap.h>
//#include <framework/container/SimpleRingBuffer.h>
//#include <framework/devicehandlers/DeviceCommunicationIF.h>
//#include <framework/returnvalues/HasReturnvaluesIF.h>
//#include <stddef.h>
//
//#include "../../framework/objectmanager/SystemObject.h"
//#include "ArduinoCookie.h"
//
////Forward declaration, so users don't peek
//class ArduinoCookie;
//
//class ArduinoComIF: public SystemObject,
// public DeviceCommunicationIF {
//public:
// static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8;
// static const uint8_t MAX_PACKET_SIZE = 64;
//
// static const uint8_t COMMAND_INVALID = -1;
// static const uint8_t COMMAND_SPI = 1;
//
// ArduinoComIF(object_id_t setObjectId, const char *serialDevice);
// virtual ~ArduinoComIF();
//
// virtual ReturnValue_t open(Cookie **cookie, uint32_t address,
// uint32_t maxReplyLen);
//
// virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address,
// uint32_t maxReplyLen);
//
// virtual void close(Cookie *cookie);
//
// //SHOULDDO can data be const?
// virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data,
// uint32_t len);
//
// virtual ReturnValue_t getSendSuccess(Cookie *cookie);
//
// virtual ReturnValue_t requestReceiveMessage(Cookie *cookie);
//
// virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer,
// uint32_t *size);
//
// virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address);
//
// virtual uint32_t getAddress(Cookie *cookie);
//
// virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter);
//
// virtual uint32_t getParameter(Cookie *cookie);
//private:
// //remembering if the initialization in the ctor worked
// //if not, all calls are disabled
// bool initialized;
// int serialPort;
// //used to know where to put the data if a reply is received
// FixedMap<uint8_t, ArduinoCookie*> spiMap;
//
// SimpleRingBuffer rxBuffer;
//
// ReturnValue_t sendMessage(uint8_t command, uint8_t address,
// const uint8_t *data, size_t dataLen);
//
// void handleSerialPortRx();
//
// void handlePacket(uint8_t *packet, size_t packetLen);
//};
//
//#endif /* MISSION_ARDUINOCOMMINTERFACE_H_ */

View File

@ -1,12 +0,0 @@
//#include <mission/Arduino/ArduinoCookie.h>
//
//ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address,
// size_t maxReplySize) :
// command(protocol), address(address), receivedDataLen(0), maxReplySize(
// maxReplySize) {
// replyBuffer = new uint8_t[maxReplySize];
//}
//
//ArduinoCookie::~ArduinoCookie() {
// delete[] replyBuffer;
//}

View File

@ -1,25 +0,0 @@
//#ifndef MISSION_ARDUINO_ARDUINOCOOKIE_H_
//#define MISSION_ARDUINO_ARDUINOCOOKIE_H_
//
//#include <framework/devicehandlers/Cookie.h>
//
//#include <stdint.h>
//#include <stdlib.h>
//
//class ArduinoCookie: public Cookie {
//public:
// enum Protocol_t {
// INVALID = 0, SPI = 1
// };
// ArduinoCookie(Protocol_t protocol, uint8_t address, size_t maxReplySize);
// virtual ~ArduinoCookie();
//
// uint8_t command;
// uint8_t address;
// uint8_t *replyBuffer;
// size_t receivedDataLen;
// size_t maxReplySize;
//
//};
//
//#endif /* MISSION_ARDUINO_ARDUINOCOOKIE_H_ */

14
bsp_q7s/CMakeLists.txt Normal file
View File

@ -0,0 +1,14 @@
target_sources(${TARGET_NAME} PUBLIC
InitMission.cpp
main.cpp
ObjectFactory.cpp
)
add_subdirectory(boardconfig)
add_subdirectory(comIF)
add_subdirectory(devices)
add_subdirectory(boardtest)
add_subdirectory(gpio)

205
bsp_q7s/InitMission.cpp Normal file
View File

@ -0,0 +1,205 @@
#include "InitMission.h"
#include "ObjectFactory.h"
#include <OBSWConfig.h>
#include <mission/utility/InitMission.h>
#include <fsfw/objectmanager/ObjectManagerIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include <fsfw/tasks/PeriodicTaskIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfwconfig/pollingsequence/pollingSequenceFactory.h>
#include <iostream>
/* This is configured for linux without CR */
#ifdef LINUX
ServiceInterfaceStream sif::debug("DEBUG");
ServiceInterfaceStream sif::info("INFO");
ServiceInterfaceStream sif::warning("WARNING");
ServiceInterfaceStream sif::error("ERROR", false, false, true);
#else
ServiceInterfaceStream sif::debug("DEBUG", true);
ServiceInterfaceStream sif::info("INFO", true);
ServiceInterfaceStream sif::warning("WARNING", true);
ServiceInterfaceStream sif::error("ERROR", true, false, true);
#endif
ObjectManagerIF *objectManager = nullptr;
void initmission::initMission() {
sif::info << "Building global objects.." << std::endl;
/* Instantiate global object manager and also create all objects */
objectManager = new ObjectManager(ObjectFactory::produce);
sif::info << "Initializing all objects.." << std::endl;
objectManager->initialize();
/* This function creates and starts all tasks */
initTasks();
}
void initmission::initTasks() {
TaskFactory* factory = TaskFactory::instance();
if(factory == nullptr) {
/* Should never happen ! */
return;
}
#if OBSW_PRINT_MISSED_DEADLINES == 1
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
#else
void (*missedDeadlineFunc) (void) = nullptr;
#endif
/* TMTC Distribution */
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
ReturnValue_t result = tmTcDistributor->addComponent(
objects::CCSDS_PACKET_DISTRIBUTOR);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR);
}
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR);
}
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL);
}
/* UDP bridge */
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = udpBridgeTask->addComponent(objects::UDP_BRIDGE);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE);
}
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK);
}
/* PUS Services */
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION);
}
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
}
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
}
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT);
}
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING);
if(result!=HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS);
}
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST);
}
//TODO: Add handling of missed deadlines
/* Polling Sequence Table Default */
#if Q7S_ADD_SPI_TEST == 0
FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask(
"PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0,
missedDeadlineFunc);
result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
}
#endif
#if TE0720 == 0
FixedTimeslotTaskIF* gomSpacePstTask = factory->
createFixedTimeslotTask("GS_PST_TASK", 50,
PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, missedDeadlineFunc);
result = pst::gomspacePstInit(gomSpacePstTask);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl;
}
#endif
#if OBSW_ADD_TEST_CODE == 1
PeriodicTaskIF* testTask = factory->createPeriodicTask(
"TEST_TASK", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc);
result = testTask->addComponent(objects::TEST_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
}
#if Q7S_ADD_SPI_TEST == 1
result = testTask->addComponent(objects::SPI_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
}
#endif
#endif /* OBSW_ADD_TEST_CODE == 1 */
#if TE0720 == 1 && TEST_LIBGPIOD == 1
result = testTask->addComponent(objects::LIBGPIOD_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
}
#endif /* TE0720 == 1 && TEST_LIBGPIOD == 1 */
sif::info << "Starting tasks.." << std::endl;
tmTcDistributor->startTask();
udpBridgeTask->startTask();
udpPollingTask->startTask();
#if TE0720 == 0
gomSpacePstTask->startTask();
#endif
#if Q7S_ADD_SPI_TEST == 0
pollingSequenceTableTaskDefault->startTask();
#endif
pusVerification->startTask();
pusEvents->startTask();
pusHighPrio->startTask();
pusMedPrio->startTask();
pusLowPrio->startTask();
#if OBSW_ADD_TEST_CODE == 1
testTask->startTask();
#endif
sif::info << "Tasks started.." << std::endl;
}

9
bsp_q7s/InitMission.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef BSP_Q7S_INITMISSION_H_
#define BSP_Q7S_INITMISSION_H_
namespace initmission {
void initMission();
void initTasks();
};
#endif /* BSP_Q7S_INITMISSION_H_ */

439
bsp_q7s/ObjectFactory.cpp Normal file
View File

@ -0,0 +1,439 @@
#include "ObjectFactory.h"
#include <OBSWConfig.h>
#include <tmtc/apid.h>
#include <devices/addresses.h>
#include <devices/gpioIds.h>
#include <tmtc/pusIds.h>
#include <devices/powerSwitcherList.h>
#include <devices/spi.h>
#include <bsp_q7s/devices/HeaterHandler.h>
#include <bsp_q7s/devices/SolarArrayDeploymentHandler.h>
#include <bsp_q7s/gpio/gpioCallbacks.h>
#include <mission/core/GenericFactory.h>
#include <mission/devices/PDU1Handler.h>
#include <mission/devices/PDU2Handler.h>
#include <mission/devices/ACUHandler.h>
#include <mission/devices/PCDUHandler.h>
#include <mission/devices/P60DockHandler.h>
#include <mission/devices/Tmp1075Handler.h>
#include <mission/devices/Max31865PT1000Handler.h>
#include <mission/devices/IMTQHandler.h>
#include <mission/devices/devicedefinitions/Max31865Definitions.h>
#include <mission/devices/SyrlinksHkHandler.h>
#include <mission/devices/MGMHandlerLIS3MDL.h>
#include <mission/devices/MGMHandlerRM3100.h>
#include <mission/devices/GyroL3GD20Handler.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include <mission/devices/devicedefinitions/SyrlinksDefinitions.h>
#include <mission/utility/TmFunnel.h>
#include <linux/csp/CspCookie.h>
#include <linux/csp/CspComIF.h>
#include <linux/uart/UartComIF.h>
#include <linux/uart/UartCookie.h>
#include <fsfw_hal/linux/i2c/I2cCookie.h>
#include <fsfw_hal/linux/i2c/I2cComIF.h>
#include <fsfw_hal/linux/spi/SpiCookie.h>
#include <fsfw_hal/linux/spi/SpiComIF.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <fsfw_hal/common/gpio/GpioCookie.h>
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
#include <fsfw/tmtcservices/CommandingServiceBase.h>
#include <fsfw/tmtcservices/PusServiceBase.h>
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
/* UDP server includes */
#include <fsfw/osal/common/UdpTmTcBridge.h>
#include <fsfw/osal/common/UdpTcPollingTask.h>
#include <linux/boardtest/SpiTestClass.h>
#if TEST_LIBGPIOD == 1
#include <linux/boardtest/LibgpiodTest.h>
#endif
void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
PusServiceBase::packetDestination = objects::TM_FUNNEL;
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
TmFunnel::downlinkDestination = objects::UDP_BRIDGE;
// No storage object for now.
TmFunnel::storageDestination = objects::NO_OBJECT;
LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
}
void ObjectFactory::produce(){
Factory::setStaticFrameworkObjectIds();
ObjectFactory::produceGenericObjects();
#if TE0720 == 1
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
#else
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
#endif
LinuxLibgpioIF* gpioComIF = new LinuxLibgpioIF(objects::GPIO_IF);
/* Communication interfaces */
new CspComIF(objects::CSP_COM_IF);
new I2cComIF(objects::I2C_COM_IF);
new UartComIF(objects::UART_COM_IF);
#if Q7S_ADD_SPI_TEST == 0
new SpiComIF(objects::SPI_COM_IF, gpioComIF);
#endif
/* Temperature sensors */
Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler(
objects::TMP1075_HANDLER_1, objects::I2C_COM_IF,
i2cCookieTmp1075tcs1);
tmp1075Handler_1->setStartUpImmediately();
Tmp1075Handler* tmp1075Handler_2 = new Tmp1075Handler(
objects::TMP1075_HANDLER_2, objects::I2C_COM_IF,
i2cCookieTmp1075tcs2);
tmp1075Handler_2->setStartUpImmediately();
GpioCookie* heaterGpiosCookie = new GpioCookie;
#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 */
P60DockHandler* p60dockhandler = new P60DockHandler(objects::P60DOCK_HANDLER,
objects::CSP_COM_IF, p60DockCspCookie);
PDU1Handler* pdu1handler = new PDU1Handler(objects::PDU1_HANDLER,
objects::CSP_COM_IF, pdu1CspCookie);
PDU2Handler* pdu2handler = new PDU2Handler(objects::PDU2_HANDLER,
objects::CSP_COM_IF, pdu2CspCookie);
ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER,
objects::CSP_COM_IF, acuCspCookie);
new PCDUHandler(objects::PCDU_HANDLER, 50);
/**
* Setting PCDU devices to mode normal immediately after start up because PCDU is always
* running.
*/
/** For now this needs to be commented out because there is no PCDU connected to the OBC */
// p60dockhandler->setModeNormal();
// pdu1handler->setModeNormal();
// pdu2handler->setModeNormal();
// acuhandler->setModeNormal();
(void) p60dockhandler;
(void) pdu1handler;
(void) pdu2handler;
(void) acuhandler;
#if OBSW_ADD_ACS_BOARD == 1
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
GpiodRegular* gpio = nullptr;
gpio = new GpiodRegular(std::string("gpiochip5"), 1, std::string("CS_GYRO_1_ADIS"),
gpio::OUT, gpio::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
gpio = new GpiodRegular(std::string("gpiochip5"), 7, std::string("CS_GYRO_2_L3G"),
gpio::OUT, gpio::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
gpio = new GpiodRegular(std::string("gpiochip5"), 3, std::string("CS_GYRO_3_L3G"),
gpio::OUT, gpio::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_L3G_CS, gpio);
gpio = new GpiodRegular(std::string("gpiochip5"), 5, std::string("CS_MGM_0_LIS3_A"),
gpio::OUT, gpio::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
gpio = new GpiodRegular(std::string("gpiochip5"), 17, std::string("CS_MGM_1_RM3100_A"),
gpio::OUT, gpio::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
gpio = new GpiodRegular(std::string("gpiochip6"), 0, std::string("CS_MGM_2_LIS3_B"),
gpio::OUT, gpio::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
gpio = new GpiodRegular(std::string("gpiochip5"), 10, std::string("CS_MGM_3_RM3100_B"),
gpio::OUT, gpio::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
gpioComIF->addGpios(gpioCookieAcsBoard);
std::string spiDev = "/dev/spidev2.0";
SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
auto mgmLis3Handler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER,
objects::SPI_COM_IF, spiCookie);
mgmLis3Handler->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev,
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
auto mgmLis3Handler2 = new MGMHandlerLIS3MDL(objects::MGM_2_LIS3_HANDLER,
objects::SPI_COM_IF, spiCookie);
mgmLis3Handler2->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev,
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
auto mgmRm3100Handler = new MGMHandlerRM3100(objects::MGM_1_RM3100_HANDLER,
objects::SPI_COM_IF, spiCookie);
mgmRm3100Handler->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev,
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF,
spiCookie);
gyroL3gHandler->setStartUpImmediately();
#endif
/* Pin H2-11 on stack connector */
GpiodRegular* gpioConfigHeater0 = new GpiodRegular(std::string("gpiochip7"), 6,
std::string("Heater0"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0);
/* Pin H2-12 on stack connector */
GpiodRegular* gpioConfigHeater1 = new GpiodRegular(std::string("gpiochip7"), 12,
std::string("Heater1"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpioConfigHeater1);
/* Pin H2-13 on stack connector */
GpiodRegular* gpioConfigHeater2 = new GpiodRegular(std::string("gpiochip7"), 7,
std::string("Heater2"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpioConfigHeater2);
GpiodRegular* gpioConfigHeater3 = new GpiodRegular(std::string("gpiochip7"), 5,
std::string("Heater3"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpioConfigHeater3);
GpiodRegular* gpioConfigHeater4 = new GpiodRegular(std::string("gpiochip7"), 3,
std::string("Heater4"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpioConfigHeater4);
GpiodRegular* gpioConfigHeater5 = new GpiodRegular(std::string("gpiochip7"), 0,
std::string("Heater5"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpioConfigHeater5);
GpiodRegular* gpioConfigHeater6 = new GpiodRegular(std::string("gpiochip7"), 1,
std::string("Heater6"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpioConfigHeater6);
GpiodRegular* gpioConfigHeater7 = new GpiodRegular(std::string("gpiochip7"), 11,
std::string("Heater7"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpioConfigHeater7);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie,
objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN);
GpioCookie* solarArrayDeplCookie = new GpioCookie;
GpiodRegular* gpioConfigDeplSA0 = new GpiodRegular(std::string("gpiochip7"), 4,
std::string("DeplSA1"), gpio::OUT, 0);
solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpioConfigDeplSA0);
GpiodRegular* gpioConfigDeplSA1 = new GpiodRegular(std::string("gpiochip7"), 2,
std::string("DeplSA2"), gpio::OUT, 0);
solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpioConfigDeplSA1);
//TODO: Find out burn time. For now set to 1000 ms.
new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF,
solarArrayDeplCookie, objects::PCDU_HANDLER, pcduSwitches::DEPLOYMENT_MECHANISM,
gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000);
UartCookie* syrlinksUartCookie = new UartCookie(
std::string("/dev/ttyUL0"), 38400, SYRLINKS::MAX_REPLY_SIZE);
syrlinksUartCookie->setParityEven();
SyrlinksHkHandler* syrlinksHkHandler = new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER,
objects::UART_COM_IF, syrlinksUartCookie);
syrlinksHkHandler->setModeNormal();
#if Q7S_ADD_RTD_DEVICES == 1
GpioCookie* rtdGpioCookie = new GpioCookie;
gpioCallbacks::initTcsBoardDecoder(gpioComIF);
GpioCallback* gpioRtdIc3 = new GpioCallback(std::string("Chip select RTD IC3"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC3, gpioRtdIc3);
GpioCallback* gpioRtdIc4 = new GpioCallback(std::string("Chip select RTD IC4"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC4, gpioRtdIc4);
GpioCallback* gpioRtdIc5 = new GpioCallback(std::string("Chip select RTD IC5"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC5, gpioRtdIc5);
GpioCallback* gpioRtdIc6 = new GpioCallback(std::string("Chip select RTD IC6"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC6, gpioRtdIc6);
GpioCallback* gpioRtdIc7 = new GpioCallback(std::string("Chip select RTD IC7"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC7, gpioRtdIc7);
GpioCallback* gpioRtdIc8 = new GpioCallback(std::string("Chip select RTD IC8"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC8, gpioRtdIc8);
GpioCallback* gpioRtdIc9 = new GpioCallback(std::string("Chip select RTD IC9"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC9, gpioRtdIc9);
GpioCallback* gpioRtdIc10 = new GpioCallback(std::string("Chip select RTD IC10"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC10, gpioRtdIc10);
GpioCallback* gpioRtdIc11 = new GpioCallback(std::string("Chip select RTD IC11"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC11, gpioRtdIc11);
GpioCallback* gpioRtdIc12 = new GpioCallback(std::string("Chip select RTD IC12"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC12, gpioRtdIc12);
GpioCallback* gpioRtdIc13 = new GpioCallback(std::string("Chip select RTD IC13"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC13, gpioRtdIc13);
GpioCallback* gpioRtdIc14 = new GpioCallback(std::string("Chip select RTD IC14"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC14, gpioRtdIc14);
GpioCallback* gpioRtdIc15 = new GpioCallback(std::string("Chip select RTD IC15"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC15, gpioRtdIc15);
GpioCallback* gpioRtdIc16 = new GpioCallback(std::string("Chip select RTD IC16"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC16, gpioRtdIc16);
GpioCallback* gpioRtdIc17 = new GpioCallback(std::string("Chip select RTD IC17"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC17, gpioRtdIc17);
GpioCallback* gpioRtdIc18 = new GpioCallback(std::string("Chip select RTD IC18"), gpio::OUT, 1,
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC18, gpioRtdIc18);
gpioComIF->addGpios(rtdGpioCookie);
SpiCookie* spiRtdIc3 = new SpiCookie(addresses::RTD_IC3, gpioIds::RTD_IC3,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc4 = new SpiCookie(addresses::RTD_IC4, gpioIds::RTD_IC4,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc5 = new SpiCookie(addresses::RTD_IC5, gpioIds::RTD_IC5,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc6 = new SpiCookie(addresses::RTD_IC6, gpioIds::RTD_IC6,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc7 = new SpiCookie(addresses::RTD_IC7, gpioIds::RTD_IC7,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc8 = new SpiCookie(addresses::RTD_IC8, gpioIds::RTD_IC8,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc9 = new SpiCookie(addresses::RTD_IC9, gpioIds::RTD_IC9,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc10 = new SpiCookie(addresses::RTD_IC10, gpioIds::RTD_IC10,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc11 = new SpiCookie(addresses::RTD_IC11, gpioIds::RTD_IC11,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc12 = new SpiCookie(addresses::RTD_IC12, gpioIds::RTD_IC12,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc13 = new SpiCookie(addresses::RTD_IC13, gpioIds::RTD_IC13,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc14 = new SpiCookie(addresses::RTD_IC14, gpioIds::RTD_IC14,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc15 = new SpiCookie(addresses::RTD_IC15, gpioIds::RTD_IC15,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc16 = new SpiCookie(addresses::RTD_IC16, gpioIds::RTD_IC16,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc17 = new SpiCookie(addresses::RTD_IC17, gpioIds::RTD_IC17,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc18 = new SpiCookie(addresses::RTD_IC18, gpioIds::RTD_IC18,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
Max31865PT1000Handler* rtdIc3 = new Max31865PT1000Handler(objects::RTD_IC3, objects::SPI_COM_IF, spiRtdIc3, 0); // 0 is switchId
Max31865PT1000Handler* rtdIc4 = new Max31865PT1000Handler(objects::RTD_IC4, objects::SPI_COM_IF, spiRtdIc4, 0);
Max31865PT1000Handler* rtdIc5 = new Max31865PT1000Handler(objects::RTD_IC5, objects::SPI_COM_IF, spiRtdIc5, 0);
Max31865PT1000Handler* rtdIc6 = new Max31865PT1000Handler(objects::RTD_IC6, objects::SPI_COM_IF, spiRtdIc6, 0);
Max31865PT1000Handler* rtdIc7 = new Max31865PT1000Handler(objects::RTD_IC7, objects::SPI_COM_IF, spiRtdIc7, 0);
Max31865PT1000Handler* rtdIc8 = new Max31865PT1000Handler(objects::RTD_IC8, objects::SPI_COM_IF, spiRtdIc8, 0);
Max31865PT1000Handler* rtdIc9 = new Max31865PT1000Handler(objects::RTD_IC9, objects::SPI_COM_IF, spiRtdIc9, 0);
Max31865PT1000Handler* rtdIc10 = new Max31865PT1000Handler(objects::RTD_IC10, objects::SPI_COM_IF, spiRtdIc10, 0);
Max31865PT1000Handler* rtdIc11 = new Max31865PT1000Handler(objects::RTD_IC11, objects::SPI_COM_IF, spiRtdIc11, 0);
Max31865PT1000Handler* rtdIc12 = new Max31865PT1000Handler(objects::RTD_IC12, objects::SPI_COM_IF, spiRtdIc12, 0);
Max31865PT1000Handler* rtdIc13 = new Max31865PT1000Handler(objects::RTD_IC13, objects::SPI_COM_IF, spiRtdIc13, 0);
Max31865PT1000Handler* rtdIc14 = new Max31865PT1000Handler(objects::RTD_IC14, objects::SPI_COM_IF, spiRtdIc14, 0);
Max31865PT1000Handler* rtdIc15 = new Max31865PT1000Handler(objects::RTD_IC15, objects::SPI_COM_IF, spiRtdIc15, 0);
Max31865PT1000Handler* rtdIc16 = new Max31865PT1000Handler(objects::RTD_IC16, objects::SPI_COM_IF, spiRtdIc16, 0);
Max31865PT1000Handler* rtdIc17 = new Max31865PT1000Handler(objects::RTD_IC17, objects::SPI_COM_IF, spiRtdIc17, 0);
Max31865PT1000Handler* rtdIc18 = new Max31865PT1000Handler(objects::RTD_IC18, objects::SPI_COM_IF, spiRtdIc18, 0);
// rtdIc10->setStartUpImmediately();
// rtdIc4->setStartUpImmediately();
(void) rtdIc3;
(void) rtdIc4;
(void) rtdIc5;
(void) rtdIc6;
(void) rtdIc7;
(void) rtdIc8;
(void) rtdIc9;
(void) rtdIc10;
(void) rtdIc11;
(void) rtdIc12;
(void) rtdIc13;
(void) rtdIc14;
(void) rtdIc15;
(void) rtdIc16;
(void) rtdIc17;
(void) rtdIc18;
#endif /* Q7S_ADD_RTD_DEVICES == 1 */
#endif /* TE0720 == 0 */
new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR, objects::TM_STORE,
objects::TC_STORE);
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, IMTQ::MAX_REPLY_SIZE,
std::string("/dev/i2c-0"));
IMTQHandler* imtqHandler = new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie);
imtqHandler->setStartUpImmediately();
#if TE0720 == 1 && TEST_LIBGPIOD == 1
/* Configure MIO0 as input */
GpiodRegular gpioConfigMio0(std::string("gpiochip0"), 0,
std::string("MIO0"), gpio::IN, 0);
GpioCookie* gpioCookie = new GpioCookie;
gpioCookie->addGpio(gpioIds::TEST_ID_0, gpioConfigMio0);
new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie);
#elif TE0720 == 1
/* Configuration for MIO0 on TE0720-03-1CFA */
GpiodRegular gpioConfigForDummyHeater(std::string("gpiochip0"), 0,
std::string("Heater0"), gpio::OUT, 0);
heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie,
objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN);
#endif
#if Q7S_ADD_SPI_TEST == 1
new SpiTestClass(objects::SPI_TEST, gpioComIF);
#endif
}

9
bsp_q7s/ObjectFactory.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef BSP_Q7S_OBJECTFACTORY_H_
#define BSP_Q7S_OBJECTFACTORY_H_
namespace ObjectFactory {
void setStatics();
void produce();
};
#endif /* BSP_Q7S_OBJECTFACTORY_H_ */

View File

@ -0,0 +1,10 @@
target_sources(${TARGET_NAME} PRIVATE
print.c
)
target_include_directories(${TARGET_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,4 +1,4 @@
#include "print.h"
#include <bsp_q7s/boardconfig/print.h>
#include <stdio.h>
void printChar(const char* character, bool errStream) {

View File

@ -0,0 +1,13 @@
#ifndef BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_
#define BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_
#define Q7S_ADD_RTD_DEVICES 0
/* Only one of those 2 should be enabled! */
/* Add code for ACS board */
#define OBSW_ADD_ACS_BOARD 0
#define Q7S_ADD_SPI_TEST 0
#endif /* BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_ */

View File

@ -0,0 +1,6 @@
target_sources(${TARGET_NAME} PRIVATE
)

6
bsp_q7s/bsp_q7s.mk Normal file
View File

@ -0,0 +1,6 @@
CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/comIF/cookies/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/comIF/*.cpp)
CSRC += $(wildcard $(CURRENTPATH)/*.c)
CSRC += $(wildcard $(CURRENTPATH)/boardconfig/*.c)

View File

@ -0,0 +1,6 @@
target_sources(${TARGET_NAME} PRIVATE
)

View File

@ -0,0 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
HeaterHandler.cpp
SolarArrayDeploymentHandler.cpp
)

View File

@ -0,0 +1,370 @@
#include "HeaterHandler.h"
#include <fsfwconfig/devices/powerSwitcherList.h>
#include <fsfw/ipc/QueueFactory.h>
#include <devices/gpioIds.h>
#include <fsfw_hal/common/gpio/GpioCookie.h>
HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_,
CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) :
SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_),
mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_),
actionHelper(this, nullptr) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
}
HeaterHandler::~HeaterHandler() {
}
ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) {
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
readCommandQueue();
handleActiveCommands();
return RETURN_OK;
}
return RETURN_OK;
}
ReturnValue_t HeaterHandler::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = initializeHeaterMap();
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
gpioInterface = objectManager->get<GpioIF>(gpioDriverId);
if (gpioInterface == nullptr) {
sif::error << "HeaterHandler::initialize: Invalid Gpio interface." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = gpioInterface->addGpios(dynamic_cast<GpioCookie*>(gpioCookie));
if (result != RETURN_OK) {
sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == nullptr) {
sif::error << "HeaterHandler::initialize: IPC store not set up in factory." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if(mainLineSwitcherObjectId != objects::NO_OBJECT) {
mainLineSwitcher = objectManager->get<PowerSwitchIF>(mainLineSwitcherObjectId);
if (mainLineSwitcher == nullptr) {
sif::error << "HeaterHandler::initialize: Main line switcher failed to fetch object"
<< "from object ID." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
return RETURN_OK;
}
ReturnValue_t HeaterHandler::initializeHeaterMap(){
HeaterCommandInfo_t heaterCommandInfo;
for(switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
std::pair status = heaterMap.emplace(switchNr, heaterCommandInfo);
if (status.second == false) {
sif::error << "HeaterHandler::initializeHeaterMap: Failed to initialize heater map"
<< std::endl;
return RETURN_FAILED;
}
}
return RETURN_OK;
}
void HeaterHandler::setInitialSwitchStates() {
for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
switchStates[switchNr] = OFF;
}
}
void HeaterHandler::readCommandQueue() {
CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) {
return;
}
result = actionHelper.handleActionMessage(&command);
if (result == RETURN_OK) {
return;
}
}
ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
ReturnValue_t result;
if (actionId != SWITCH_HEATER) {
result = COMMAND_NOT_SUPPORTED;
} else {
switchNr_t switchNr = *data;
HeaterMapIter heaterMapIter = heaterMap.find(switchNr);
if (heaterMapIter != heaterMap.end()) {
if (heaterMapIter->second.active) {
return COMMAND_ALREADY_WAITING;
}
heaterMapIter->second.action = *(data + 1);
heaterMapIter->second.active = true;
heaterMapIter->second.replyQueue = commandedBy;
}
else {
sif::error << "HeaterHandler::executeAction: Invalid switchNr" << std::endl;
return INVALID_SWITCH_NR;
}
result = RETURN_OK;
}
return result;
}
void HeaterHandler::sendSwitchCommand(uint8_t switchNr,
ReturnValue_t onOff) const {
ReturnValue_t result;
store_address_t storeAddress;
uint8_t commandData[2];
switch(onOff) {
case PowerSwitchIF::SWITCH_ON:
commandData[0] = switchNr;
commandData[1] = SET_SWITCH_ON;
break;
case PowerSwitchIF::SWITCH_OFF:
commandData[0] = switchNr;
commandData[1] = SET_SWITCH_OFF;
break;
default:
sif::error << "HeaterHandler::sendSwitchCommand: Invalid switch request"
<< std::endl;
break;
}
result = IPCStore->addData(&storeAddress, commandData, sizeof(commandData));
if (result == RETURN_OK) {
CommandMessage message;
ActionMessage::setCommand(&message, SWITCH_HEATER, storeAddress);
/* Send heater command to own command queue */
result = commandQueue->sendMessage(commandQueue->getId(), &message, 0);
if (result != RETURN_OK) {
sif::debug << "HeaterHandler::sendSwitchCommand: Failed to send switch"
<< "message" << std::endl;
}
}
}
void HeaterHandler::handleActiveCommands(){
HeaterMapIter heaterMapIter = heaterMap.begin();
for (; heaterMapIter != heaterMap.end(); heaterMapIter++) {
if (heaterMapIter->second.active) {
switch(heaterMapIter->second.action) {
case SET_SWITCH_ON:
handleSwitchOnCommand(heaterMapIter);
break;
case SET_SWITCH_OFF:
handleSwitchOffCommand(heaterMapIter);
break;
default:
sif::error << "HeaterHandler::handleActiveCommands: Invalid action commanded"
<< std::endl;
break;
}
}
}
}
void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) {
ReturnValue_t result = RETURN_OK;
switchNr_t switchNr;
/* Check if command waits for main switch being set on and whether the timeout has expired */
if (heaterMapIter->second.waitMainSwitchOn
&& heaterMapIter->second.mainSwitchCountdown.hasTimedOut()) {
//TODO - This requires the initiation of an FDIR procedure
triggerEvent(MAIN_SWITCH_TIMEOUT);
sif::error << "HeaterHandler::handleSwitchOnCommand: Main switch setting on timeout"
<< std::endl;
heaterMapIter->second.active = false;
heaterMapIter->second.waitMainSwitchOn = false;
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, MAIN_SWITCH_SET_TIMEOUT );
}
return;
}
switchNr = heaterMapIter->first;
/* Check state of main line switch */
ReturnValue_t mainSwitchState = mainLineSwitcher->getSwitchState(mainLineSwitch);
if (mainSwitchState == PowerSwitchIF::SWITCH_ON) {
if (!checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullHigh(gpioId);
if (result != RETURN_OK) {
sif::error << "HeaterHandler::handleSwitchOnCommand: Failed to pull gpio with id "
<< gpioId << " high" << std::endl;
triggerEvent(GPIO_PULL_HIGH_FAILED, result);
}
else {
switchStates[switchNr] = ON;
}
}
else {
triggerEvent(SWITCH_ALREADY_ON, switchNr);
}
/* There is no need to send action finish replies if the sender was the
* HeaterHandler itself. */
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
if(result == RETURN_OK) {
actionHelper.finish(true, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
else {
actionHelper.finish(false, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
}
heaterMapIter->second.active = false;
heaterMapIter->second.waitMainSwitchOn = false;
}
else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF
&& heaterMapIter->second.waitMainSwitchOn) {
/* Just waiting for the main switch being set on */
return;
}
else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF) {
mainLineSwitcher->sendSwitchCommand(mainLineSwitch,
PowerSwitchIF::SWITCH_ON);
heaterMapIter->second.mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
heaterMapIter->second.waitMainSwitchOn = true;
}
else {
sif::debug << "HeaterHandler::handleActiveCommands: Failed to get state of"
<< " main line switch" << std::endl;
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, mainSwitchState);
}
heaterMapIter->second.active = false;
}
}
void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) {
ReturnValue_t result = RETURN_OK;
switchNr_t switchNr = heaterMapIter->first;
/* Check whether switch is already off */
if (checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullLow(gpioId);
if (result != RETURN_OK) {
sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id"
<< gpioId << " low" << std::endl;
triggerEvent(GPIO_PULL_LOW_FAILED, result);
}
else {
switchStates[switchNr] = OFF;
/* When all switches are off, also main line switch will be turned off */
if (allSwitchesOff()) {
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
}
}
}
else {
sif::info << "HeaterHandler::handleSwitchOffCommand: Switch already off" << std::endl;
triggerEvent(SWITCH_ALREADY_OFF, switchNr);
}
if (heaterMapIter->second.replyQueue != NO_COMMANDER) {
/* Report back switch command reply if necessary */
if(result == HasReturnvaluesIF::RETURN_OK) {
actionHelper.finish(true, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
else {
actionHelper.finish(false, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
}
heaterMapIter->second.active = false;
}
bool HeaterHandler::checkSwitchState(int switchNr) {
return switchStates[switchNr];
}
bool HeaterHandler::allSwitchesOff() {
bool allSwitchesOrd = false;
/* Or all switches. As soon one switch is on, allSwitchesOrd will be true */
for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
allSwitchesOrd = allSwitchesOrd || switchStates[switchNr];
}
return !allSwitchesOrd;
}
gpioId_t HeaterHandler::getGpioIdFromSwitchNr(int switchNr) {
gpioId_t gpioId = 0xFFFF;
switch(switchNr) {
case heaterSwitches::HEATER_0:
gpioId = gpioIds::HEATER_0;
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:
sif::error << "HeaterHandler::getGpioIdFromSwitchNr: Unknown heater switch number"
<< std::endl;
break;
}
return gpioId;
}
MessageQueueId_t HeaterHandler::getCommandQueue() const {
return commandQueue->getId();
}
void HeaterHandler::sendFuseOnCommand(uint8_t fuseNr) const {
}
ReturnValue_t HeaterHandler::getSwitchState( uint8_t switchNr ) const {
return 0;
}
ReturnValue_t HeaterHandler::getFuseState( uint8_t fuseNr ) const {
return 0;
}
uint32_t HeaterHandler::getSwitchDelayMs(void) const {
return 0;
}

View File

@ -0,0 +1,177 @@
#ifndef MISSION_DEVICES_HEATERHANDLER_H_
#define MISSION_DEVICES_HEATERHANDLER_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfwconfig/devices/heaterSwitcherList.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <fsfw_hal/common/gpio/GpioIF.h>
#include <unordered_map>
/**
* @brief This class intends the control of heaters.
*
* @author J. Meier
*/
class HeaterHandler: public ExecutableObjectIF,
public PowerSwitchIF,
public SystemObject,
public HasActionsIF {
public:
/** Device command IDs */
static const DeviceCommandId_t SWITCH_HEATER = 0x0;
HeaterHandler(object_id_t setObjectId, object_id_t gpioDriverId, CookieIF * gpioCookie,
object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch);
virtual ~HeaterHandler();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const override;
virtual void sendFuseOnCommand(uint8_t fuseNr) const override;
/**
* @brief This function will be called from the Heater object to check
* the current switch state.
*/
virtual ReturnValue_t getSwitchState( uint8_t switchNr ) const override;
virtual ReturnValue_t getFuseState( uint8_t fuseNr ) const override;
virtual uint32_t getSwitchDelayMs(void) const override;
virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
virtual ReturnValue_t initialize() override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::HEATER_HANDLER;
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1);
static const ReturnValue_t INIT_FAILED = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t INVALID_SWITCH_NR = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER_HANDLER;
static const Event GPIO_PULL_HIGH_FAILED = MAKE_EVENT(0, severity::LOW);
static const Event GPIO_PULL_LOW_FAILED = MAKE_EVENT(1, severity::LOW);
static const Event SWITCH_ALREADY_ON = MAKE_EVENT(2, severity::LOW);
static const Event SWITCH_ALREADY_OFF = MAKE_EVENT(3, severity::LOW);
static const Event MAIN_SWITCH_TIMEOUT = MAKE_EVENT(4, severity::LOW);
static const MessageQueueId_t NO_COMMANDER = 0;
enum SwitchState : bool {
ON = true,
OFF = false
};
/**
* @brief Struct holding information about a heater command to execute.
*
* @param action The action to perform.
* @param replyQueue The queue of the commander to which status replies
* will be sent.
* @param active True if command is waiting for execution, otherwise false.
* @param waitSwitchOn True if the command is waiting for the main switch being set on.
* @param mainSwitchCountdown Sets timeout to wait for main switch being set on.
*/
typedef struct HeaterCommandInfo {
uint8_t action;
MessageQueueId_t replyQueue;
bool active = false;
bool waitMainSwitchOn = false;
Countdown mainSwitchCountdown;
} HeaterCommandInfo_t;
enum SwitchAction {
SET_SWITCH_OFF,
SET_SWITCH_ON
};
using switchNr_t = uint8_t;
using HeaterMap = std::unordered_map<switchNr_t, HeaterCommandInfo_t>;
using HeaterMapIter = HeaterMap::iterator;
HeaterMap heaterMap;
bool switchStates[heaterSwitches::NUMBER_OF_SWITCHES];
/** Size of command queue */
size_t cmdQueueSize = 20;
/**
* The object ID of the GPIO driver which enables and disables the
* heaters.
*/
object_id_t gpioDriverId;
CookieIF * gpioCookie;
GpioIF* gpioInterface = nullptr;
/** Queue to receive messages from other objects. */
MessageQueueIF* commandQueue = nullptr;
object_id_t mainLineSwitcherObjectId;
/** Switch number of the heater power supply switch */
uint8_t mainLineSwitch;
/**
* Power switcher object which controls the 8V main line of the heater
* logic on the TCS board.
*/
PowerSwitchIF *mainLineSwitcher = nullptr;
ActionHelper actionHelper;
StorageManagerIF *IPCStore = nullptr;
void readCommandQueue();
/**
* @brief Returns the state of a switch (ON - true, or OFF - false).
* @param switchNr The number of the switch to check.
*/
bool checkSwitchState(int switchNr);
/**
* @brief Returns the ID of the GPIO related to a heater identified by the switch number
* which is defined in the heaterSwitches list.
*/
gpioId_t getGpioIdFromSwitchNr(int switchNr);
/**
* @brief This function runs commands waiting for execution.
*/
void handleActiveCommands();
ReturnValue_t initializeHeaterMap();
/**
* @brief Sets all switches to OFF.
*/
void setInitialSwitchStates();
void handleSwitchOnCommand(HeaterMapIter heaterMapIter);
void handleSwitchOffCommand(HeaterMapIter heaterMapIter);
/**
* @brief Checks if all switches are off.
* @return True if all switches are off, otherwise false.
*/
bool allSwitchesOff();
};
#endif /* MISSION_DEVICES_HEATERHANDLER_H_ */

View File

@ -0,0 +1,201 @@
#include "SolarArrayDeploymentHandler.h"
#include <devices/powerSwitcherList.h>
#include <devices/gpioIds.h>
#include <fsfw_hal/common/gpio/GpioCookie.h>
#include <fsfw/ipc/QueueFactory.h>
SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_,
object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_,
uint8_t mainLineSwitch_, gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs) :
SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_),
mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_),
deplSA1(deplSA1), deplSA2(deplSA2), burnTimeMs(burnTimeMs), actionHelper(this, nullptr) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
}
SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() {
}
ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) {
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
handleStateMachine();
return RETURN_OK;
}
return RETURN_OK;
}
ReturnValue_t SolarArrayDeploymentHandler::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
gpioInterface = objectManager->get<GpioIF>(gpioDriverId);
if (gpioInterface == nullptr) {
sif::error << "SolarArrayDeploymentHandler::initialize: Invalid Gpio interface."
<< std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = gpioInterface->addGpios(dynamic_cast<GpioCookie*>(gpioCookie));
if (result != RETURN_OK) {
sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface"
<< std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if (mainLineSwitcherObjectId != objects::NO_OBJECT) {
mainLineSwitcher = objectManager->get<PowerSwitchIF>(mainLineSwitcherObjectId);
if (mainLineSwitcher == nullptr) {
sif::error
<< "SolarArrayDeploymentHandler::initialize: Main line switcher failed to fetch object"
<< "from object ID." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
return RETURN_OK;
}
void SolarArrayDeploymentHandler::handleStateMachine() {
switch (stateMachine) {
case WAIT_ON_DELOYMENT_COMMAND:
readCommandQueue();
break;
case SWITCH_8V_ON:
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON);
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
stateMachine = WAIT_ON_8V_SWITCH;
break;
case WAIT_ON_8V_SWITCH:
performWaitOn8VActions();
break;
case SWITCH_DEPL_GPIOS:
switchDeploymentTransistors();
break;
case WAIT_ON_DEPLOYMENT_FINISH:
handleDeploymentFinish();
break;
case WAIT_FOR_MAIN_SWITCH_OFF:
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) {
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
} else if (mainSwitchCountdown.hasTimedOut()) {
triggerEvent(MAIN_SWITCH_OFF_TIMEOUT);
sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main"
<< " switch off" << std::endl;
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
}
break;
default:
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << std::endl;
break;
}
}
void SolarArrayDeploymentHandler::performWaitOn8VActions() {
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) {
stateMachine = SWITCH_DEPL_GPIOS;
} else {
if (mainSwitchCountdown.hasTimedOut()) {
triggerEvent(MAIN_SWITCH_ON_TIMEOUT);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
MAIN_SWITCH_TIMEOUT_FAILURE);
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
}
}
}
void SolarArrayDeploymentHandler::switchDeploymentTransistors() {
ReturnValue_t result = RETURN_OK;
result = gpioInterface->pullHigh(deplSA1);
if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
" array deployment switch 1 high " << std::endl;
/* If gpio switch high failed, state machine is reset to wait for a command reinitiating
* the deployment sequence. */
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
SWITCHING_DEPL_SA2_FAILED);
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
}
result = gpioInterface->pullHigh(deplSA2);
if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
" array deployment switch 2 high " << std::endl;
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
SWITCHING_DEPL_SA2_FAILED);
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
}
deploymentCountdown.setTimeout(burnTimeMs);
stateMachine = WAIT_ON_DEPLOYMENT_FINISH;
}
void SolarArrayDeploymentHandler::handleDeploymentFinish() {
ReturnValue_t result = RETURN_OK;
if (deploymentCountdown.hasTimedOut()) {
actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, RETURN_OK);
result = gpioInterface->pullLow(deplSA1);
if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
" array deployment switch 1 low " << std::endl;
}
result = gpioInterface->pullLow(deplSA2);
if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
" array deployment switch 2 low " << std::endl;
}
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
stateMachine = WAIT_FOR_MAIN_SWITCH_OFF;
}
}
void SolarArrayDeploymentHandler::readCommandQueue() {
CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) {
return;
}
result = actionHelper.handleActionMessage(&command);
if (result == RETURN_OK) {
return;
}
}
ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
ReturnValue_t result;
if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) {
sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in"
<< "waiting-on-command-state" << std::endl;
return DEPLOYMENT_ALREADY_EXECUTING;
}
if (actionId != DEPLOY_SOLAR_ARRAYS) {
sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command"
<< std::endl;
result = COMMAND_NOT_SUPPORTED;
} else {
stateMachine = SWITCH_8V_ON;
rememberCommanderId = commandedBy;
result = RETURN_OK;
}
return result;
}
MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const {
return commandQueue->getId();
}

View File

@ -0,0 +1,158 @@
#ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
#define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <fsfw_hal/common/gpio/GpioIF.h>
#include <unordered_map>
/**
* @brief This class is used to control the solar array deployment.
*
* @author J. Meier
*/
class SolarArrayDeploymentHandler: public ExecutableObjectIF,
public SystemObject,
public HasReturnvaluesIF,
public HasActionsIF {
public:
static const DeviceCommandId_t DEPLOY_SOLAR_ARRAYS = 0x5;
/**
* @brief constructor
*
* @param setObjectId The object id of the SolarArrayDeploymentHandler.
* @param gpioDriverId The id of the gpio com if.
* @param gpioCookie GpioCookie holding information about the gpios used to switch the
* transistors.
* @param mainLineSwitcherObjectId The object id of the object responsible for switching
* the 8V power source. This is normally the PCDU.
* @param mainLineSwitch The id of the main line switch. This is defined in
* powerSwitcherList.h.
* @param deplSA1 gpioId of the GPIO controlling the deployment 1 transistor.
* @param deplSA2 gpioId of the GPIO controlling the deployment 2 transistor.
* @param burnTimeMs Time duration the power will be applied to the burn wires.
*/
SolarArrayDeploymentHandler(object_id_t setObjectId, object_id_t gpioDriverId,
CookieIF * gpioCookie, object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch,
gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs);
virtual ~SolarArrayDeploymentHandler();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
virtual ReturnValue_t initialize() override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::SA_DEPL_HANDLER;
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA0);
static const ReturnValue_t DEPLOYMENT_ALREADY_EXECUTING = MAKE_RETURN_CODE(0xA1);
static const ReturnValue_t MAIN_SWITCH_TIMEOUT_FAILURE = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t SWITCHING_DEPL_SA1_FAILED = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t SWITCHING_DEPL_SA2_FAILED = MAKE_RETURN_CODE(0xA4);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SA_DEPL_HANDLER;
static const Event MAIN_SWITCH_ON_TIMEOUT = MAKE_EVENT(0, severity::LOW);
static const Event MAIN_SWITCH_OFF_TIMEOUT = MAKE_EVENT(1, severity::LOW);
static const Event DEPLOYMENT_FAILED = MAKE_EVENT(2, severity::HIGH);
static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH);
static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH);
enum StateMachine {
WAIT_ON_DELOYMENT_COMMAND,
SWITCH_8V_ON,
WAIT_ON_8V_SWITCH,
SWITCH_DEPL_GPIOS,
WAIT_ON_DEPLOYMENT_FINISH,
WAIT_FOR_MAIN_SWITCH_OFF
};
StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND;
/**
* This countdown is used to check if the PCDU sets the 8V line on in the intended time.
*/
Countdown mainSwitchCountdown;
/**
* This countdown is used to wait for the burn wire being successful cut.
*/
Countdown deploymentCountdown;
/**
* The message queue id of the component commanding an action will be stored in this variable.
* This is necessary to send later the action finish replies.
*/
MessageQueueId_t rememberCommanderId = 0;
/** Size of command queue */
size_t cmdQueueSize = 20;
/** The object ID of the GPIO driver which switches the deployment transistors */
object_id_t gpioDriverId;
CookieIF * gpioCookie;
/** Object id of the object responsible to switch the 8V power input. Typically the PCDU. */
object_id_t mainLineSwitcherObjectId;
/** Switch number of the 8V power switch */
uint8_t mainLineSwitch;
gpioId_t deplSA1;
gpioId_t deplSA2;
GpioIF* gpioInterface = nullptr;
/** Time duration switches are active to cut the burn wire */
uint32_t burnTimeMs;
/** Queue to receive messages from other objects. */
MessageQueueIF* commandQueue = nullptr;
/**
* After initialization this pointer will hold the reference to the main line switcher object.
*/
PowerSwitchIF *mainLineSwitcher = nullptr;
ActionHelper actionHelper;
void readCommandQueue();
/**
* @brief This function performs actions dependent on the current state.
*/
void handleStateMachine();
/**
* @brief This function polls the 8V switch state and changes the state machine when the
* switch has been enabled.
*/
void performWaitOn8VActions();
/**
* @brief This functions handles the switching of the solar array deployment transistors.
*/
void switchDeploymentTransistors();
/**
* @brief This function performs actions to finish the deployment. Essentially switches
* are turned of after the burn time has expired.
*/
void handleDeploymentFinish();
};
#endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */

View File

@ -0,0 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
gpioCallbacks.cpp
)

View File

@ -0,0 +1,221 @@
#include "gpioCallbacks.h"
#include <devices/gpioIds.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <fsfw_hal/common/gpio/GpioCookie.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
namespace gpioCallbacks {
GpioIF* gpioComInterface;
void initTcsBoardDecoder(GpioIF* gpioComIF) {
ReturnValue_t result;
if (gpioComIF == nullptr) {
sif::debug << "initTcsBoardDecoder: Invalid gpioComIF" << std::endl;
return;
}
gpioComInterface = gpioComIF;
GpioCookie* spiMuxGpios = new GpioCookie;
/**
* Initial values of the spi mux gpios can all be set to an arbitrary value expect for spi mux
* bit 1. Setting spi mux bit 1 to high will pull all decoder outputs to high voltage level.
*/
GpiodRegular* spiMuxBit1 = new GpiodRegular(std::string("gpiochip7"), 13,
std::string("SPI Mux Bit 1"), gpio::OUT, 1);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit1);
GpiodRegular* spiMuxBit2 = new GpiodRegular(std::string("gpiochip7"), 14,
std::string("SPI Mux Bit 2"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit2);
GpiodRegular* spiMuxBit3 = new GpiodRegular(std::string("gpiochip7"), 15,
std::string("SPI Mux Bit 3"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit3);
GpiodRegular* spiMuxBit4 = new GpiodRegular(std::string("gpiochip7"), 16,
std::string("SPI Mux Bit 4"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit4);
GpiodRegular* spiMuxBit5 = new GpiodRegular(std::string("gpiochip7"), 17,
std::string("SPI Mux Bit 5"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit5);
GpiodRegular* spiMuxBit6 = new GpiodRegular(std::string("gpiochip7"), 18,
std::string("SPI Mux Bit 6"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_6, spiMuxBit6);
result = gpioComInterface->addGpios(spiMuxGpios);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "initTcsBoardDecoder: Failed to add mux bit gpios to gpioComIF"
<< std::endl;
return;
}
}
void tcsBoardDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value,
void* args) {
if (gpioComInterface == nullptr) {
sif::debug << "tcsBoardDecoderCallback: No gpioComIF specified. Call initTcsBoardDecoder "
<< "to specify gpioComIF" << std::endl;
return;
}
/* Read is not supported by the callback function */
if (gpioOp == gpio::GpioOperation::READ) {
return;
}
if (value == 1) {
/* This will pull all 16 decoder outputs to high */
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
}
else if (value == 0) {
switch (gpioId) {
case(gpioIds::RTD_IC3): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC4): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC5): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC6): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC7): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC8): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC9): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC10): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC11): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC12): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC13): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC14): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC15): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC16): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC17): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
break;
}
case(gpioIds::RTD_IC18): {
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
break;
}
default:
sif::debug << "tcsBoardDecoderCallback: Invalid gpioid " << gpioId << std::endl;
}
}
else {
sif::debug << "tcsBoardDecoderCallback: Invalid value. Must be 0 or 1" << std::endl;
}
}
}

View File

@ -0,0 +1,23 @@
#ifndef LINUX_GPIO_GPIOCALLBACKS_H_
#define LINUX_GPIO_GPIOCALLBACKS_H_
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
#include <fsfw_hal/common/gpio/GpioIF.h>
namespace gpioCallbacks {
/**
* @brief This function initializes the GPIOs used to control the SN74LVC138APWR decoders on
* the TCS Board.
*/
void initTcsBoardDecoder(GpioIF* gpioComIF);
/**
* @brief This function implements the decoding to multiply gpios by using the two decoder
* chips SN74LVC138APWR on the TCS board.
*/
void tcsBoardDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args);
}
#endif /* LINUX_GPIO_GPIOCALLBACKS_H_ */

View File

@ -1,5 +1,4 @@
#include "InitMission.h"
#include <OBSWVersion.h>
#include <fsfw/tasks/TaskFactory.h>
@ -14,15 +13,15 @@
int main(void)
{
std::cout << "-- EIVE OBSW --" << std::endl;
std::cout << "-- Compiled for Linux " << " --" << std::endl;
std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl;
std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "."
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl;
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
InitMission::initMission();
initmission::initMission();
for(;;) {
// suspend main thread by sleeping it.
/* Suspend main thread by sleeping it. */
TaskFactory::delayTask(5000);
}
}

14
bsp_rpi/CMakeLists.txt Normal file
View File

@ -0,0 +1,14 @@
target_sources(${TARGET_NAME} PUBLIC
InitMission.cpp
main.cpp
ObjectFactory.cpp
)
add_subdirectory(boardconfig)
add_subdirectory(boardtest)
add_subdirectory(gpio)

177
bsp_rpi/InitMission.cpp Normal file
View File

@ -0,0 +1,177 @@
#include "InitMission.h"
#include "ObjectFactory.h"
#include <fsfwconfig/objects/systemObjectList.h>
#include <fsfwconfig/OBSWConfig.h>
#include <fsfwconfig/pollingsequence/pollingSequenceFactory.h>
#include <mission/utility/InitMission.h>
#include <fsfw/objectmanager/ObjectManagerIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include <fsfw/tasks/PeriodicTaskIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <iostream>
ServiceInterfaceStream sif::debug("DEBUG");
ServiceInterfaceStream sif::info("INFO");
ServiceInterfaceStream sif::warning("WARNING");
ServiceInterfaceStream sif::error("ERROR");
ObjectManagerIF *objectManager = nullptr;
void initmission::initMission() {
sif::info << "Building global objects.." << std::endl;
/* Instantiate global object manager and also create all objects */
objectManager = new ObjectManager(ObjectFactory::produce);
sif::info << "Initializing all objects.." << std::endl;
objectManager->initialize();
/* This function creates and starts all tasks */
initTasks();
}
void initmission::initTasks() {
TaskFactory* factory = TaskFactory::instance();
if(factory == nullptr) {
/* Should never happen ! */
return;
}
#if OBSW_PRINT_MISSED_DEADLINES == 1
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
#else
void (*missedDeadlineFunc) (void) = nullptr;
#endif
/* TMTC Distribution */
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
ReturnValue_t result = tmTcDistributor->addComponent(
objects::CCSDS_PACKET_DISTRIBUTOR);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Object add component failed" << std::endl;
}
/* UDP bridge */
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = udpBridgeTask->addComponent(objects::UDP_BRIDGE);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
}
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component UDP Polling failed" << std::endl;
}
/* PUS Services */
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
if(result != HasReturnvaluesIF::RETURN_OK){
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
}
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
}
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
}
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
}
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
}
#if RPI_TEST_ACS_BOARD == 1
FixedTimeslotTaskIF* acsTask = factory->createFixedTimeslotTask(
"ACS_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc);
result = pst::pollingSequenceAcsTest(acsTask);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "initmission::initTasks: ACS PST initialization failed!" << std::endl;
}
#endif /* RPI_TEST_ACS_BOARD == 1 */
PeriodicTaskIF* testTask = factory->createPeriodicTask(
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
#if OBSW_ADD_TEST_CODE == 1
result = testTask->addComponent(objects::TEST_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
}
#endif /* OBSW_ADD_TEST_CODE == 1 */
#if RPI_ADD_SPI_TEST == 1
result = testTask->addComponent(objects::SPI_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
}
#endif /* RPI_ADD_SPI_TEST == 1 */
#if RPI_ADD_GPIO_TEST == 1
result = testTask->addComponent(objects::LIBGPIOD_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
}
#endif /* RPI_ADD_GPIO_TEST == 1 */
sif::info << "Starting tasks.." << std::endl;
tmTcDistributor->startTask();
udpBridgeTask->startTask();
udpPollingTask->startTask();
pusVerification->startTask();
pusEvents->startTask();
pusHighPrio->startTask();
pusMedPrio->startTask();
pusLowPrio->startTask();
#if OBSW_ADD_TEST_CODE == 1
testTask->startTask();
#endif /* OBSW_ADD_TEST_CODE == 1 */
#if RPI_TEST_ACS_BOARD == 1
acsTask->startTask();
#endif /* RPI_TEST_ACS_BOARD == 1 */
sif::info << "Tasks started.." << std::endl;
}

View File

@ -1,7 +1,7 @@
#ifndef BSP_LINUX_INITMISSION_H_
#define BSP_LINUX_INITMISSION_H_
namespace InitMission {
namespace initmission {
void initMission();
void initTasks();
};

125
bsp_rpi/ObjectFactory.cpp Normal file
View File

@ -0,0 +1,125 @@
#include "ObjectFactory.h"
#include <fsfwconfig/objects/systemObjectList.h>
#include <fsfwconfig/devices/addresses.h>
#include <fsfwconfig/devices/gpioIds.h>
#include <fsfwconfig/OBSWConfig.h>
#include <fsfwconfig/tmtc/apid.h>
#include <fsfwconfig/tmtc/pusIds.h>
#include <fsfwconfig/devices/spi.h>
#include <linux/boardtest/LibgpiodTest.h>
#include <linux/boardtest/SpiTestClass.h>
#include <mission/devices/GyroL3GD20Handler.h>
#include <mission/core/GenericFactory.h>
#include <mission/utility/TmFunnel.h>
#include <mission/devices/MGMHandlerLIS3MDL.h>
#include <mission/devices/MGMHandlerRM3100.h>
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
#include <fsfw/tmtcservices/CommandingServiceBase.h>
#include <fsfw/tmtcservices/PusServiceBase.h>
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
#include <fsfw/tasks/TaskFactory.h>
/* UDP server includes */
#include <fsfw/osal/common/UdpTmTcBridge.h>
#include <fsfw/osal/common/UdpTcPollingTask.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <fsfw_hal/linux/rpi/GpioRPi.h>
#include <fsfw_hal/common/gpio/GpioCookie.h>
#include <fsfw_hal/linux/spi/SpiCookie.h>
#include <fsfw_hal/linux/spi/SpiComIF.h>
void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
PusServiceBase::packetDestination = objects::TM_FUNNEL;
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
TmFunnel::downlinkDestination = objects::UDP_BRIDGE;
// No storage object for now.
TmFunnel::storageDestination = objects::NO_OBJECT;
LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT;
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
TmPacketStored::timeStamperId = objects::TIME_STAMPER;
}
void ObjectFactory::produce(){
Factory::setStaticFrameworkObjectIds();
ObjectFactory::produceGenericObjects();
new UdpTmTcBridge(objects::UDP_BRIDGE,
objects::CCSDS_PACKET_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE);
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
#if RPI_ADD_SPI_TEST == 1
new SpiTestClass(objects::SPI_TEST, gpioIF);
#endif
#if RPI_LOOPBACK_TEST_GPIO == 1
GpioCookie* gpioCookieLoopback = new GpioCookie();
/* Loopback pins. Adapt according to setup */
gpioId_t gpioIdSender = gpioIds::TEST_ID_0;
int bcmPinSender = 26;
gpioId_t gpioIdReader = gpioIds::TEST_ID_1;
int bcmPinReader = 16;
gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER",
gpio::Direction::OUT, 0);
gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER",
gpio::Direction::IN, 0);
new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback);
#endif /* RPI_LOOPBACK_TEST_GPIO == 1 */
new SpiComIF(objects::SPI_COM_IF, gpioIF);
#if RPI_TEST_ACS_BOARD == 1
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN,
"MGM_0_LIS3", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN,
"MGM_1_RM3100", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN,
"MGM_2_LIS3", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN,
"MGM_3_RM3100", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN,
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN,
"GYRO_1_L3G", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_2_L3G_CS, gpio::GYRO_2_BCM_PIN,
"GYRO_2_L3G", gpio::Direction::OUT, 1);
gpioIF->addGpios(gpioCookieAcsBoard);
std::string spiDev = "/dev/spidev0.0";
SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
auto mgmLis3Handler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER,
objects::SPI_COM_IF, spiCookie);
mgmLis3Handler->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev,
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
auto mgmRm3100Handler = new MGMHandlerRM3100(objects::MGM_1_RM3100_HANDLER,
objects::SPI_COM_IF, spiCookie);
mgmRm3100Handler->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev,
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF,
spiCookie);
gyroL3gHandler->setStartUpImmediately();
#endif /* RPI_TEST_ACS_BOARD == 1 */
}

View File

@ -0,0 +1,10 @@
target_sources(${TARGET_NAME} PRIVATE
print.c
)
target_include_directories(${TARGET_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -0,0 +1,38 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2019 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_PROFILE_H__
#define __ETL_PROFILE_H__
#define ETL_CHECK_PUSH_POP
#define ETL_CPP11_SUPPORTED 1
#define ETL_NO_NULLPTR_SUPPORT 0
#endif

View File

@ -0,0 +1,14 @@
#ifndef LINUX_GCOV_H_
#define LINUX_GCOV_H_
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#ifdef GCOV
extern "C" void __gcov_flush();
#else
void __gcov_flush() {
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
"coverage information is desired.\n" << std::flush;
}
#endif
#endif /* LINUX_GCOV_H_ */

View File

@ -0,0 +1,14 @@
#include <bsp_q7s/boardconfig/print.h>
#include <stdio.h>
void printChar(const char* character, bool errStream) {
if(errStream) {
putc(*character, stderr);
return;
}
putc(*character, stdout);
}

View File

@ -0,0 +1,24 @@
#ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_
#define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_
#include <cstdint>
#define RPI_ADD_GPIO_TEST 0
#define RPI_LOOPBACK_TEST_GPIO 0
/* Only one of those 2 should be enabled! */
#define RPI_ADD_SPI_TEST 0
#define RPI_TEST_ACS_BOARD 0
/* Adapt these values accordingly */
namespace gpio {
static constexpr uint8_t MGM_0_BCM_PIN = 0;
static constexpr uint8_t MGM_1_BCM_PIN = 1;
static constexpr uint8_t MGM_2_BCM_PIN = 17;
static constexpr uint8_t MGM_3_BCM_PIN = 27;
static constexpr uint8_t GYRO_0_BCM_PIN = 5;
static constexpr uint8_t GYRO_1_BCM_PIN = 6;
static constexpr uint8_t GYRO_2_BCM_PIN = 4;
}
#endif /* BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ */

View File

@ -0,0 +1,6 @@
target_sources(${TARGET_NAME} PRIVATE
)

View File

@ -0,0 +1,8 @@
target_sources(${TARGET_NAME} PUBLIC
)

28
bsp_rpi/main.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "InitMission.h"
#include <OBSWVersion.h>
#include <fsfw/tasks/TaskFactory.h>
#include <iostream>
/**
* @brief This is the main program and entry point for the Raspberry Pi.
* @return
*/
int main(void)
{
std::cout << "-- EIVE OBSW --" << std::endl;
std::cout << "-- Compiled for Linux (Raspberry Pi) --" << std::endl;
std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "."
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl;
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
initmission::initMission();
for(;;) {
/* Suspend main thread by sleeping it. */
TaskFactory::delayTask(5000);
}
}

45
cmake/BuildType.cmake Normal file
View File

@ -0,0 +1,45 @@
function(set_build_type)
message(STATUS "Used build generator: ${CMAKE_GENERATOR}")
# Set a default build type if none was specified
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(DEFAULT_BUILD_TYPE "Debug")
endif()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS
"Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified."
)
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE
STRING "Choose the type of build." FORCE
)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo"
)
endif()
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
message(STATUS
"Building Debug application with flags: ${CMAKE_C_FLAGS_DEBUG}"
)
elseif(${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo")
message(STATUS
"Building Release (Debug) application with "
"flags: ${CMAKE_C_FLAGS_RELWITHDEBINFO}"
)
elseif(${CMAKE_BUILD_TYPE} MATCHES "MinSizeRel")
message(STATUS
"Building Release (Size) application with "
"flags: ${CMAKE_C_FLAGS_MINSIZEREL}"
)
else()
message(STATUS
"Building Release (Speed) application with "
"flags: ${CMAKE_C_FLAGS_RELEASE}"
)
endif()
endfunction()

View File

@ -0,0 +1,62 @@
function(post_source_hw_os_config)
if(LINK_LWIP)
message(STATUS "Linking against ${LIB_LWIP_NAME} lwIP library")
if(LIB_LWIP_NAME)
target_link_libraries(${TARGET_NAME} PUBLIC
${LIB_LWIP_NAME}
)
else()
message(WARNING "lwIP library name not set!")
endif()
endif()
if(LINK_HAL)
message(STATUS "Linking against ${LIB_HAL_NAME} HAL library")
if(LIB_HAL_NAME)
target_link_libraries(${TARGET_NAME} PUBLIC
${LIB_HAL_NAME}
)
else()
message(WARNING "HAL library name not set!")
endif()
endif()
if(LINKER_SCRIPT)
target_link_options(${TARGET_NAME} PRIVATE
-T${LINKER_SCRIPT}
)
endif()
set(C_FLAGS "" CACHE INTERNAL "C flags")
set(C_DEFS ""
CACHE INTERNAL
"C Defines"
)
set(CXX_FLAGS ${C_FLAGS})
set(CXX_DEFS ${C_DEFS})
if(CMAKE_VERBOSE)
message(STATUS "C Flags: ${C_FLAGS}")
message(STATUS "CXX Flags: ${CXX_FLAGS}")
message(STATUS "C Defs: ${C_DEFS}")
message(STATUS "CXX Defs: ${CXX_DEFS}")
endif()
# Generator expression. Can be used to set different C, CXX and ASM flags.
target_compile_options(${TARGET_NAME} PRIVATE
$<$<COMPILE_LANGUAGE:C>:${C_DEFS} ${C_FLAGS}>
$<$<COMPILE_LANGUAGE:CXX>:${CXX_DEFS} ${CXX_FLAGS}>
$<$<COMPILE_LANGUAGE:ASM>:${ASM_FLAGS}>
)
add_custom_command(
TARGET ${TARGET_NAME}
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET_NAME} ${TARGET_NAME}.bin
COMMENT "Generating binary file ${CMAKE_PROJECT_NAME}.bin.."
)
endfunction()

View File

@ -0,0 +1,70 @@
function(pre_source_hw_os_config)
# FreeRTOS
if(${OS_FSFW} MATCHES freertos)
message(FATAL_ERROR "No FreeRTOS support implemented yet.")
# RTEMS
elseif(${OS_FSFW} STREQUAL rtems)
add_definitions(-DRTEMS)
message(FATAL_ERROR "No RTEMS support implemented yet.")
elseif(${OS_FSFW} STREQUAL linux)
add_definitions(-DUNIX -DLINUX)
find_package(Threads REQUIRED)
# Hosted
else()
set(BSP_PATH "bsp_hosted")
if(WIN32)
add_definitions(-DWIN32)
elseif(UNIX)
find_package(Threads REQUIRED)
add_definitions(-DUNIX -DLINUX)
endif()
endif()
# Cross-compile information
if(CMAKE_CROSSCOMPILING)
# set(CMAKE_VERBOSE TRUE)
message(STATUS "Cross-compiling for ${TGT_BSP} target")
message(STATUS "Cross-compile gcc: ${CMAKE_C_COMPILER}")
message(STATUS "Cross-compile g++: ${CMAKE_CXX_COMPILER}")
if(CMAKE_VERBOSE)
message(STATUS "Cross-compile linker: ${CMAKE_LINKER}")
message(STATUS "Cross-compile size utility: ${CMAKE_SIZE}")
message(STATUS "Cross-compile objcopy utility: ${CMAKE_OBJCOPY}")
message(STATUS "Cross-compile ranlib utility: ${CMAKE_RANLIB}")
message(STATUS "Cross-compile ar utility: ${CMAKE_AR}")
message(STATUS "Cross-compile nm utility: ${CMAKE_NM}")
message(STATUS "Cross-compile strip utility: ${CMAKE_STRIP}")
message(STATUS
"Cross-compile assembler: ${CMAKE_ASM_COMPILER} "
"-x assembler-with-cpp"
)
message(STATUS "ABI flags: ${ABI_FLAGS}")
message(STATUS "Custom linker script: ${LINKER_SCRIPT}")
endif()
set_property(CACHE TGT_BSP
PROPERTY STRINGS
"arm/q7s" "arm/raspberrypi"
)
endif()
if(TGT_BSP)
if (${TGT_BSP} MATCHES "arm/raspberrypi")
set(BSP_PATH "bsp_rpi")
elseif(${TGT_BSP} MATCHES "arm/q7s")
set(BSP_PATH "bsp_q7s")
else()
message(WARNING "CMake not configured for this target!")
message(FATAL_ERROR "Target: ${TGT_BSP}!")
endif()
else()
set(BSP_PATH "bsp_hosted")
endif()
set(BSP_PATH ${BSP_PATH} PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,59 @@
function(pre_project_config)
# Basic input sanitization
if(DEFINED TGT_BSP)
if(${TGT_BSP} MATCHES "arm/raspberrypi" AND NOT ${OS_FSFW} MATCHES linux)
message(STATUS "FSFW OSAL invalid for specified target BSP ${TGT_BSP}!")
message(STATUS "Setting valid OS_FSFW: linux")
set(OS_FSFW "linux")
endif()
endif()
# Disable compiler checks for cross-compiling.
if(${OS_FSFW} STREQUAL linux AND TGT_BSP)
if(${TGT_BSP} MATCHES "arm/q7s")
set(CMAKE_TOOLCHAIN_FILE
"${CMAKE_SCRIPT_PATH}/Q7SCrossCompileConfig.cmake"
PARENT_SCOPE
)
elseif (${TGT_BSP} MATCHES "arm/raspberrypi")
if(NOT DEFINED ENV{RASPBIAN_ROOTFS})
if(NOT DEFINED RASPBIAN_ROOTFS)
message(WARNING "No RASPBIAN_ROOTFS environmental or CMake variable set!")
set(ENV{RASPBIAN_ROOTFS} "$ENV{HOME}/raspberrypi/rootfs")
else()
set(ENV{RASPBIAN_ROOTFS} "${RASPBIAN_ROOTFS}")
endif()
else()
message(STATUS
"RASPBIAN_ROOTFS from environmental variables used: $ENV{RASPBIAN_ROOTFS}"
)
endif()
if(NOT DEFINED ENV{RASPBERRY_VERSION})
if(NOT RASPBERRY_VERSION)
message(STATUS "No RASPBERRY_VERSION specified, setting to 4")
set(RASPBERRY_VERSION "4" CACHE STRING "Raspberry Pi version")
else()
message(STATUS "Setting RASPBERRY_VERSION to ${RASPBERRY_VERSION}")
set(RASPBERRY_VERSION ${RASPBERRY_VERSION} CACHE STRING "Raspberry Pi version")
set(ENV{RASPBERRY_VERSION} ${RASPBERRY_VERSION})
endif()
else()
message(STATUS
"RASPBERRY_VERSION from environmental variables used: "
"$ENV{RASPBERRY_VERSION}"
)
endif()
set(CMAKE_TOOLCHAIN_FILE
"${CMAKE_SCRIPT_PATH}/RPiCrossCompileConfig.cmake"
PARENT_SCOPE
)
else()
message(WARNING "Target BSP (TGT_BSP) ${TGT_BSP} unknown!")
endif()
endif()
endfunction()

View File

@ -0,0 +1,88 @@
# CROSS_COMPILE also needs to be set accordingly or passed to the CMake command
if(NOT DEFINED ENV{Q7S_SYSROOT})
# message(FATAL_ERROR
# "Define the Q7S_ROOTFS variable to "
# "point to the raspbian rootfs."
# )
else()
set(SYSROOT_PATH "$ENV{Q7S_SYSROOT}")
endif()
if(NOT DEFINED ENV{CROSS_COMPILE})
set(CROSS_COMPILE "arm-linux-gnueabihf")
message(STATUS
"No CROSS_COMPILE environmental variable set, using default ARM linux "
"cross compiler name ${CROSS_COMPILE}"
)
else()
set(CROSS_COMPILE "$ENV{CROSS_COMPILE}")
message(STATUS
"Using environmental variable CROSS_COMPILE as cross-compiler: "
"$ENV{CROSS_COMPILE}"
)
endif()
message(STATUS "Using sysroot path: ${SYSROOT_PATH}")
set(CROSS_COMPILE_CC "${CROSS_COMPILE}-gcc")
set(CROSS_COMPILE_CXX "${CROSS_COMPILE}-g++")
set(CROSS_COMPILE_LD "${CROSS_COMPILE}-ld")
set(CROSS_COMPILE_AR "${CROSS_COMPILE}-ar")
set(CROSS_COMPILE_RANLIB "${CROSS_COMPILE}-ranlib")
set(CROSS_COMPILE_STRIP "${CROSS_COMPILE}-strip")
set(CROSS_COMPILE_NM "${CROSS_COMPILE}-nm")
set(CROSS_COMPILE_OBJCOPY "${CROSS_COMPILE}-objcopy")
set(CROSS_COMPILE_SIZE "${CROSS_COMPILE}-size")
# At the very least, cross compile gcc and g++ have to be set!
find_program (CROSS_COMPILE_CC_FOUND ${CROSS_COMPILE_CC} REQUIRED)
find_program (CROSS_COMPILE_CXX_FOUND ${CROSS_COMPILE_CXX} REQUIRED)
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_SYSROOT "${SYSROOT_PATH}")
# Define name of the target system
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "armv7")
# Define the compiler
set(CMAKE_C_COMPILER ${CROSS_COMPILE_CC})
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX})
# List of library dirs where LD has to look. Pass them directly through gcc.
set(LIB_DIRS
"${SYSROOT_PATH}/usr/include"
"${SYSROOT_PATH}/usr/include/linux"
"${SYSROOT_PATH}/usr/lib"
"${SYSROOT_PATH}/lib"
"${SYSROOT_PATH}"
"${SYSROOT_PATH}/usr/lib/arm-xiphos-linux-gnueabi"
)
# You can additionally check the linker paths if you add the
# flags ' -Xlinker --verbose'
set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/lib")
foreach(LIB ${LIB_DIRS})
set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}")
endforeach()
set(CMAKE_PREFIX_PATH
"${CMAKE_PREFIX_PATH}"
# "${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
)
set(CMAKE_C_FLAGS
"-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS} -lgpiod"
CACHE STRING "C flags for Q7S"
)
set(CMAKE_CXX_FLAGS
"${CMAKE_C_FLAGS}"
CACHE STRING "CPP flags for Q7S"
)
# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -0,0 +1,146 @@
# Based on https://github.com/Pro/raspi-toolchain but rewritten completely.
# Adapted for the FSFW Example
if(NOT $ENV{RASPBERRY_VERSION})
message(STATUS "Raspberry Pi version not specified, setting version 4!")
set(RASPBERRY_VERSION 4)
else()
set(RASPBERRY_VERSION $ENV{RASPBERRY_VERSION})
endif()
# RASPBIAN_ROOTFS should point to the local directory which contains all the
# libraries and includes from the target raspi.
# The following command can be used to do this, replace <ip-address> and the
# local <rootfs-path> accordingly:
# rsync -vR --progress -rl --delete-after --safe-links pi@<ip-address>:/{lib,usr,opt/vc/lib} <rootfs-path>
# RASPBIAN_ROOTFS needs to be passed to the CMake command or defined in the
# application CMakeLists.txt before loading the toolchain file.
# CROSS_COMPILE also needs to be set accordingly or passed to the CMake command
if(NOT DEFINED ENV{RASPBIAN_ROOTFS})
message(FATAL_ERROR
"Define the RASPBIAN_ROOTFS variable to "
"point to the raspbian rootfs."
)
else()
set(SYSROOT_PATH "$ENV{RASPBIAN_ROOTFS}")
endif()
if(NOT DEFINED ENV{CROSS_COMPILE})
set(CROSS_COMPILE "arm-linux-gnueabihf")
message(STATUS
"No CROSS_COMPILE environmental variable set, using default ARM linux "
"cross compiler name ${CROSS_COMPILE}"
)
else()
set(CROSS_COMPILE "$ENV{CROSS_COMPILE}")
message(STATUS
"Using environmental variable CROSS_COMPILE as cross-compiler: "
"$ENV{CROSS_COMPILE}"
)
endif()
message(STATUS "Using sysroot path: ${SYSROOT_PATH}")
set(CROSS_COMPILE_CC "${CROSS_COMPILE}-gcc")
set(CROSS_COMPILE_CXX "${CROSS_COMPILE}-g++")
set(CROSS_COMPILE_LD "${CROSS_COMPILE}-ld")
set(CROSS_COMPILE_AR "${CROSS_COMPILE}-ar")
set(CROSS_COMPILE_RANLIB "${CROSS_COMPILE}-ranlib")
set(CROSS_COMPILE_STRIP "${CROSS_COMPILE}-strip")
set(CROSS_COMPILE_NM "${CROSS_COMPILE}-nm")
set(CROSS_COMPILE_OBJCOPY "${CROSS_COMPILE}-objcopy")
set(CROSS_COMPILE_SIZE "${CROSS_COMPILE}-size")
# At the very least, cross compile gcc and g++ have to be set!
find_program (CROSS_COMPILE_CC_FOUND ${CROSS_COMPILE_CC} REQUIRED)
find_program (CROSS_COMPILE_CXX_FOUND ${CROSS_COMPILE_CXX} REQUIRED)
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_SYSROOT "${SYSROOT_PATH}")
# Define name of the target system
set(CMAKE_SYSTEM_NAME "Linux")
if(RASPBERRY_VERSION VERSION_GREATER 1)
set(CMAKE_SYSTEM_PROCESSOR "armv7")
else()
set(CMAKE_SYSTEM_PROCESSOR "arm")
endif()
# Define the compiler
set(CMAKE_C_COMPILER ${CROSS_COMPILE_CC})
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX})
# List of library dirs where LD has to look. Pass them directly through gcc.
# LD_LIBRARY_PATH is not evaluated by arm-*-ld
set(LIB_DIRS
"/opt/cross-pi-gcc/arm-linux-gnueabihf/lib"
"/opt/cross-pi-gcc/lib"
"${SYSROOT_PATH}/opt/vc/lib"
"${SYSROOT_PATH}/lib/${CROSS_COMPILE}"
"${SYSROOT_PATH}/usr/local/lib"
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
"${SYSROOT_PATH}/usr/lib"
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}/blas"
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}/lapack"
)
# You can additionally check the linker paths if you add the
# flags ' -Xlinker --verbose'
set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/include")
foreach(LIB ${LIB_DIRS})
set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}")
endforeach()
set(CMAKE_PREFIX_PATH
"${CMAKE_PREFIX_PATH}"
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
)
if(RASPBERRY_VERSION VERSION_GREATER 3)
set(CMAKE_C_FLAGS
"-mcpu=cortex-a72 -mfpu=neon-vfpv4 -mfloat-abi=hard ${COMMON_FLAGS}"
CACHE STRING "CPP flags for Raspberry PI 4"
)
set(CMAKE_CXX_FLAGS
"${CMAKE_C_FLAGS}"
CACHE STRING "C flags for Raspberry PI 4"
)
elseif(RASPBERRY_VERSION VERSION_GREATER 2)
set(CMAKE_C_FLAGS
"-mcpu=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard ${COMMON_FLAGS}"
CACHE STRING "C flags for Raspberry PI 3"
)
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}"
CACHE STRING "CPP flags for Raspberry PI 3"
)
elseif(RASPBERRY_VERSION VERSION_GREATER 1)
set(CMAKE_C_FLAGS
"-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard ${COMMON_FLAGS}"
CACHE STRING "C flags for Raspberry PI 2"
)
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}"
CACHE STRING "CPP flags for Raspberry PI 2"
)
else()
set(CMAKE_C_FLAGS
"-mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard ${COMMON_FLAGS}"
CACHE STRING "C flags for Raspberry PI 1 B+ Zero"
)
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}"
CACHE STRING "CPP flags for Raspberry PI 1 B+ Zero"
)
endif()
set(CMAKE_FIND_ROOT_PATH
"${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH};${CMAKE_SYSROOT}"
)
# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
cmake/scripts/.idea/misc.xml generated Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>

8
cmake/scripts/.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/scripts.iml" filepath="$PROJECT_DIR$/.idea/scripts.iml" />
</modules>
</component>
</project>

8
cmake/scripts/.idea/scripts.iml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
cmake/scripts/.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
</component>
</project>

89
cmake/scripts/.idea/workspace.xml generated Normal file
View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="b7804b00-6384-4363-ae17-406610449420" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../../.." />
</component>
<component name="ProjectId" id="1mFLMh77EFiQ6e8GGJM4DSy44LC" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.tslint" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.path.for.package.tslint" value="project" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="node.js.selected.package.tslint" value="(autodetect)" />
</component>
<component name="RunManager">
<configuration name="cmake_build_config" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="scripts" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/cmake_build_config.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python.cmake_build_config" />
</list>
</recent_temporary>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="b7804b00-6384-4363-ae17-406610449420" name="Default Changelist" comment="" />
<created>1609084345199</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1609084345199</updated>
<workItem from="1609084346343" duration="6791000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/scripts$cmake_build_config.coverage" NAME="cmake_build_config Coverage Results" MODIFIED="1609089450693" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component>
</project>

View File

@ -0,0 +1,27 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "create_cmake_cfg.sh not found in upper directories!"
exit 1
fi
build_generator=""
build_dir="Debug-Host"
os_fsfw="host"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
fi
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l"${build_dir}"

View File

@ -0,0 +1,27 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "create_cmake_cfg.sh not found in upper directories!"
exit 1
fi
build_generator=""
os_fsfw="host"
build_dir="Release-Host"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
fi
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -l"${build_dir}"

View File

@ -0,0 +1,26 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "create_cmake_cfg.sh not found in upper directories!"
exit 1
fi
build_generator=""
os_fsfw="host"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
fi
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "reldeb"

View File

@ -0,0 +1,26 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "create_cmake_cfg.sh not found in upper directories!"
exit 1
fi
build_generator=""
os_fsfw="host"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
fi
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "size"

View File

@ -0,0 +1,25 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "create_cmake_cfg.sh not found in upper directories!"
exit 1
fi
build_generator="Unix Makefiles"
os_fsfw="linux"
builddir="Debug-Linux"
echo "Running command (without the leading +):"
set -x # Print command
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}"
# Use this if commands are added which should not be printed
# set +x

View File

@ -0,0 +1,25 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "create_cmake_cfg.sh not found in upper directories!"
exit 1
fi
build_generator="Unix Makefiles"
os_fsfw="linux"
builddir="Release-Linux"
echo "Running command (without the leading +):"
set -x # Print command
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}"
# Use this if commands are added which should not be printed
# set +x

View File

@ -0,0 +1,25 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "create_cmake_cfg.sh not found in upper directories!"
exit 1
fi
build_generator="Unix Makefiles"
os_fsfw="linux"
builddir="RelWithDeb-Linux"
echo "Running command (without the leading +):"
set -x # Print command
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}"
# Use this if commands are added which should not be printed
# set +x

View File

@ -0,0 +1,20 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "create_cmake_cfg.sh not found in upper directories!"
exit 1
fi
build_generator="Unix Makefiles"
os_fsfw="linux"
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "size"

Some files were not shown because too many files have changed in this diff Show More