mb_data.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. *********************************************************************************************************
  3. * uC/Modbus
  4. * The Embedded Modbus Stack
  5. *
  6. * Copyright 2003-2020 Silicon Laboratories Inc. www.silabs.com
  7. *
  8. * SPDX-License-Identifier: APACHE-2.0
  9. *
  10. * This software is subject to an open source license and is distributed by
  11. * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
  12. * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
  13. *
  14. *********************************************************************************************************
  15. */
  16. /*
  17. *********************************************************************************************************
  18. * uC/MODBUS TARGET SPECIFIC DATA ACCESS FUNCTIONS (Template)
  19. *
  20. * Filename : mb_data.c
  21. * Version : V2.14.00
  22. *********************************************************************************************************
  23. * Note(s) :
  24. *********************************************************************************************************
  25. */
  26. #include "mb.h"
  27. /*
  28. *********************************************************************************************************
  29. * GET THE VALUE OF A SINGLE COIL
  30. *
  31. * Description: This function returns the value of a single coil.
  32. * It is called by 'MBS_FC01_CoilRd()'.
  33. * You must 'map' the 'coil' to the actual application's coil.
  34. *
  35. * Arguments : coil is the coil number that is being requested.
  36. *
  37. * perr is a pointer to an error code variable. You must either return:
  38. *
  39. * MODBUS_ERR_NONE the specified coil is valid and you are returning its value.
  40. * MODBUS_ERR_RANGE the specified coil is an invalid coil number in your
  41. * application (i.e. product). YOUR product defines what the
  42. * valid range of values is for the 'coil' argument.
  43. *
  44. * Note(s) : 1) You can perform the mapping of coil number to application coils directly in this
  45. * function or via a table lookup. A table lookup would make sense if you had a lot of
  46. * coils in your product.
  47. *********************************************************************************************************
  48. */
  49. #if (MODBUS_CFG_FC01_EN == DEF_ENABLED)
  50. CPU_BOOLEAN MB_CoilRd (CPU_INT16U coil,
  51. CPU_INT16U *perr)
  52. {
  53. CPU_BOOLEAN coil_val;
  54. switch (coil) {
  55. case 0:
  56. coil_val = DEF_TRUE;
  57. break;
  58. case 1:
  59. coil_val = DEF_FALSE;
  60. break;
  61. case 2:
  62. coil_val = DEF_TRUE;
  63. break;
  64. default:
  65. case 3:
  66. coil_val = DEF_FALSE;
  67. break;
  68. }
  69. *perr = MODBUS_ERR_NONE;
  70. return (coil_val);
  71. }
  72. #endif
  73. /*
  74. *********************************************************************************************************
  75. * SET THE VALUE OF A SINGLE COIL
  76. *
  77. * Description: This function changes the value of a single coil.
  78. * It is called by 'MBS_FC05_CoilWr()' and 'MBS_FC15_CoilWrMultiple()'.
  79. * You must 'map' the 'coil' to the actual application's coil.
  80. *
  81. * Arguments : coil is the coil number that needs to be changed.
  82. *
  83. * coil_val is the desired value of the coil. This value can be either DEF_TRUE or DEF_FALSE with
  84. * DEF_TRUE indicating an energized coil.
  85. *
  86. * perr is a pointer to an error code variable. You must either return:
  87. *
  88. * MODBUS_ERR_NONE the specified coil is valid and your code changed the value
  89. * of the coil.
  90. * MODBUS_ERR_RANGE the specified coil is an invalid coil number in your
  91. * application (i.e. product). YOUR product defines what the
  92. * valid range of values is for the 'coil' argument.
  93. * MODBUS_ERR_WR if the device is not able to write or accept the value
  94. *
  95. * Note(s) : 1) You can perform the mapping of coil number to application coils directly in this
  96. * function or via a table lookup. A table lookup would make sense if you had a lot of
  97. * coils in your product.
  98. *********************************************************************************************************
  99. */
  100. #if (MODBUS_CFG_FC05_EN == DEF_ENABLED) || \
  101. (MODBUS_CFG_FC15_EN == DEF_ENABLED)
  102. void MB_CoilWr (CPU_INT16U coil,
  103. CPU_BOOLEAN coil_val,
  104. CPU_INT16U *perr)
  105. {
  106. (void)coil;
  107. (void)coil_val;
  108. *perr = MODBUS_ERR_NONE;
  109. }
  110. #endif
  111. /*
  112. *********************************************************************************************************
  113. * GET THE VALUE OF A SINGLE DISCRETE INPUT
  114. *
  115. * Description: This function reads the value of a single DI (DI means Discrete Input).
  116. * It is called by 'MBS_FC02_DIRd()'.
  117. * You must 'map' the 'di' to the actual application's DI.
  118. *
  119. * Arguments : di is the Discrete Input number that needs to be read.
  120. *
  121. * perr is a pointer to an error code variable. You must either return:
  122. *
  123. * MODBUS_ERR_NONE the specified DI is valid and your code is returning its
  124. * current value.
  125. * MODBUS_ERR_RANGE the specified DI is an invalid Discrete Input number in your
  126. * application (i.e. product). YOUR product defines what the
  127. * valid range of values is for the 'di' argument.
  128. *
  129. * Note(s) : 1) You can perform the mapping of DI number to the application DIs directly in this function
  130. * or via a table lookup. A table lookup would make sense if you had a lot of Discrete
  131. * Inputs in your product.
  132. *********************************************************************************************************
  133. */
  134. #if (MODBUS_CFG_FC02_EN == DEF_ENABLED)
  135. CPU_BOOLEAN MB_DIRd (CPU_INT16U di,
  136. CPU_INT16U *perr)
  137. {
  138. (void)di;
  139. *perr = MODBUS_ERR_NONE;
  140. return (DEF_FALSE);
  141. }
  142. #endif
  143. /*
  144. *********************************************************************************************************
  145. * GET THE VALUE OF A SINGLE INPUT REGISTER
  146. *
  147. * Description: This function reads the value of a single Input Register.
  148. * It is called by 'MBS_FC04_InRegRd()' when the argument 'reg' is BELOW the value set by
  149. * the configuration constant MODBUS_CFG_FP_START_IX (see MB_CFG.H).
  150. * You must 'map' the Input Register to the actual application's corresponding integer register.
  151. *
  152. * Arguments : reg is the Input Register number that needs to be read.
  153. *
  154. * perr is a pointer to an error code variable. You must either return:
  155. *
  156. * MODBUS_ERR_NONE the specified input register is valid and your code is
  157. * returning its current value.
  158. * MODBUS_ERR_RANGE the specified input register is an invalid number in your
  159. * application (i.e. product). YOUR product defines what the
  160. * valid range of values is for the 'reg' argument.
  161. *
  162. * Note(s) : 1) You can perform the mapping of input register number to the application's input registers
  163. * directly in this function or via a table lookup. A table lookup would make sense if you
  164. * had a lot of Input Registers in your product.
  165. * 2) If your product doesn't have input registers, you could simply set '*err' to
  166. * MODBUS_ERR_NONE and return 0.
  167. *********************************************************************************************************
  168. */
  169. #if (MODBUS_CFG_FC04_EN == DEF_ENABLED)
  170. CPU_INT16U MB_InRegRd (CPU_INT16U reg,
  171. CPU_INT16U *perr)
  172. {
  173. CPU_INT16U val;
  174. CPU_SR cpu_sr;
  175. OS_ERR err;
  176. switch (reg) {
  177. case 10:
  178. #if OS_CFG_STAT_TASK_EN > 0u
  179. CPU_CRITICAL_ENTER();
  180. val = (CPU_INT16U)(OSStatTaskCPUUsage/100);
  181. CPU_CRITICAL_EXIT();
  182. #else
  183. val = (CPU_INT16U)0;
  184. #endif
  185. break;
  186. case 11:
  187. #if 0
  188. CPU_CRITICAL_ENTER();
  189. val = (CPU_INT16U)OSCtxSwCtr;
  190. CPU_CRITICAL_EXIT();
  191. #else
  192. val = (CPU_INT16U)0;
  193. #endif
  194. break;
  195. case 12:
  196. CPU_CRITICAL_ENTER();
  197. val = (CPU_INT16U)(OSTimeGet(&err) >> 16);
  198. CPU_CRITICAL_EXIT();
  199. break;
  200. case 13:
  201. CPU_CRITICAL_ENTER();
  202. val = (CPU_INT16U)(OSTimeGet(&err) & 0x0000FFFF);
  203. CPU_CRITICAL_EXIT();
  204. break;
  205. case 14:
  206. CPU_CRITICAL_ENTER();
  207. val = (CPU_INT16U)MB_ChSize;
  208. CPU_CRITICAL_EXIT();
  209. break;
  210. case 15:
  211. CPU_CRITICAL_ENTER();
  212. val = (CPU_INT16U)(MB_TotalRAMSize & 0x0000FFFF);
  213. CPU_CRITICAL_EXIT();
  214. break;
  215. default:
  216. val = 0;
  217. break;
  218. }
  219. *perr = MODBUS_ERR_NONE;
  220. return (val);
  221. }
  222. #endif
  223. /*
  224. *********************************************************************************************************
  225. * GET THE VALUE OF A SINGLE 'FLOATING-POINT' INPUT REGISTER
  226. *
  227. * Description: This function reads the value of a single Input Register.
  228. * It is called by 'MBS_FC04_InRegRd()' when the argument 'reg' is ABOVE or equal to the
  229. * value set the configuration constant MODBUS_CFG_FP_START_IX (see MB_CFG.H).
  230. * You must 'map' the Input Register to the actual application's corresponding floating-point
  231. * register.
  232. *
  233. * Arguments : reg is the Input Register number that needs to be read.
  234. *
  235. * perr is a pointer to an error code variable. You must either return:
  236. *
  237. * MODBUS_ERR_NONE the specified input register is valid and your code is
  238. * returning its current value.
  239. * MODBUS_ERR_RANGE the specified input register is an invalid number in your
  240. * application (i.e. product). YOUR product defines what the
  241. * valid range of values is for the 'reg' argument.
  242. *
  243. * Note(s) : 1) You can perform the mapping of input register number to the application's input registers
  244. * directly in this function or via a table lookup. A table lookup would make sense if you
  245. * had a lot of Input Registers in your product.
  246. * 2) If your product doesn't have input registers, you could simply set '*err' to
  247. * MODBUS_ERR_NONE and return (CPU_FP32)0.
  248. *********************************************************************************************************
  249. */
  250. #if (MODBUS_CFG_FP_EN == DEF_ENABLED)
  251. #if (MODBUS_CFG_FC04_EN == DEF_ENABLED)
  252. CPU_FP32 MB_InRegRdFP (CPU_INT16U reg,
  253. CPU_INT16U *perr)
  254. {
  255. (void)reg;
  256. *perr = MODBUS_ERR_NONE;
  257. return ((CPU_FP32)0);
  258. }
  259. #endif
  260. #endif
  261. /*
  262. *********************************************************************************************************
  263. * GET THE VALUE OF A SINGLE HOLDING REGISTER
  264. *
  265. * Description: This function reads the value of a single Holding Register.
  266. * It is called by 'MBS_FC03_HoldingRegRd()' when the argument 'reg' is BELOW the value set
  267. * by the configuration constant MODBUS_CFG_FP_START_IX (see MB_CFG.H).
  268. * You must 'map' the Holding Register to the actual application's corresponding integer register.
  269. *
  270. * Arguments : reg is the Holding Register number that needs to be read.
  271. *
  272. * perr is a pointer to an error code variable. You must either return:
  273. *
  274. * MODBUS_ERR_NONE the specified holding register is valid and your code is
  275. * returning its current value.
  276. * MODBUS_ERR_RANGE the specified holding register is an invalid number in your
  277. * application (i.e. product). YOUR product defines what the
  278. * valid range of values is for the 'reg' argument.
  279. *
  280. * Note(s) : 1) You can perform the mapping of holding register number to the application's holding
  281. * registers directly in this function or via a table lookup. A table lookup would make
  282. * sense if you had a lot of Holding Registers in your product.
  283. * 2) If your product doesn't have holding registers, you could simply set '*err' to
  284. * MODBUS_ERR_NONE and return 0.
  285. *********************************************************************************************************
  286. */
  287. #if (MODBUS_CFG_FC03_EN == DEF_ENABLED)
  288. CPU_INT16U MB_HoldingRegRd (CPU_INT16U reg,
  289. CPU_INT16U *perr)
  290. {
  291. CPU_INT16U val;
  292. CPU_SR cpu_sr;
  293. OS_ERR err;
  294. switch (reg) {
  295. case 0:
  296. #if OS_CFG_STAT_TASK_EN > 0u
  297. CPU_CRITICAL_ENTER();
  298. val = (CPU_INT16U)(OSStatTaskCPUUsage/100);
  299. CPU_CRITICAL_EXIT();
  300. #else
  301. val = (CPU_INT16U)0;
  302. #endif
  303. break;
  304. case 1:
  305. #if 0
  306. CPU_CRITICAL_ENTER();
  307. val = (CPU_INT16U)OSCtxSwCtr;
  308. CPU_CRITICAL_EXIT();
  309. #else
  310. val = (CPU_INT16U)0;
  311. #endif
  312. case 2:
  313. CPU_CRITICAL_ENTER();
  314. val = (CPU_INT16U)(OSTimeGet(&err) >> 16);
  315. CPU_CRITICAL_EXIT();
  316. break;
  317. case 3:
  318. CPU_CRITICAL_ENTER();
  319. val = (CPU_INT16U)(OSTimeGet(&err) & 0x0000FFFF);
  320. CPU_CRITICAL_EXIT();
  321. break;
  322. case 4:
  323. CPU_CRITICAL_ENTER();
  324. val = (CPU_INT16U)MB_ChSize;
  325. CPU_CRITICAL_EXIT();
  326. break;
  327. case 5:
  328. CPU_CRITICAL_ENTER();
  329. val = (CPU_INT16U)(MB_TotalRAMSize & 0x0000FFFF);
  330. CPU_CRITICAL_EXIT();
  331. break;
  332. case 6:
  333. CPU_CRITICAL_ENTER();
  334. val = (CPU_INT16U)((MB_ChTbl[0].RxCtr / 1000) & 0x0000FFFF);
  335. CPU_CRITICAL_EXIT();
  336. break;
  337. case 7:
  338. CPU_CRITICAL_ENTER();
  339. val = (CPU_INT16U)((MB_ChTbl[0].RxCtr % 1000) & 0x0000FFFF);
  340. CPU_CRITICAL_EXIT();
  341. break;
  342. case 8:
  343. CPU_CRITICAL_ENTER();
  344. val = (CPU_INT16U)((MB_ChTbl[0].TxCtr / 1000) & 0x0000FFFF);
  345. CPU_CRITICAL_EXIT();
  346. break;
  347. case 9:
  348. CPU_CRITICAL_ENTER();
  349. val = (CPU_INT16U)((MB_ChTbl[0].TxCtr % 1000) & 0x0000FFFF);
  350. CPU_CRITICAL_EXIT();
  351. break;
  352. default:
  353. val = 0;
  354. break;
  355. }
  356. *perr = MODBUS_ERR_NONE;
  357. return (val);
  358. }
  359. #endif
  360. /*
  361. *********************************************************************************************************
  362. * GET THE VALUE OF A SINGLE 'FLOATING-POINT' HOLDING REGISTER
  363. *
  364. * Description: This function reads the value of a single Floating-Point Holding Register.
  365. * It is called by 'MBS_FC03_HoldingRegRd()' when the argument 'reg' is ABOVE or equal to the
  366. * value set by the configuration constant MODBUS_CFG_FP_START_IX (see MB_CFG.H).
  367. * You must 'map' the Holding Register to the actual application's corresponding floating-point
  368. * register.
  369. *
  370. * Arguments : reg is the Holding Register number that needs to be read.
  371. *
  372. * perr is a pointer to an error code variable. You must either return:
  373. *
  374. * MODBUS_ERR_NONE the specified holding register is valid and your code is
  375. * returning its current value.
  376. * MODBUS_ERR_RANGE the specified holding register is an invalid number in your
  377. * application (i.e. product). YOUR product defines what the
  378. * valid range of values is for the 'reg' argument.
  379. *
  380. * Note(s) : 1) You can perform the mapping of holding register number to the application's holding
  381. * registers directly in this function or via a table lookup. A table lookup would make
  382. * sense if you had a lot of Holding Registers in your product.
  383. * 2) If your product doesn't have holding registers, you could simply set '*err' to
  384. * MODBUS_ERR_NONE and return 0.
  385. *********************************************************************************************************
  386. */
  387. #if (MODBUS_CFG_FP_EN == DEF_ENABLED)
  388. #if (MODBUS_CFG_FC03_EN == DEF_ENABLED)
  389. CPU_FP32 MB_HoldingRegRdFP (CPU_INT16U reg,
  390. CPU_INT16U *perr)
  391. {
  392. (void)reg;
  393. *perr = MODBUS_ERR_NONE;
  394. return ((CPU_FP32)0);
  395. }
  396. #endif
  397. #endif
  398. /*
  399. *********************************************************************************************************
  400. * SET THE VALUE OF A SINGLE HOLDING REGISTER
  401. *
  402. * Description: This function is called to change the value of a single Integer Holding Register.
  403. * It is called by 'MBS_FC06_HoldingRegWr()' and 'MBS_FC16_HoldingRegWrMultiple()' when the argument
  404. * 'reg' is BELOW to the value set by the configuration constant MODBUS_CFG_FP_START_IX (see MB_CFG.H).
  405. * You must 'map' the Holding Register to the actual application's corresponding integer register.
  406. *
  407. * Arguments : reg is the Holding Register number that needs to be read.
  408. *
  409. * reg_val is the desired value of the holding register.
  410. * The value is specified as an unsigned integer even though it could actually be
  411. * represented by a signed integer.
  412. *
  413. * perr is a pointer to an error code variable. You must either return:
  414. *
  415. * MODBUS_ERR_NONE the specified holding register is valid and your code is
  416. * returning its current value.
  417. * MODBUS_ERR_RANGE the specified holding register is an invalid number in your
  418. * application (i.e. product). YOUR product defines what the
  419. * valid range of values is for the 'reg' argument.
  420. * MODBUS_ERR_WR if the device is not able to write or accept the value
  421. *
  422. * Note(s) : 1) You can perform the mapping of holding register number to the application's holding
  423. * registers directly in this function or via a table lookup. A table lookup would make
  424. * sense if you had a lot of Holding Registers in your product.
  425. * 2) If your product doesn't have holding registers, you could simply set '*err' to
  426. * MODBUS_ERR_NONE and return 0.
  427. *********************************************************************************************************
  428. */
  429. #if (MODBUS_CFG_FC06_EN == DEF_ENABLED) || \
  430. (MODBUS_CFG_FC16_EN == DEF_ENABLED)
  431. void MB_HoldingRegWr (CPU_INT16U reg,
  432. CPU_INT16U reg_val_16,
  433. CPU_INT16U *perr)
  434. {
  435. /* Access to your variable here! */
  436. (void)reg;
  437. (void)reg_val_16;
  438. *perr = MODBUS_ERR_NONE;
  439. }
  440. #endif
  441. /*
  442. *********************************************************************************************************
  443. * SET THE VALUE OF A SINGLE 'FLOATING-POINT' HOLDING REGISTER
  444. *
  445. * Description: This function is called to change the value of a single Floating-Point Holding Register.
  446. * It is called by 'MBS_FC06_HoldingRegWr()' and 'MBS_FC16_HoldingRegWrMultiple()' when the argument
  447. * 'reg' is ABOVE or equal to the value set by the configuration constant MODBUS_CFG_FP_START_IX
  448. * (see MB_CFG.H).
  449. * You must 'map' the Holding Register to the actual application's corresponding floating-point
  450. * register.
  451. *
  452. * Arguments : reg is the Holding Register number that needs to be read.
  453. *
  454. * reg_val is the desired value of the holding register.
  455. * The value is specified as an unsigned integer even though it could actually be
  456. * represented by a signed integer.
  457. *
  458. * perr is a pointer to an error code variable. You must either return:
  459. *
  460. * MODBUS_ERR_NONE the specified holding register is valid and your code is
  461. * returning its current value.
  462. * MODBUS_ERR_RANGE the specified holding register is an invalid number in your
  463. * application (i.e. product). YOUR product defines what the
  464. * valid range of values is for the 'reg' argument.
  465. * MODBUS_ERR_WR if the device is not able to write or accept the value
  466. *
  467. * Note(s) : 1) You can perform the mapping of holding register number to the application's holding
  468. * registers directly in this function or via a table lookup. A table lookup would make
  469. * sense if you had a lot of Holding Registers in your product.
  470. * 2) If your product doesn't have holding registers, you could simply set '*err' to
  471. * MODBUS_ERR_NONE and return 0.
  472. *********************************************************************************************************
  473. */
  474. #if (MODBUS_CFG_FP_EN == DEF_ENABLED)
  475. #if (MODBUS_CFG_FC06_EN == DEF_ENABLED) || \
  476. (MODBUS_CFG_FC16_EN == DEF_ENABLED)
  477. void MB_HoldingRegWrFP (CPU_INT16U reg,
  478. CPU_FP32 reg_val_fp,
  479. CPU_INT16U *perr)
  480. {
  481. (void)reg;
  482. (void)reg_val_fp;
  483. *perr = MODBUS_ERR_RANGE;
  484. }
  485. #endif
  486. #endif
  487. /*
  488. *********************************************************************************************************
  489. * GET A SINGLE ENTRY FROM A RECORD IN A FILE
  490. *
  491. * Description: This function is called to read a single integer from a file.
  492. * As mentionned in the Modbus specifications, a file is an organization of records.
  493. * Each file can contain up to 10,000 records (addressed from 0 to 9999).
  494. * You must 'map' the File/Record/Ix to the actual application's corresponding data.
  495. *
  496. * Arguments : file_nbr is the number of the desired file.
  497. *
  498. * record_nbr is the desired record within the file
  499. *
  500. * ix is the desired entry in the specified record.
  501. *
  502. * record_len is the desired length of the record. Note that this parameter is passed to
  503. * this function to provide the 'requested' requested length from the MODBUS command.
  504. *
  505. * perr is a pointer to an error code variable. You must either return:
  506. *
  507. * MODBUS_ERR_NONE the specified file/record/entry is valid and your code is
  508. * returning its current value.
  509. * MODBUS_ERR_FILE if the specified 'file_nbr' is not a valid file number in
  510. * your product.
  511. * MODBUS_ERR_RECORD if the specified 'record_nbr' is not a valid record in the
  512. * specified file.
  513. * MODBUS_ERR_IX if the specified 'ix' is not a valid index into the specified
  514. * record.
  515. *
  516. * Note(s) : 1) You can perform the mapping of file/record/ix to the application's data directly in
  517. * this function or via a table lookup. A table lookup would make sense if you had a lot
  518. * data in your files.
  519. *********************************************************************************************************
  520. */
  521. #if (MODBUS_CFG_FC20_EN == DEF_ENABLED)
  522. CPU_INT16U MB_FileRd (CPU_INT16U file_nbr,
  523. CPU_INT16U record_nbr,
  524. CPU_INT16U ix,
  525. CPU_INT08U record_len,
  526. CPU_INT16U *perr)
  527. {
  528. (void)file_nbr;
  529. (void)record_nbr;
  530. (void)ix;
  531. (void)record_len;
  532. *perr = MODBUS_ERR_NONE;
  533. return (0);
  534. }
  535. #endif
  536. /*
  537. *********************************************************************************************************
  538. * SET A SINGLE ENTRY OF A RECORD IN A FILE
  539. *
  540. * Description: This function is called to change a single integer value in a file.
  541. * As mentionned in the Modbus specifications, a file is an organization of records.
  542. * Each file can contain up to 10,000 records (addressed from 0 to 9999).
  543. * You must 'map' the File/Record/Ix to the actual application's corresponding data.
  544. *
  545. * Arguments : file_nbr is the number of the desired file.
  546. *
  547. * record_nbr is the desired record within the file
  548. *
  549. * ix is the desired entry in the specified record.
  550. *
  551. * record_len is the desired length of the record. Note that this parameter is passed to
  552. * this function to provide the 'requested' requested length from the MODBUS command.
  553. *
  554. * val is the new value to place in the file.
  555. *
  556. * perr is a pointer to an error code variable. You must either return:
  557. *
  558. * MODBUS_ERR_NONE the specified file/record/entry is valid and your code is
  559. * returning its current value.
  560. * MODBUS_ERR_FILE if the specified 'file_nbr' is not a valid file number in
  561. * your product.
  562. * MODBUS_ERR_RECORD if the specified 'record_nbr' is not a valid record in the
  563. * specified file.
  564. * MODBUS_ERR_IX if the specified 'ix' is not a valid index into the specified
  565. * record.
  566. *
  567. * Note(s) : 1) You can perform the mapping of file/record/ix to the application's data directly in
  568. * this function or via a table lookup. A table lookup would make sense if you had a lot
  569. * data in your files.
  570. *********************************************************************************************************
  571. */
  572. #if (MODBUS_CFG_FC21_EN == DEF_ENABLED)
  573. void MB_FileWr (CPU_INT16U file_nbr,
  574. CPU_INT16U record_nbr,
  575. CPU_INT16U ix,
  576. CPU_INT08U record_len,
  577. CPU_INT16U val,
  578. CPU_INT16U *perr)
  579. {
  580. (void)file_nbr;
  581. (void)record_nbr;
  582. (void)ix;
  583. (void)record_len;
  584. (void)val;
  585. *perr = MODBUS_ERR_NONE;
  586. }
  587. #endif