You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

118 line
2.8 KiB

  1. #include "stm32f4xx_flash.h"
  2. #include "stm32f4xx.h"
  3. #include "modbus_parse.h"
  4. #include "modbus_flash.h"
  5. #include "string.h"
  6. #include "os.h"
  7. extern uint8_t ModbusCoil[1250];
  8. extern uint16_t ModbusReg[10000];
  9. extern uint8_t ModbusErr;
  10. extern OS_EVENT* ModbusWriteFlash; /*接收到modbus写入coil请求报文*/
  11. uint8_t ModbusFlashWrite(void);
  12. uint8_t ModbusErrReply(uint8_t func, uint8_t err);
  13. /*flash写入任务*/
  14. void AppTaskModbusWriteFlash(void *p_arg)
  15. {
  16. OS_ERR err;
  17. while(1)
  18. {
  19. OSSemPend(ModbusWriteFlash, 0, &err);
  20. while(1)
  21. {
  22. /*清除多余嵌套的信号量*/
  23. while(OSSemAccept(ModbusWriteFlash) > 0);
  24. OSSemPend(ModbusWriteFlash, OS_TICKS_PER_SEC * 2, &err);
  25. /*当连续2s未收到信号量时,退出循环*/
  26. if (err == OS_ERR_TIMEOUT)
  27. {
  28. break;
  29. }
  30. /*出现错误退出循环,防止阻塞*/
  31. if (err != OS_ERR_NONE)
  32. {
  33. break;
  34. }
  35. }
  36. /*当因为错误退出循环时,不进行flash写入*/
  37. if (err != OS_ERR_TIMEOUT)
  38. {
  39. continue;
  40. }
  41. /*只有当连续2s未收到信号量时才进行写入操作,防止信号量嵌套导致重复写入延迟*/
  42. //ModbusErr = ModbusFlashWrite();
  43. }
  44. }
  45. uint8_t ModbusFlashWrite(void)
  46. {
  47. uint32_t addres = MODBUS_FLASH_COIL_ADDR;
  48. uint16_t halfWord;
  49. FLASH_Status status;
  50. FLASH_Unlock();
  51. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR
  52. | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
  53. /*扇区擦除,写入之前必须先擦除*/
  54. status = FLASH_EraseSector(MODBUS_FLASH_SECTOR, VoltageRange_3);
  55. if(status != FLASH_COMPLETE)
  56. {
  57. return ERR_SLAVE;
  58. }
  59. for(uint16_t i = 0; i < 1250; i += 2)
  60. {
  61. /*前面的放在低字节,后面的放在高字节*/
  62. halfWord = ((uint16_t)ModbusCoil[i + 1] << 8) | ((uint16_t)ModbusCoil[i]);
  63. status = FLASH_ProgramHalfWord(addres, halfWord);
  64. /*写入失败,停止写入*/
  65. if(status != FLASH_COMPLETE)
  66. {
  67. return ERR_SLAVE;
  68. }
  69. addres += 2;
  70. }
  71. addres = MODBUS_FLASH_REG_ADDR;
  72. for(uint16_t i = 0; i < 10000; i++)
  73. {
  74. status = FLASH_ProgramHalfWord(addres, ModbusReg[i]);
  75. /*写入失败,停止写入*/
  76. if(status != FLASH_COMPLETE)
  77. {
  78. return ERR_SLAVE;
  79. }
  80. addres += 2;
  81. }
  82. FLASH_Lock();
  83. return 0;
  84. }
  85. void ModbusRegReadFlash(void)
  86. {
  87. memcpy(ModbusReg, (const void *)MODBUS_FLASH_REG_ADDR, sizeof(ModbusReg));
  88. }
  89. void ModbusCoilReadFlash(void)
  90. {
  91. memcpy(ModbusCoil, (const void *)MODBUS_FLASH_COIL_ADDR, sizeof(ModbusCoil));
  92. }