main.lua 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. -- SPI接口TF卡和WAN口复用演示项目
  2. -- 项目功能:
  3. -- 1. 演示Air8000开发板上SPI1接口复用,同时支持TF卡存储和CH390网络芯片
  4. -- 2. TF卡功能:文件读写操作、启动次数记录、状态日志保存
  5. -- 3. WAN口功能:通过CH390芯片提供以太网连接,支持DHCP自动获取IP
  6. -- 4. 网络测试:定期进行HTTP请求测试,验证网络连通性
  7. -- 5. 状态监控:实时监控TF卡和网络状态,记录运行日志
  8. --
  9. -- 硬件配置:
  10. -- - SPI1: 复用接口,连接TF卡和CH390
  11. -- - GPIO20: TF卡片选引脚
  12. -- - GPIO12: CH390片选引脚
  13. -- - GPIO140: CH390供电控制引脚
  14. -- - SPI速度: 12.8MHz(兼容TF卡和CH390的统一速度)
  15. PROJECT = "spi_tf_wan"
  16. VERSION = "1.0.0"
  17. -- 引入必要的库文件(lua编写), 内部库不需要require
  18. sys = require("sys")
  19. sysplus = require("sysplus")
  20. local rtos_bsp = rtos.bsp()
  21. local USE_CH390 = true -- 使用ch390时,设置为true,否则为false
  22. local SPI_SPEED = 25600000
  23. -- spi_id,pin_cs
  24. local function fatfs_spi_pin()
  25. return 1, 20 -- Air8000整机开发板上的pin_cs为gpio20
  26. end
  27. -- TF卡和WAN口初始化函数
  28. local function tf_wan_init()
  29. if USE_CH390 then
  30. gpio.setup(140, 1, gpio.PULLUP) -- 打开ch390供电
  31. end
  32. sys.wait(1000) -- 延迟1秒让ch390 稳定后再挂载TF卡
  33. -- #################################################
  34. -- 首先初始化TF卡
  35. -- #################################################
  36. log.info("tf_wan", "开始初始化TF卡")
  37. -- fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因
  38. -- 此为spi方式
  39. local spi_id, pin_cs,tp = fatfs_spi_pin()
  40. -- 仅SPI方式需要自行初始化spi, sdio不需要
  41. -- 使用较低的统一速度以兼容TF卡和CH390
  42. spi.setup(spi_id, pin_cs, 0, 0, 8, SPI_SPEED)
  43. gpio.setup(pin_cs, 1)
  44. fatfs.mount(fatfs.SPI, "/sd", spi_id, pin_cs, SPI_SPEED)
  45. local data, err = fatfs.getfree("/sd")
  46. if data then
  47. log.info("fatfs", "getfree", json.encode(data))
  48. else
  49. log.info("fatfs", "err", err)
  50. end
  51. -- #################################################
  52. -- 文件操作测试
  53. -- #################################################
  54. local f = io.open("/sd/boottime", "rb")
  55. local c = 0
  56. if f then
  57. local data = f:read("*a")
  58. log.info("fs", "data", data, data:toHex())
  59. c = tonumber(data)
  60. f:close()
  61. end
  62. log.info("fs", "boot count", c)
  63. if c == nil then
  64. c = 0
  65. end
  66. c = c + 1
  67. f = io.open("/sd/boottime", "wb")
  68. if f ~= nil then
  69. log.info("fs", "write c to file", c, tostring(c))
  70. f:write(tostring(c))
  71. f:close()
  72. else
  73. log.warn("sdio", "mount not good?!")
  74. end
  75. if fs then
  76. log.info("fsstat", fs.fsstat("/"))
  77. log.info("fsstat", fs.fsstat("/sd"))
  78. end
  79. -- 测试一下追加, fix in 2021.12.21
  80. os.remove("/sd/test_a")
  81. sys.wait(50)
  82. f = io.open("/sd/test_a", "w")
  83. if f then
  84. f:write("ABC")
  85. f:close()
  86. end
  87. f = io.open("/sd/test_a", "a+")
  88. if f then
  89. f:write("def")
  90. f:close()
  91. end
  92. f = io.open("/sd/test_a", "r")
  93. if f then
  94. local data = f:read("*a")
  95. log.info("data", data, data == "ABCdef")
  96. f:close()
  97. end
  98. -- 测试一下按行读取, fix in 2022-01-16
  99. f = io.open("/sd/testline", "w")
  100. if f then
  101. f:write("abc\n")
  102. f:write("123\n")
  103. f:write("wendal\n")
  104. f:close()
  105. end
  106. sys.wait(100)
  107. f = io.open("/sd/testline", "r")
  108. if f then
  109. log.info("sdio", "line1", f:read("*l"))
  110. log.info("sdio", "line2", f:read("*l"))
  111. log.info("sdio", "line3", f:read("*l"))
  112. f:close()
  113. end
  114. log.info("tf_wan", "TF卡初始化完成")
  115. -- #################################################
  116. -- 然后初始化WAN口
  117. -- #################################################
  118. log.info("tf_wan", "开始初始化WAN口")
  119. sys.wait(500)
  120. -- 初始化指定netdrv设备,
  121. -- socket.LWIP_ETH 网络适配器编号
  122. -- netdrv.CH390外挂CH390
  123. -- SPI ID 1, 片选 GPIO12
  124. netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=1,cs=12})
  125. netdrv.dhcp(socket.LWIP_ETH, true)
  126. log.info("tf_wan", "WAN口初始化完成")
  127. end
  128. -- 初始化TF卡和WAN口
  129. sys.taskInit(tf_wan_init)
  130. -- 网络和TF卡状态监控,包含文件读写和网络通信
  131. local function status_monitor()
  132. local boot_count = 0
  133. while true do
  134. sys.wait(1000) -- 每1秒检查一次
  135. local status_info = {}
  136. -- 检查WAN口状态
  137. local wan_link = netdrv.link(socket.LWIP_ETH)
  138. local wan_ready = netdrv.ready(socket.LWIP_ETH)
  139. table.insert(status_info, string.format("WAN: link=%s ready=%s", tostring(wan_link), tostring(wan_ready)))
  140. -- 检查TF卡状态并进行文件读写操作
  141. local tf_status = "未知"
  142. local data, err = fatfs.getfree("/sd")
  143. if data then
  144. tf_status = "正常"
  145. -- 读取启动次数文件
  146. local f = io.open("/sd/boottime", "rb")
  147. if f then
  148. local count_data = f:read("*a")
  149. boot_count = tonumber(count_data) or 0
  150. f:close()
  151. end
  152. boot_count = boot_count + 1
  153. -- 写入新的启动次数
  154. f = io.open("/sd/boottime", "wb")
  155. if f then
  156. f:write(tostring(boot_count))
  157. f:close()
  158. log.info("文件操作", "启动次数已更新:", boot_count)
  159. end
  160. -- 写入状态日志文件
  161. local timestamp = os.date("%Y-%m-%d %H:%M:%S")
  162. local status_log = string.format("[%s] %s\n", timestamp, table.concat(status_info, ", "))
  163. f = io.open("/sd/status.log", "ab")
  164. if f then
  165. f:write(status_log)
  166. f:close()
  167. end
  168. else
  169. tf_status = "异常"
  170. end
  171. table.insert(status_info, string.format("TF卡: %s (启动次数: %d)", tf_status, boot_count))
  172. log.info("状态", table.concat(status_info, ", "))
  173. -- WAN口网络通信测试
  174. if wan_ready then
  175. log.info("网络测试", "开始WAN口网络通信测试")
  176. local code, headers, body = http.request("GET", "http://httpbin.air32.cn/get", nil, nil, {adapter=socket.LWIP_ETH}).wait()
  177. if code == 200 then
  178. -- 将网络测试结果写入TF卡
  179. if tf_status == "正常" then
  180. local f = io.open("/sd/network_test.log", "ab")
  181. if f then
  182. local test_log = string.format("[%s] WAN HTTP测试成功, 响应码: %d\n", os.date("%Y-%m-%d %H:%M:%S"), code)
  183. log.info("网络测试", "WAN口HTTP请求成功, 响应码:", code)
  184. f:write(test_log)
  185. f:close()
  186. end
  187. end
  188. else
  189. log.info("网络测试", "WAN口HTTP请求失败, 响应码:", code)
  190. end
  191. end
  192. -- 输出内存使用情况
  193. log.info("内存", "Lua:", rtos.meminfo())
  194. log.info("内存", "Sys:", rtos.meminfo("sys"))
  195. end
  196. end
  197. -- 启动状态监控任务
  198. sys.taskInit(status_monitor)
  199. -- 用户代码已结束---------------------------------------------
  200. -- 结尾总是这一句
  201. sys.run()
  202. -- sys.run()之后后面不要加任何语句!!!!!