file_led.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /******************************************************************************
  2. 版权所有: 珠海欧力配网自动化股份有限公司
  3. 文件名称: file_led.c
  4. 文件版本: 01.00
  5. 创建作者: 赵海洋
  6. 创建日期: 2020-03-13
  7. 功能说明: 故障指示灯记忆文件
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "head.h"
  14. /*------------------------------- 宏定义 --------------------------------------
  15. */
  16. /*------------------------------ 类型结构 -------------------------------------
  17. */
  18. /*------------------------------ 全局变量 -------------------------------------
  19. */
  20. u32 g_file_led_sign;
  21. struct file_led_res *g_file_led_read;
  22. struct file_led_res g_file_led_write[SWITCH_NUM_MAX];
  23. struct file *file_led_handle; // 故障LED状态bin文件句柄
  24. /*------------------------------ 局部变量 -------------------------------------
  25. */
  26. // 文件CRC校验
  27. u16 g_crc_file_led_res;
  28. /*------------------------------ 函数声明 -------------------------------------
  29. */
  30. static int _file_led_init(void);
  31. static int _file_led_creat(void);
  32. static int _file_led_write(void);
  33. /*------------------------------ 外部函数 -------------------------------------
  34. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  35. */
  36. /******************************************************************************
  37. 函数名称: file_led_init
  38. 函数版本: 01.00
  39. 创建作者: 赵海洋
  40. 创建日期: 2020年3月20日
  41. 函数说明: 故障LED状态系统初始化
  42. 参数说明:
  43. 返回值:
  44. 0: 成功
  45. 其它: 失败
  46. 修改记录:
  47. */
  48. int file_led_init(void)
  49. {
  50. int i;
  51. unsigned long us,us0;
  52. i = _file_led_init();
  53. if (i != 0)
  54. {
  55. rt_printf("iret = %d\r\n", i);
  56. rt_file_del("/app/data/file_led.bin");
  57. us0 = ustimer_get_origin();
  58. i = _file_led_creat();
  59. us = ustimer_get_duration(us0);
  60. rt_printf("初始化故障LED记录文件, ret=%d, 耗时 t=%dus\r\n", i, us);
  61. }
  62. return i;
  63. }
  64. /******************************************************************************
  65. 函数名称: _file_led_init
  66. 函数版本: 01.00
  67. 创建作者: 赵海洋
  68. 创建日期: 2020年3月20日
  69. 函数说明: 故障LED状态初始化调用
  70. 参数说明:
  71. 返回值:
  72. 0: 成功
  73. 其它: 失败
  74. 修改记录:
  75. */
  76. int _file_led_init(void)
  77. {
  78. int j;
  79. u32 len;
  80. u8 *buf;
  81. u8 *tmp;
  82. struct file_led_res_head *brh;
  83. loff_t pos;
  84. // 打开文件
  85. file_led_handle = rt_file_open("/app/data/file_led.bin",O_RDWR ,0655);
  86. if(IS_ERR(file_led_handle))
  87. {
  88. return -1;
  89. }
  90. // 得到文件长度
  91. // 得到文件长度
  92. len = rt_file_getfile_size(file_led_handle);
  93. if(len <= 0)
  94. {
  95. rt_file_close(file_led_handle,0);
  96. return -1;
  97. }
  98. // 分配内存
  99. buf = rt_malloc(len);
  100. if((buf) == NULL)
  101. {
  102. rt_file_close(file_led_handle,0);
  103. return -2;
  104. }
  105. //保存原指针,便于以后释放内存
  106. tmp = buf;
  107. // 读出内容
  108. pos = 0;
  109. if(rt_file_read(file_led_handle,buf,len,&pos) != len)
  110. {
  111. rt_file_close(file_led_handle,0);
  112. rt_free(buf);
  113. return -3;
  114. }
  115. // 检查CRC
  116. g_crc_file_led_res = CrcStr(buf,len-2);
  117. if(g_crc_file_led_res != *(u16*)(buf+len-2))
  118. {
  119. rt_free(buf);
  120. return -4;
  121. }
  122. // 检查文件签名
  123. brh = (struct file_led_res_head*)buf;
  124. if(brh->cfh.signature != SIG_FILE_LED_RES_FILE)
  125. {
  126. rt_free(buf);
  127. return -5;
  128. }
  129. // rt_printf("运行到这里....file_led_addr=%d,file_led_num=%d\r\n",brh->file_led_addr,brh->file_led_num);
  130. // 检查文件长度
  131. if(len < sizeof(*brh) + brh->file_led_num*sizeof(struct file_led_res)+ 2)
  132. {
  133. rt_free(buf);
  134. return -6;
  135. }
  136. // 文件头的长度写入了file_led_addr
  137. g_file_led_read = (struct file_led_res *)(buf + brh->file_led_addr);
  138. // 初始化故障LED状态结构体
  139. memset(g_file_led_write,0,sizeof(g_file_led_write));
  140. for(j=0;j<brh->file_led_num;j++)
  141. {
  142. g_file_led_write[j].led_hw=g_file_led_read[j].led_hw;
  143. g_file_led_write[j].led_tw=g_file_led_read[j].led_tw;
  144. g_file_led_write[j].led_gl=g_file_led_read[j].led_gl;
  145. g_file_led_write[j].led_jd=g_file_led_read[j].led_jd;
  146. }
  147. buf = tmp;
  148. //释放内存
  149. rt_free(buf);
  150. return 0;
  151. }
  152. /******************************************************************************
  153. 函数名称: file_led_exit
  154. 函数版本: 01.00
  155. 创建作者: 赵海洋
  156. 创建日期: 2020年3月20日
  157. 函数说明: 故障LED状态文件句柄退出
  158. 参数说明:
  159. 返回值:
  160. 0: 成功
  161. 其它: 失败
  162. 修改记录:
  163. */
  164. int file_led_exit(void)
  165. {
  166. // 清除文件指针
  167. if(file_led_handle != 0)
  168. {
  169. rt_file_close(file_led_handle,0);
  170. file_led_handle = 0;
  171. }
  172. return 0;
  173. }
  174. /******************************************************************************
  175. 函数名称: _file_led_creat
  176. 函数版本: 01.00
  177. 创建作者: 赵海洋
  178. 创建日期: 2020年3月20日
  179. 函数说明: 创建LED显示灯状态文件
  180. 参数说明:
  181. 返回值:
  182. 0: 成功
  183. 其它: 失败
  184. 修改记录:
  185. */
  186. int _file_led_creat(void)
  187. {
  188. unsigned int i,file_length;
  189. u16 crc16;
  190. char *p;
  191. loff_t pos;
  192. int ret;
  193. struct file_led_res_head fh;
  194. struct file_led_res desc;
  195. // 配置文件头
  196. memset(&fh,0,sizeof(fh));
  197. fh.cfh.signature = SIG_FILE_LED_RES_FILE;
  198. fh.cfh.version = 0X01010101;
  199. fh.file_led_addr = FILE_ADDR_ALGIN(sizeof(fh));
  200. // 故障LED状态数据容量
  201. fh.file_led_num = SWITCH_NUM_MAX;
  202. // 整个文件长度(文件头长度+数据长度)
  203. file_length = FILE_ADDR_ALGIN(fh.file_led_addr + fh.file_led_num * sizeof(struct file_led_res));
  204. // 分配并初始化空间
  205. p = rt_malloc(file_length + 2); //加crc长度
  206. if(!p)
  207. {
  208. return -1;
  209. }
  210. memset(p,0,file_length);
  211. // 写入文件头
  212. memcpy(p,(char *)&fh,sizeof(fh));
  213. // 写LED状态数据
  214. for(i=0; i<fh.file_led_num; i++)
  215. {
  216. memset(&desc,0,sizeof(desc));
  217. desc.led_hw = g_file_led_write[i].led_hw;
  218. desc.led_tw = g_file_led_write[i].led_tw;
  219. desc.led_gl = g_file_led_write[i].led_gl;
  220. // desc.led_gl = 2;
  221. desc.led_jd = g_file_led_write[i].led_jd;
  222. memcpy(p + fh.file_led_addr + i*sizeof(desc), (char *)&desc, sizeof(desc));
  223. }
  224. // 写入LED状态文件
  225. file_led_handle = rt_file_open("/app/data/file_led.bin",O_CREAT|O_RDWR|O_TRUNC,0644);
  226. if(IS_ERR(file_led_handle))
  227. {
  228. rt_free(p);
  229. return -1;
  230. }
  231. // 计算CRC
  232. crc16 = CrcStr(p,file_length);
  233. memcpy(p+file_length,&crc16,2);
  234. pos = 0;
  235. ret=rt_file_write(file_led_handle,p,file_length + 2,&pos);
  236. // 打开文件句柄程序退出前不再关闭
  237. // rt_file_close(file_led_handle,0);
  238. rt_free(p);
  239. rt_printf("led creat len=%d\r\n",ret);
  240. return 0;
  241. }
  242. /******************************************************************************
  243. 函数名称: file_led_write
  244. 函数版本: 01.00
  245. 创建作者: 赵海洋
  246. 创建日期: 2020年3月20日
  247. 函数说明: 记录LED显示灯状态
  248. 参数说明:
  249. 返回值:
  250. 修改记录:
  251. */
  252. void file_led_write(void)
  253. {
  254. static unsigned long us0=0;
  255. unsigned long us;
  256. // 标志置位延时5秒处理一次
  257. us = 5*USTIMER_SEC;
  258. if(ustimer_delay_origin2(&us0,us) != 1)
  259. {
  260. return;
  261. }
  262. if (g_file_led_sign)
  263. {
  264. _file_led_write();
  265. g_file_led_sign = 0;
  266. }
  267. }
  268. /******************************************************************************
  269. 函数名称: _file_led_write
  270. 函数版本: 01.00
  271. 创建作者: 赵海洋
  272. 创建日期: 2020年3月20日
  273. 函数说明: 写故障显示灯状态到LED状态文件
  274. 参数说明:
  275. 返回值:
  276. 0: 成功
  277. 其它: 失败
  278. 修改记录:
  279. */
  280. int _file_led_write(void)
  281. {
  282. unsigned int i,file_length;
  283. u16 crc16;
  284. char *p;
  285. loff_t pos;
  286. unsigned int ret;
  287. struct file_led_res_head fh;
  288. struct file_led_res desc;
  289. // 更新记录
  290. if (file_led_handle ==0)
  291. {
  292. return -1;
  293. }
  294. // 配置文件头
  295. memset(&fh,0,sizeof(fh));
  296. fh.cfh.signature = SIG_FILE_LED_RES_FILE;
  297. fh.cfh.version = 0X01010101;
  298. fh.file_led_addr = FILE_ADDR_ALGIN(sizeof(fh));
  299. // 故障LED状态数据容量
  300. fh.file_led_num = SWITCH_NUM_MAX;
  301. // 整个文件长度(文件头长度+数据长度)
  302. file_length = FILE_ADDR_ALGIN(fh.file_led_addr + fh.file_led_num * sizeof(struct file_led_res));
  303. // 分配并初始化空间
  304. p = rt_malloc(file_length + 2); //加crc长度
  305. if(!p)
  306. {
  307. return -2;
  308. }
  309. memset(p,0,file_length);
  310. // 写入文件头
  311. memcpy(p,(char *)&fh,sizeof(fh));
  312. // 写LED状态数据
  313. for(i=0; i<fh.file_led_num; i++)
  314. {
  315. memset(&desc,0,sizeof(desc));
  316. desc.led_hw = g_file_led_write[i].led_hw;
  317. desc.led_tw = g_file_led_write[i].led_tw;
  318. desc.led_gl = g_file_led_write[i].led_gl;
  319. desc.led_jd = g_file_led_write[i].led_jd;
  320. memcpy(p + fh.file_led_addr + i*sizeof(desc), (char *)&desc, sizeof(desc));
  321. }
  322. // 计算CRC
  323. crc16 = CrcStr(p,file_length);
  324. memcpy(p+file_length,&crc16,2);
  325. pos = 0;
  326. ret=rt_file_write(file_led_handle,p,file_length + 2,&pos);
  327. if (ret != file_length + 2)
  328. {
  329. rt_free(p);
  330. rt_printf("led save error ret=%d\r\n",ret);
  331. return -3;
  332. }
  333. rt_free(p);
  334. rt_printf("led save len=%d\r\n",ret);
  335. return 0;
  336. }
  337. /*------------------------------ 内部函数 -------------------------------------
  338. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  339. */
  340. /*------------------------------ 测试函数 -------------------------------------
  341. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  342. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  343. */
  344. /*------------------------------ 文件结束 -------------------------------------
  345. */