app_utils.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*********************************************************************
  2. * _ _ _
  3. * _ __ | |_ _ | | __ _ | |__ ___
  4. * | '__|| __|(_)| | / _` || '_ \ / __|
  5. * | | | |_ _ | || (_| || |_) |\__ \
  6. * |_| \__|(_)|_| \__,_||_.__/ |___/
  7. *
  8. * www.rt-labs.com
  9. * Copyright 2021 rt-labs AB, Sweden.
  10. *
  11. * This software is dual-licensed under GPLv3 and a commercial
  12. * license. See the file LICENSE.md distributed with this software for
  13. * full license information.
  14. ********************************************************************/
  15. #ifndef APP_UTILS_H
  16. #define APP_UTILS_H
  17. /**
  18. * @file
  19. * @brief Application utilities and helper functions
  20. *
  21. * Functions for getting string representation of
  22. * P-Net events, error codes and more.
  23. *
  24. * API, slot and subslot administration.
  25. *
  26. * Initialization of P-Net configuration from app_gsdml.h.
  27. */
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31. #include "osal.h"
  32. #include "pnal.h"
  33. #include <pnet_api.h>
  34. typedef struct app_utils_netif_name
  35. {
  36. char name[PNET_INTERFACE_NAME_MAX_SIZE];
  37. } app_utils_netif_name_t;
  38. typedef struct app_utils_netif_namelist
  39. {
  40. app_utils_netif_name_t netif[PNET_MAX_PHYSICAL_PORTS + 1];
  41. } app_utils_netif_namelist_t;
  42. /* Forward declaration */
  43. typedef struct app_subslot app_subslot_t;
  44. /**
  45. * Callback for updated cyclic data
  46. *
  47. * @param subslot InOut: Subslot structure
  48. * @param tag InOut: Typically a handle to a submodule
  49. */
  50. typedef void (*app_utils_cyclic_callback) (app_subslot_t * subslot, void * tag);
  51. /**
  52. * Information of submodule plugged into a subslot.
  53. *
  54. * Note that submodule data is not stored here but must
  55. * be handled by the submodule implementation.
  56. *
  57. * All parameters are initialized by the app_utils_plug_submodule()
  58. * function.
  59. *
  60. * The cyclic_callback is used when app_utils_cyclic_data_poll()
  61. * is called. Typically on the tick event in the main task.
  62. * The \a tag parameter is passed with the cyclic_callback and
  63. * is typically a handle to a submodule on application.
  64. */
  65. typedef struct app_subslot
  66. {
  67. /** True when the position in the subslot array is occupied */
  68. bool used;
  69. /** True when the subslot is plugged */
  70. bool plugged;
  71. uint16_t slot_nbr;
  72. uint16_t subslot_nbr;
  73. uint32_t submodule_id;
  74. const char * submodule_name;
  75. pnet_data_cfg_t data_cfg;
  76. /** Status indicator from PLC */
  77. uint8_t indata_iocs;
  78. /** Status indicator from PLC */
  79. uint8_t outdata_iops;
  80. /** Callback for cyclic input- or output data, or NULL if not implemented */
  81. app_utils_cyclic_callback cyclic_callback;
  82. void * tag;
  83. } app_subslot_t;
  84. /**
  85. * Information of module plugged into a slot,
  86. * and array of subslots for admin of submodules.
  87. */
  88. typedef struct app_slot
  89. {
  90. bool plugged;
  91. uint32_t module_id;
  92. const char * name; /** Module name */
  93. /** Subslots. Use a separate index, as the subslot number might be large.
  94. * For example the subslot for DAP port 1 has number 0x8001 */
  95. app_subslot_t subslots[PNET_MAX_SUBSLOTS];
  96. } app_slot_t;
  97. /**
  98. * Profinet API state for application
  99. *
  100. * Used to manage plugged modules into slots (and submodules into subslots).
  101. */
  102. typedef struct app_api_t
  103. {
  104. uint32_t api_id;
  105. uint32_t arep;
  106. /** Slots. Use slot number as index */
  107. app_slot_t slots[PNET_MAX_SLOTS];
  108. } app_api_t;
  109. /**
  110. * Convert IP address to string
  111. * @param ip In: IP address
  112. * @param outputstring Out: Resulting string buffer. Should have size
  113. * PNAL_INET_ADDRSTR_SIZE.
  114. */
  115. void app_utils_ip_to_string (pnal_ipaddr_t ip, char * outputstring);
  116. /**
  117. * Get string description of data direction
  118. * @param direction In: Submodule data direction
  119. * @return String representation of data direction
  120. */
  121. const char * app_utils_submod_dir_to_string (pnet_submodule_dir_t direction);
  122. /**
  123. * Get string description of PNIO producer or consumer status
  124. * @param ioxs In: Producer or consumer status (IOPS/IOCS)
  125. * @return String representation of ioxs (IOPS/IOCS)
  126. */
  127. const char * app_utils_ioxs_to_string (pnet_ioxs_values_t ioxs);
  128. /**
  129. * Get string representation of application subslot in format
  130. * [slot,subslot,module name]
  131. * This function has an internal buffer for temp storage
  132. * of the generated string.
  133. * @param subslot In: Subslot
  134. * @return String representation of subslot.
  135. */
  136. char * app_utils_get_subslot_string (const app_subslot_t * subslot);
  137. /**
  138. * Convert MAC address to string
  139. * @param mac In: MAC address
  140. * @param outputstring Out: Resulting string buffer. Should have size
  141. * PNAL_ETH_ADDRSTR_SIZE.
  142. */
  143. void app_utils_mac_to_string (pnet_ethaddr_t mac, char * outputstring);
  144. /**
  145. * Convert error code to string format
  146. * Only common error codes supported.
  147. * Todo: Add rest of error codes.
  148. *
  149. * @param err_cls In: The error class. See PNET_ERROR_CODE_1_*
  150. * @param err_code In: The error code. See PNET_ERROR_CODE_2_*
  151. * @param err_cls_str Out: The error class string
  152. * @param err_code_str Out: The error code string
  153. */
  154. void app_utils_get_error_code_strings (
  155. uint16_t err_cls,
  156. uint16_t err_code,
  157. const char ** err_cls_str,
  158. const char ** err_code_str);
  159. /**
  160. * Copy an IP address (as an integer) to a struct
  161. * @param destination_struct Out: Destination
  162. * @param ip In: IP address
  163. */
  164. void app_utils_copy_ip_to_struct (
  165. pnet_cfg_ip_addr_t * destination_struct,
  166. pnal_ipaddr_t ip);
  167. /**
  168. * Return a string representation of
  169. * the given dcontrol command.
  170. * @param event In: control_command
  171. * @return A string representing the command
  172. */
  173. const char * app_utils_dcontrol_cmd_to_string (
  174. pnet_control_command_t control_command);
  175. /**
  176. * Return a string representation of the given event.
  177. * @param event In: event
  178. * @return A string representing the event
  179. */
  180. const char * app_utils_event_to_string (pnet_event_values_t event);
  181. /**
  182. * Update network configuration from a string
  183. * defining a list of network interfaces examples:
  184. * "eth0" or "br0,eth0,eth1"
  185. *
  186. * Read IP, netmask etc from operating system.
  187. *
  188. * @param netif_list_str In: Comma separated string of network ifs
  189. * @param if_list Out: Array of network ifs
  190. * @param number_of_ports Out: Number of ports
  191. * @param if_cfg Out: P-Net network configuration to be updated
  192. * @return 0 on success, -1 on error
  193. */
  194. int app_utils_pnet_cfg_init_netifs (
  195. const char * netif_list_str,
  196. app_utils_netif_namelist_t * if_list,
  197. uint16_t * number_of_ports,
  198. pnet_if_cfg_t * if_cfg);
  199. /**
  200. * Parse a comma separated list of network interfaces and check
  201. * that the number of interfaces match the PNET_MAX_PHYSICAL_PORTS
  202. * configuration.
  203. *
  204. * For a single Ethernet interface, the \a arg_str should consist of
  205. * one name. For two Ethernet interfaces, the \a arg_str should consist of
  206. * three names, as we also need a bridge interface.
  207. *
  208. * Does only consider the number of comma separated names. No check of the
  209. * names themselves are done.
  210. *
  211. * Examples:
  212. * arg_str num_ports
  213. * "eth0" 1
  214. * "eth0,eth1" error (We need a bridge as well)
  215. * "br0,eth0,eth1" 2
  216. *
  217. * @param arg_str In: Network interface list as comma separated,
  218. * terminated string. For example "eth0" or
  219. * "br0,eth0,eth1".
  220. * @param max_port In: PNET_MAX_PHYSICAL_PORTS, passed as argument to
  221. * allow test.
  222. * @param p_if_list Out: List of network interfaces
  223. * @param p_num_ports Out: Resulting number of physical ports
  224. * @return 0 on success
  225. * -1 on error
  226. */
  227. int app_utils_get_netif_namelist (
  228. const char * arg_str,
  229. uint16_t max_port,
  230. app_utils_netif_namelist_t * p_if_list,
  231. uint16_t * p_num_ports);
  232. /**
  233. * Print network configuration using APP_LOG_INFO().
  234. *
  235. * @param if_cfg In: Network configuration
  236. * @param number_of_ports In: Number of used ports
  237. */
  238. void app_utils_print_network_config (
  239. pnet_if_cfg_t * if_cfg,
  240. uint16_t number_of_ports);
  241. /**
  242. * Print message if IOXS has changed.
  243. *
  244. * Uses APP_LOG_INFO()
  245. *
  246. * @param subslot In: Subslot
  247. * @param ioxs_str In: String description Producer or Consumer
  248. * @param ioxs_current In: Current status
  249. * @param ioxs_new In: New status
  250. */
  251. void app_utils_print_ioxs_change (
  252. const app_subslot_t * subslot,
  253. const char * ioxs_str,
  254. uint8_t ioxs_current,
  255. uint8_t ioxs_new);
  256. /**
  257. * Init the p-net configuration to default values.
  258. *
  259. * Most values are picked from app_gsdml.h
  260. *
  261. * Network configuration not initialized.
  262. * This means that \a '.if_cfg' must be set by application.
  263. *
  264. * Use this function to init P-Net configuration before
  265. * before passing config to app_init().
  266. *
  267. * @param pnet_cfg Out: Configuration for use by p-net
  268. * @return 0 if the operation succeeded.
  269. * -1 if an error occurred.
  270. */
  271. int app_utils_pnet_cfg_init_default (pnet_cfg_t * pnet_cfg);
  272. /**
  273. * Plug application module
  274. *
  275. * This is for the application to remember which slots are
  276. * populated in the p-net stack.
  277. *
  278. * @param p_api InOut: API
  279. * @param slot_nbr In: Slot number
  280. * @param id In: Module identity
  281. * @param name In: Module name
  282. * @return 0 on success, -1 on error
  283. */
  284. int app_utils_plug_module (
  285. app_api_t * p_api,
  286. uint16_t slot_nbr,
  287. uint32_t id,
  288. const char * name);
  289. /**
  290. * Pull any application module in given slot.
  291. *
  292. * This is for the application to remember which slots are
  293. * populated in the p-net stack.
  294. *
  295. * @param p_api InOut: API
  296. * @param slot_nbr In: Slot number
  297. * @return 0 on success, -1 on error
  298. */
  299. int app_utils_pull_module (app_api_t * p_api, uint16_t slot_nbr);
  300. /**
  301. * Plug application submodule.
  302. *
  303. * This is for the application to remember which subslots are
  304. * populated in the p-net stack.
  305. *
  306. * @param p_api InOut: API
  307. * @param slot_nbr In: Slot number
  308. * @param subslot_nbr In: Subslot number
  309. * @param submodule_id In: Submodule identity
  310. * @param p_data_cfg In: Data configuration,
  311. * direction, in and out sizes
  312. * @param submodule_name In: Submodule name
  313. * @param cyclic_callback In: Submodule data callback
  314. * @param tag In: Tag passed in cyclic callback
  315. * Typically application or
  316. * submodule handle
  317. * @return Reference to allocated subslot,
  318. * NULL if no free subslot is available. This should
  319. * never happen if application is aligned with p-net state.
  320. */
  321. app_subslot_t * app_utils_plug_submodule (
  322. app_api_t * p_api,
  323. uint16_t slot_nbr,
  324. uint16_t subslot_nbr,
  325. uint32_t submodule_id,
  326. const pnet_data_cfg_t * p_data_cfg,
  327. const char * submodule_name,
  328. app_utils_cyclic_callback cyclic_callback,
  329. void * tag);
  330. /**
  331. * Unplug any application submodule from given subslot.
  332. *
  333. * This is for the application to remember which subslots are
  334. * populated in the p-net stack.
  335. *
  336. * @param p_api InOut: API
  337. * @param slot_nbr In: Slot number
  338. * @param subslot_nbr In: Subslot number
  339. * @return 0 on success, -1 on error.
  340. */
  341. int app_utils_pull_submodule (
  342. app_api_t * p_api,
  343. uint16_t slot_nbr,
  344. uint16_t subslot_nbr);
  345. /**
  346. * Trigger data callback for all plugged submodules in all slots.
  347. *
  348. * The callbacks given in \a app_utils_plug_submodule() are used.
  349. *
  350. * @param p_api In: API
  351. */
  352. void app_utils_cyclic_data_poll (app_api_t * p_api);
  353. /**
  354. * Get subslot application information.
  355. *
  356. * @param p_appdata InOut: Application state.
  357. * @param slot_nbr In: Slot number.
  358. * @param subslot_nbr In: Subslot number. Range 0 - 0x9FFF.
  359. * @return Reference to application subslot,
  360. * NULL if subslot is not found/plugged.
  361. */
  362. app_subslot_t * app_utils_subslot_get (
  363. app_api_t * p_api,
  364. uint16_t slot_nbr,
  365. uint16_t subslot_nbr);
  366. /**
  367. * Return true if subslot is input.
  368. *
  369. * @param p_subslot In: Reference to subslot.
  370. * @return true if subslot is input or input/output.
  371. * false if not.
  372. */
  373. bool app_utils_subslot_is_input (const app_subslot_t * p_subslot);
  374. /**
  375. * Return true if subslot is neither input or output.
  376. *
  377. * This is applies for DAP submodules/slots
  378. *
  379. * @param p_subslot In: Reference to subslot.
  380. * @return true if subslot is input or input/output.
  381. * false if not.
  382. */
  383. bool app_utils_subslot_is_no_io (const app_subslot_t * p_subslot);
  384. /**
  385. * Return true if subslot is output.
  386. *
  387. * @param p_subslot In: Reference to subslot.
  388. * @return true if subslot is output or input/output,
  389. * false if not.
  390. */
  391. bool app_utils_subslot_is_output (const app_subslot_t * p_subslot);
  392. #ifdef __cplusplus
  393. }
  394. #endif
  395. #endif /* APP_UTILS_H */