使用rtthread

This commit is contained in:
ranchuan
2023-06-25 15:30:36 +08:00
parent 3604192d8f
commit cdad432f8a
41 changed files with 6047 additions and 95 deletions

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"files.associations": {
"if_pwm.h": "c"
}
}

View File

@@ -17,6 +17,6 @@
#define CMSIS_device_header "stm32mp157dxx_cm4.h"
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
#define RTE_Compiler_IO_STDOUT_BKPT /* Compiler I/O: STDOUT Breakpoint */
#define RTE_Compiler_IO_STDOUT_User /* Compiler I/O: STDOUT Breakpoint */
#endif /* RTE_COMPONENTS_H */

View File

@@ -1,3 +1,5 @@
2023.6.21
建立工程,成功创建两个虚拟串口与主机通信
2023.6.25
使用rt-thread
电机控制、按键、ADC在M4上实现

View File

@@ -314,21 +314,249 @@
<Group>
<GroupName>rtthread</GroupName>
<tvExp>0</tvExp>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>11</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\libcpu\arm\cortex-m4\cpuport.c</PathWithFileName>
<FilenameWithoutPath>cpuport.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>12</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\libcpu\arm\cortex-m4\context_rvds.S</PathWithFileName>
<FilenameWithoutPath>context_rvds.S</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>13</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\clock.c</PathWithFileName>
<FilenameWithoutPath>clock.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>14</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\components.c</PathWithFileName>
<FilenameWithoutPath>components.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>15</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\cpu.c</PathWithFileName>
<FilenameWithoutPath>cpu.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>16</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\idle.c</PathWithFileName>
<FilenameWithoutPath>idle.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>17</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\ipc.c</PathWithFileName>
<FilenameWithoutPath>ipc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>18</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\irq.c</PathWithFileName>
<FilenameWithoutPath>irq.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>19</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\kservice.c</PathWithFileName>
<FilenameWithoutPath>kservice.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>20</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\mem.c</PathWithFileName>
<FilenameWithoutPath>mem.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\memheap.c</PathWithFileName>
<FilenameWithoutPath>memheap.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\mempool.c</PathWithFileName>
<FilenameWithoutPath>mempool.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\object.c</PathWithFileName>
<FilenameWithoutPath>object.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\scheduler.c</PathWithFileName>
<FilenameWithoutPath>scheduler.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\slab.c</PathWithFileName>
<FilenameWithoutPath>slab.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\thread.c</PathWithFileName>
<FilenameWithoutPath>thread.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\src\timer.c</PathWithFileName>
<FilenameWithoutPath>timer.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>28</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\board.c</PathWithFileName>
<FilenameWithoutPath>board.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>29</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\rt_thread\core_delay.c</PathWithFileName>
<FilenameWithoutPath>core_delay.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>stm32lib</GroupName>
<tvExp>0</tvExp>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>11</FileNumber>
<FileNumber>30</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -340,7 +568,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>12</FileNumber>
<FileNumber>31</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -352,7 +580,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>13</FileNumber>
<FileNumber>32</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -364,7 +592,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>14</FileNumber>
<FileNumber>33</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -376,7 +604,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>15</FileNumber>
<FileNumber>34</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -388,7 +616,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>16</FileNumber>
<FileNumber>35</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -400,7 +628,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>17</FileNumber>
<FileNumber>36</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -412,7 +640,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>18</FileNumber>
<FileNumber>37</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -424,7 +652,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>19</FileNumber>
<FileNumber>38</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -436,7 +664,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>20</FileNumber>
<FileNumber>39</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -448,7 +676,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>21</FileNumber>
<FileNumber>40</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -460,7 +688,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>22</FileNumber>
<FileNumber>41</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -472,7 +700,7 @@
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>23</FileNumber>
<FileNumber>42</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -482,6 +710,18 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>43</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\stm32lib\STM32MP1xx_HAL_Driver\Src\stm32mp1xx_hal_tim.c</PathWithFileName>
<FilenameWithoutPath>stm32mp1xx_hal_tim.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
@@ -492,7 +732,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>24</FileNumber>
<FileNumber>44</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -504,7 +744,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>25</FileNumber>
<FileNumber>45</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -516,7 +756,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>26</FileNumber>
<FileNumber>46</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -528,7 +768,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>27</FileNumber>
<FileNumber>47</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -540,7 +780,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>28</FileNumber>
<FileNumber>48</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -552,7 +792,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>29</FileNumber>
<FileNumber>49</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -564,7 +804,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>30</FileNumber>
<FileNumber>50</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -576,7 +816,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>31</FileNumber>
<FileNumber>51</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -588,7 +828,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>32</FileNumber>
<FileNumber>52</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -600,7 +840,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>33</FileNumber>
<FileNumber>53</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -612,7 +852,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>34</FileNumber>
<FileNumber>54</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -624,7 +864,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>35</FileNumber>
<FileNumber>55</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -636,7 +876,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>36</FileNumber>
<FileNumber>56</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -648,7 +888,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>37</FileNumber>
<FileNumber>57</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -660,7 +900,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>38</FileNumber>
<FileNumber>58</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -672,7 +912,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>39</FileNumber>
<FileNumber>59</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -684,7 +924,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>40</FileNumber>
<FileNumber>60</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -696,7 +936,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>41</FileNumber>
<FileNumber>61</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -708,7 +948,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>42</FileNumber>
<FileNumber>62</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -720,6 +960,166 @@
</File>
</Group>
<Group>
<GroupName>interface</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>6</GroupNumber>
<FileNumber>63</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\interface\if_pwm.c</PathWithFileName>
<FilenameWithoutPath>if_pwm.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>soft</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>64</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\buff.c</PathWithFileName>
<FilenameWithoutPath>buff.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>65</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\bytearray.c</PathWithFileName>
<FilenameWithoutPath>bytearray.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>66</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\cJSON.c</PathWithFileName>
<FilenameWithoutPath>cJSON.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>67</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\crc.c</PathWithFileName>
<FilenameWithoutPath>crc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>68</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\debug.c</PathWithFileName>
<FilenameWithoutPath>debug.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>69</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\list.c</PathWithFileName>
<FilenameWithoutPath>list.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>70</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\mymisc.c</PathWithFileName>
<FilenameWithoutPath>mymisc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>71</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\mystdlib.c</PathWithFileName>
<FilenameWithoutPath>mystdlib.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>72</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\mystring.c</PathWithFileName>
<FilenameWithoutPath>mystring.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>73</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\signal.c</PathWithFileName>
<FilenameWithoutPath>signal.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>74</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\source\soft\sort.c</PathWithFileName>
<FilenameWithoutPath>sort.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>::CMSIS</GroupName>
<tvExp>0</tvExp>

View File

@@ -54,7 +54,7 @@
<CreateLib>0</CreateLib>
<CreateHexFile>0</CreateHexFile>
<DebugInformation>1</DebugInformation>
<BrowseInformation>0</BrowseInformation>
<BrowseInformation>1</BrowseInformation>
<ListingPath>.\Listings\</ListingPath>
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
@@ -336,9 +336,9 @@
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>CORE_CM4,NO_ATOMIC_64_SUPPORT,USE_HAL_DRIVER,STM32MP157Dxx,METAL_INTERNAL,METAL_MAX_DEVICE_REGIONS=2,METAL_INTERNAL,VIRTIO_SLAVE_ONLY,__LOG_TRACE_IO_</Define>
<Define>CORE_CM4,NO_ATOMIC_64_SUPPORT,USE_HAL_DRIVER,STM32MP157Dxx,METAL_INTERNAL,METAL_MAX_DEVICE_REGIONS=2,METAL_INTERNAL,VIRTIO_SLAVE_ONLY,__LOG_TRACE_IO_,RT_THREAD</Define>
<Undefine></Undefine>
<IncludePath>.\source\core;.\source\main;.\source\rt_thread;.\source\rt_thread\include;.\source\stm32lib\STM32MP1xx_HAL_Driver\Inc;.\source\stm32lib\CMSIS\Include;.\source\OpenAMP\open-amp\lib\include;.\source\OpenAMP\libmetal\lib\include;.\source\OpenAMP\virtual_driver</IncludePath>
<IncludePath>.\source\core;.\source\main;.\source\rt_thread;.\source\rt_thread\include;.\source\stm32lib\STM32MP1xx_HAL_Driver\Inc;.\source\stm32lib\CMSIS\Include;.\source\OpenAMP\open-amp\lib\include;.\source\OpenAMP\libmetal\lib\include;.\source\OpenAMP\virtual_driver;.\source\soft</IncludePath>
</VariousControls>
</Cads>
<Aads>
@@ -441,6 +441,103 @@
</Group>
<Group>
<GroupName>rtthread</GroupName>
<Files>
<File>
<FileName>cpuport.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\libcpu\arm\cortex-m4\cpuport.c</FilePath>
</File>
<File>
<FileName>context_rvds.S</FileName>
<FileType>2</FileType>
<FilePath>.\source\rt_thread\libcpu\arm\cortex-m4\context_rvds.S</FilePath>
</File>
<File>
<FileName>clock.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\clock.c</FilePath>
</File>
<File>
<FileName>components.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\components.c</FilePath>
</File>
<File>
<FileName>cpu.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\cpu.c</FilePath>
</File>
<File>
<FileName>idle.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\idle.c</FilePath>
</File>
<File>
<FileName>ipc.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\ipc.c</FilePath>
</File>
<File>
<FileName>irq.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\irq.c</FilePath>
</File>
<File>
<FileName>kservice.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\kservice.c</FilePath>
</File>
<File>
<FileName>mem.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\mem.c</FilePath>
</File>
<File>
<FileName>memheap.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\memheap.c</FilePath>
</File>
<File>
<FileName>mempool.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\mempool.c</FilePath>
</File>
<File>
<FileName>object.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\object.c</FilePath>
</File>
<File>
<FileName>scheduler.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\scheduler.c</FilePath>
</File>
<File>
<FileName>slab.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\slab.c</FilePath>
</File>
<File>
<FileName>thread.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\thread.c</FilePath>
</File>
<File>
<FileName>timer.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\src\timer.c</FilePath>
</File>
<File>
<FileName>board.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\board.c</FilePath>
</File>
<File>
<FileName>core_delay.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\rt_thread\core_delay.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>stm32lib</GroupName>
@@ -561,6 +658,11 @@
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>stm32mp1xx_hal_tim.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\stm32lib\STM32MP1xx_HAL_Driver\Src\stm32mp1xx_hal_tim.c</FilePath>
</File>
</Files>
</Group>
<Group>
@@ -663,6 +765,280 @@
</File>
</Files>
</Group>
<Group>
<GroupName>interface</GroupName>
<Files>
<File>
<FileName>if_pwm.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\interface\if_pwm.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>soft</GroupName>
<Files>
<File>
<FileName>buff.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\buff.c</FilePath>
</File>
<File>
<FileName>bytearray.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\bytearray.c</FilePath>
</File>
<File>
<FileName>cJSON.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\cJSON.c</FilePath>
</File>
<File>
<FileName>crc.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\crc.c</FilePath>
</File>
<File>
<FileName>debug.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\debug.c</FilePath>
</File>
<File>
<FileName>list.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\list.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>mymisc.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\mymisc.c</FilePath>
</File>
<File>
<FileName>mystdlib.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\mystdlib.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>mystring.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\mystring.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>signal.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\signal.c</FilePath>
</File>
<File>
<FileName>sort.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\soft\sort.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
</Files>
</Group>
<Group>
<GroupName>::CMSIS</GroupName>
</Group>

55
source/interface/if_pwm.c Normal file
View File

@@ -0,0 +1,55 @@
#include "board.h"
#include "debug.h"
// 使用定时器14
// PF7,8,9 是输出口
typedef struct{
TIM_HandleTypeDef htim;
}self_def;
static self_def g_self;
static int init(pwm_def *p)
{
self_def *s=&g_self;
if(p->private_data) return 0;
p->private_data=s;
s->htim.Instance = TIM14;
s->htim.Init.Prescaler = 209-1;
s->htim.Init.CounterMode = TIM_COUNTERMODE_UP;
s->htim.Init.Period = 65535;
s->htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
s->htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&s->htim) != HAL_OK)
{
DBG_ERR("time init failed.");
return -1;
}
return 0;
}
void TIM14_IRQHandler(void)
{
self_def *s=&g_self;
HAL_TIM_IRQHandler(&s->htim);
}

17
source/interface/if_pwm.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef if_pwm_h__
#define if_pwm_h__
#endif

View File

@@ -24,7 +24,7 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "debug.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -78,17 +78,17 @@ void VIRT_UART1_RxCpltCallback(VIRT_UART_HandleTypeDef *huart);
int main(void)
{
/* USER CODE BEGIN 1 */
debug_init();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
log_info("ssss");
DBG_LOG("mcu start.");
/* Reset of all peripherals, Initialize the Systick. */
HAL_Init();
log_info("aaaa");
/* USER CODE BEGIN Init */
if(IS_ENGINEERING_BOOT_MODE())
if(IS_ENGINEERING_BOOT_MODE())
{
/* Configure the system clock */
SystemClock_Config();

View File

@@ -70,7 +70,7 @@
/*#define HAL_SPI_MODULE_ENABLED */
/*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_TAMP_MODULE_ENABLED */
/*#define HAL_TIM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
/*#define HAL_TMPSENS_MODULE_ENABLED */
/*#define HAL_UART_MODULE_ENABLED */
/*#define HAL_USART_MODULE_ENABLED */

View File

@@ -128,6 +128,66 @@ void HAL_IPCC_MspDeInit(IPCC_HandleTypeDef* hipcc)
}
/**
* @brief TIM_Base MSP Initialization
* This function configures the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM14)
{
/* USER CODE BEGIN TIM14_MspInit 0 */
/* USER CODE END TIM14_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM14_CLK_ENABLE();
/* TIM14 interrupt Init */
HAL_NVIC_SetPriority(TIM14_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(TIM14_IRQn);
/* USER CODE BEGIN TIM14_MspInit 1 */
/* USER CODE END TIM14_MspInit 1 */
}
}
/**
* @brief TIM_Base MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM14)
{
/* USER CODE BEGIN TIM14_MspDeInit 0 */
/* USER CODE END TIM14_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM14_CLK_DISABLE();
/* TIM14 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM14_IRQn);
/* USER CODE BEGIN TIM14_MspDeInit 1 */
/* USER CODE END TIM14_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -83,17 +83,17 @@ void NMI_Handler(void)
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
//void HardFault_Handler(void)
//{
// /* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
// /* USER CODE END HardFault_IRQn 0 */
// while (1)
// {
// /* USER CODE BEGIN W1_HardFault_IRQn 0 */
// /* USER CODE END W1_HardFault_IRQn 0 */
// }
//}
/**
* @brief This function handles Memory management fault.
@@ -169,29 +169,29 @@ void DebugMon_Handler(void)
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
//void PendSV_Handler(void)
//{
// /* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
// /* USER CODE END PendSV_IRQn 0 */
// /* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
// /* USER CODE END PendSV_IRQn 1 */
//}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
//void SysTick_Handler(void)
//{
// /* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
// /* USER CODE END SysTick_IRQn 0 */
// HAL_IncTick();
// /* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
// /* USER CODE END SysTick_IRQn 1 */
//}
/******************************************************************************/
/* STM32MP1xx Peripheral Interrupt Handlers */

View File

@@ -1,5 +1,5 @@
#include "stm32h7xx.h"
#include "stm32mp1xx.h"
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
@@ -36,7 +36,7 @@ static uint32_t _SysTick_Config(rt_uint32_t ticks)
}
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
static uint32_t g_heap[64*1024/4];
static uint32_t g_heap[32*1024/4];
RT_WEAK void *rt_heap_begin_get(void)
{
return (void *)g_heap;
@@ -44,7 +44,7 @@ RT_WEAK void *rt_heap_begin_get(void)
RT_WEAK void *rt_heap_end_get(void)
{
return (void *)(g_heap+(64*1024/4));
return (void *)(g_heap+(32*1024/4));
}
#endif
@@ -57,10 +57,10 @@ void rt_hw_board_init()
{
//NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x20000);
// 1msһ<73><D2BB>tick
_SysTick_Config (400000000/1000);
_SysTick_Config (HAL_RCC_GetMCUFreq()/1000);
rt_system_heap_init(rt_heap_begin_get(),rt_heap_end_get());
mem_init();
tempptr_init();
//mem_init();
//tempptr_init();
delay_init();
signal_init();
@@ -75,6 +75,23 @@ void SysTick_Handler(void)
}
uint32_t HAL_GetTick(void)
{
return rt_tick_get();
}
void HAL_Delay(uint32_t Delay)
{
rt_thread_mdelay(Delay);
}
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
return HAL_OK;
}
#endif
void *dev_get(const char *name)
@@ -223,25 +240,25 @@ void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
#pragma import(__use_no_semihosting)
//#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
//struct __FILE
//{
// int handle;
//};
FILE __stdout;
//FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
//void _sys_exit(int x)
//{
// x = x;
//}
int fputc(int ch, FILE *f)
{
// SEGGER_RTT_PutChar(0,ch);
return ch;
}
//int fputc(int ch, FILE *f)
//{
//// SEGGER_RTT_PutChar(0,ch);
// return ch;
//}

View File

@@ -5,7 +5,7 @@
#include "rtthread.h"
#include <rthw.h>
#include "string.h"
#include "stm32h7xx.h"
#include "stm32mp1xx.h"
struct dev_struct{

View File

@@ -1,4 +1,4 @@
#include "stm32h7xx.h"
#include "stm32mp1xx.h"
#include "core_delay.h"
#include "rtthread.h"
#include <rthw.h>
@@ -17,7 +17,7 @@
//<2F><>ȡϵͳ<CFB5><CDB3>Ƶ
static uint32_t get_sys_clocks_freq (void)
{
return HAL_RCC_GetSysClockFreq();
return HAL_RCC_GetMCUFreq();
}

View File

@@ -217,13 +217,13 @@ rt_hw_interrupt_thread_switch PROC
BX lr
ENDP
IMPORT bk_reboot_hard_err
;IMPORT bk_reboot_hard_err
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler PROC
; get current context
BL bk_reboot_hard_err
;BL bk_reboot_hard_err
B .
TST lr, #0x04 ; if(!EXC_RETURN[2])
ITE EQ

180
source/soft/buff.c Normal file
View File

@@ -0,0 +1,180 @@
#include "buff.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#ifdef RT_THREAD
#include "rthw.h"
#define IRQ_DISABLE() rt_base_t irq_stat=rt_hw_interrupt_disable( )
#define IRQ_ENABLE() rt_hw_interrupt_enable (irq_stat)
#define MUTEX_INIT(buff,name) buff->mutex=rt_mutex_create(name,RT_IPC_FLAG_FIFO)
#define MUTEX_TAKE(buff) rt_mutex_take(buff->mutex,RT_WAITING_FOREVER)
#define MUTEX_RELEASE(buff) rt_mutex_release(buff->mutex);
#else
#define IRQ_DISABLE() { }
#define IRQ_ENABLE() { }
#define MUTEX_INIT(buff,name) {}
#define MUTEX_TAKE(buff) {}
#define MUTEX_RELEASE(buff) {}
#endif
static int g_buff_num=0;
int buff_init(data_buff *buff,int size,int use_frame,int frame_start,int frame_end)
{
int buff_index;
char str[20];
if(buff==0) return -1;
if(buff->buff==0)
{
IRQ_DISABLE();
buff_index=g_buff_num;
g_buff_num++;
IRQ_ENABLE();
buff->buff=malloc(size);
if(buff->buff==0) return -1;
memset(buff->buff,0,sizeof(size));
buff->buff_len= size;
buff->use_frame=use_frame;
buff->frame_start=frame_start;
buff->frame_end=frame_end;
sprintf(str,"buff_#%d",buff_index);
MUTEX_INIT(buff,str);
}
buff_clear(buff);
return 0;
}
int buff_deinit(data_buff *buff)
{
if(buff==0) return -1;
if(buff->buff)
{
free(buff->buff);
buff->buff=0;
buff->buff_len=0;
}
return 0;
}
int buff_get_used(data_buff *buff)
{
int ret=-1;
IRQ_DISABLE();
ret=buff->buff_used;
IRQ_ENABLE();
return ret;
}
int buff_save_byte(data_buff *buff,uint8_t data)
{
if(buff==0) return -1;
int ret=-1;
IRQ_DISABLE();
if((!buff->use_frame)||(data==buff->frame_start)) buff->active=1;
if((buff->buff_used<buff->buff_len)&&buff->active)
{
buff->buff[buff->save_ptr]=data;
buff->buff_used++;
if((buff->use_frame)&&(data==buff->frame_end)) {
buff->frame_num++;
buff->active=0;
}
buff->save_ptr++;
if (buff->save_ptr>=buff->buff_len)
buff->save_ptr=0;
ret= 0;
}
IRQ_ENABLE();
return ret;
}
int buff_save_bytes(data_buff *buff,const uint8_t *data,int len)
{
if(buff==0) return -1;
int ret=-1;
MUTEX_TAKE(buff);
if (buff->buff_used+len<=buff->buff_len)
{
while(len--)
{
ret=buff_save_byte(buff,*data);data++;
if(ret!=0) break;
}
}
MUTEX_RELEASE(buff);
return ret;
}
int buff_read_byte(data_buff *buff,uint8_t *data)
{
if(buff==0) return -1;
int ret=-1;
IRQ_DISABLE();
if (((buff->frame_num)&&(buff->buff_used))||((!buff->use_frame)&&(buff->buff_used)))
{
*data=buff->buff[buff->read_ptr];
buff->buff_used--;
if((buff->use_frame)&&(*data==buff->frame_end)) buff->frame_num--;
buff->read_ptr++;
if (buff->read_ptr>=buff->buff_len)
buff->read_ptr=0;
ret= 0;
}
IRQ_ENABLE();
return ret;
}
int buff_read_bytes(data_buff *buff,uint8_t *data,int len)
{
if(buff==0) return -1;
int ret=-1;
MUTEX_TAKE(buff);
if (buff->buff_used>=len)
{
while(len--)
{
ret=buff_read_byte(buff,data);data++;
if(ret!=0) break;
}
}
MUTEX_RELEASE(buff);
return ret;
}
int buff_clear(data_buff *buff)
{
if(buff==0) return -1;
IRQ_DISABLE();
buff->buff_used=0;
buff->read_ptr=0;
buff->save_ptr=0;
buff->frame_num=0;
buff->active=0;
IRQ_ENABLE();
return 0;
}

60
source/soft/buff.h Normal file
View File

@@ -0,0 +1,60 @@
#ifndef BUFF_H__
#define BUFF_H__
#include <stdint.h>
typedef struct
{
int buff_len;
int buff_used;
int read_ptr;
int save_ptr;
int use_frame; //使用帧
int frame_start; //帧开始
int frame_end; //帧结束
int frame_num; //完整帧数
int active; //在接收到帧开始之后进入活跃状态
uint8_t *buff;
void *mutex;
} data_buff;
// 初始化一个指定长度的缓冲区返回0成功
int buff_init(data_buff *buff,int size,int use_frame,int frame_start,int frame_end);
// 去初始化一个指定长度的缓冲区返回0成功
int buff_deinit(data_buff *buff);
// 获取buff的使用量
int buff_get_used(data_buff *buff);
// 保存一个字节数据返回0成功
int buff_save_byte(data_buff *buff,uint8_t data);
// 保存多个字节返回0成功
int buff_save_bytes(data_buff *buff,const uint8_t *data,int len);
// 读取一个字节数据返回0成功
int buff_read_byte(data_buff *buff,uint8_t *data);
// 读取多个字节返回0成功
int buff_read_bytes(data_buff *buff,uint8_t *data,int len);
// 清除缓冲区返回0成功
int buff_clear(data_buff *buff);
#endif

208
source/soft/bytearray.c Normal file
View File

@@ -0,0 +1,208 @@
#include "bytearray.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "board.h"
#include "mystdlib.h"
#include "debug.h"
#include "rtthread.h"
#define ARR_MAX_PRINT_LEN 20
#define ARRAY_APPEND_SKIP 50
// 使用时保证不要在不同线程同时修改,可以不用保护以提高速度
#define rt_mutex_create(...) 0
#define rt_mutex_delete(...)
#define rt_mutex_take(...)
#define rt_mutex_release(...)
struct _array_def{
int32_t all;
int32_t used;
rt_mutex_t mutex;
uint8_t data[0];
};
array_def *arr_creat(void)
{
array_def *a;
static uint16_t count=0;
char s1[16]={0};
sprintf(s1,"arr_mut#%d",count);
int size=0;
size+=sizeof(array_def);
size+=ARRAY_APPEND_SKIP;
a=malloc(size);
param_check(a);
a->all=ARRAY_APPEND_SKIP;
a->used=0;
a->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO);
count++;
return a;
}
static array_def *arr_expend(array_def *a)
{
array_def *r;
int size=0;
int cpysize=0;
size+=sizeof(array_def);
size+=a->all+ARRAY_APPEND_SKIP;
r=malloc(size);
param_check(r);
cpysize=sizeof(array_def)+a->used;
memcpy(r,a,cpysize);
r->all+=ARRAY_APPEND_SKIP;
free(a);
return r;
}
array_def *_arr_append(array_def **a,uint8_t d)
{
param_check(a);
param_check(*a);
array_def *r=*a;
rt_mutex_take(r->mutex,RT_WAITING_FOREVER);
if((*a)->used>=(*a)->all)
{
r=arr_expend(*a);
}
r->data[r->used]=d;
r->used++;
rt_mutex_release(r->mutex);
*a=r;
return r;
}
uint8_t arr_get(array_def *a,int index)
{
uint8_t ret=0;
param_check(a);
rt_mutex_take(a->mutex,RT_WAITING_FOREVER);
if(index<0) index=a->used+index;
if((index>=0&&index<a->used)==0) ret=0;
else ret=a->data[index];
rt_mutex_release(a->mutex);
return ret;
}
uint8_t *arr_data(array_def *a)
{
param_check(a);
return a->data;
}
int arr_length(array_def *a)
{
param_check(a);
return a->used;
}
// 截取数组
array_def *arr_mid(array_def *a,int start,int len)
{
param_check(a);
array_def *r;
r=arr_creat();
if(start<0) start=a->used+start;
if((start>=0&&start<a->used)==0)
{
return r;
}
if(start+len>a->used)
{
len=a->used-start;
}
for(int i=0;i<len;i++)
{
//_arr_append(&r,arr_get(a,i+start));
_arr_append(&r,a->data[i+start]);
}
//return tappend(r,0);
return r;
}
// 移除一些数据,返回实际移除的数据长度
int arr_remove(array_def *a,int start,int len)
{
param_check(a);
if(start<0) start=a->used+start;
if((start>=0&&start<a->used)==0)
{
return 0;
}
if(start+len>a->used)
{
len=a->used-start;
}
int move_len=a->used-(start+len);
memcpy(&a->data[start],&a->data[start+len],move_len);
a->used-=len;
return len;
}
// 输出打印字符串
char *arr_string(array_def *a)
{
param_check(a);
array_def *d=arr_creat();
param_check(d);
// DBG_LOG("d=%08x,a=%08x",d,a);
// DBG_LOG("%s:length(a)==%d.",__func__,arr_length(a));
int len=0;
char s[20];
int index=0;
arr_append(d,'[');
for(int i=0;i<arr_length(a);i++)
{
sprintf(s,"%02x",arr_get(a,i));
// sprintf(s,"%02x",(uint8_t)i);
len=strlen(s);
arr_appends(d,s,len);
arr_append(d,',');
index++;
if(index>=ARR_MAX_PRINT_LEN){
// 超过20字节的 只打印前20字节
sprintf(s,"...(%d)",arr_length(a));
len=strlen(s);
arr_appends(d,s,len);
break;
}
}
arr_append(d,']');
len=arr_length(d);
char *ptr=malloc(len+1);
param_check(ptr);
memcpy(ptr,arr_data(d),len);
arr_delete(d);
ptr[len]=0;
return ptr;
}

46
source/soft/bytearray.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef bytearray_h__
#define bytearray_h__
#include "stdint.h"
struct _array_def;
typedef struct _array_def array_def;
array_def *arr_creat(void);
uint8_t arr_get(array_def *a,int index);
array_def *arr_mid(array_def *a,int start,int len);
uint8_t *arr_data(array_def *a);
int arr_length(array_def *a);
int arr_remove(array_def *a,int start,int len);
char *arr_string(array_def *a);
#define arr_delete(a) {free(a);a=0;}
#define arr_append(a,d) _arr_append(&a,d)
#define arr_appends(a,d,len) for(int i=0;i<len;i++){_arr_append(&a,((uint8_t *)d)[i]);}
#define arr_appends_from(a,b) {\
uint8_t *d=arr_data(b);\
arr_appends(a,d,arr_length(b));}
#define arr_append_num(a,num,d) for(int i=0;i<num;i++){_arr_append(&a,d);}
#define arr_clear(a) arr_remove(a,0,arr_length(a))
#define arr_duplicate(a) arr_mid(a,0,arr_length(a))
// 转化为临时指针
#define arr_temp(a) tappend(a,0)
array_def *_arr_append(array_def **a,uint8_t d);
#endif

641
source/soft/cJSON.c Normal file
View File

@@ -0,0 +1,641 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* cJSON */
/* JSON parser in C. */
//#define MY_NUMTOSTR //使用自己的数字转字符串函数,以防使用sprintf导致的浮点数输出始终为0的情况
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "cJSON.h"
static const char *ep;
const char *cJSON_GetErrorPtr(void) {return ep;}
static int cJSON_strcasecmp(const char *s1,const char *s2)
{
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}
static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free;
static char* cJSON_strdup(const char* str)
{
size_t len;
char* copy;
len = strlen(str) + 1;
if ((copy = (char*)cJSON_malloc(len)),copy==0) return 0;
memcpy(copy,(void *)str,len);
return copy;
}
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = malloc;
cJSON_free = free;
return;
}
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
}
/* Internal constructor. */
static cJSON *cJSON_New_Item(void)
{
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
if (node) memset(node,0,sizeof(cJSON));
return node;
}
/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
cJSON *next;
while (c)
{
next=c->next;
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
if (c->string) cJSON_free(c->string);
cJSON_free(c);
c=next;
}
}
/* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
if (*num=='-') sign=-1,num++; /* Has sign? */
if (*num=='0') num++; /* is zero */
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
if (*num=='e' || *num=='E') /* Exponent? */
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
}
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
item->valuedouble=n;
item->valueint=(int)n;
item->type=cJSON_Number;
return num;
}
#ifdef MY_NUMTOSTR
//把数字转换成字符串
void num_to_str (u8 *str,u8 num1,u8 num2)
{
if (num1>9)
{
*str++=num1/10+'0';
*str++=num1%10+'0';
}
else
{
*str++=num1+'0';
}
*str++='.';
if (num2<10)
{
*str++=num2+'0';
}
else
{
*str++=num2/10+'0';
*str++=num2%10+'0';
}
*str=0;
}
#endif
/* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item)
{
char *str;
double d=item->valuedouble;
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
{
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
if (str) sprintf(str,"%d",item->valueint);
}
else
{
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
if (str)
{
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
else
{
#ifndef MY_NUMTOSTR
sprintf(str,"%f",d);
#else
num_to_str((u8*)str,(u8)d,(u8)((d-(u8)d)*10));
#endif
}
}
}
return str;
}
static unsigned parse_hex4(const char *str)
{
unsigned h=0;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
return h;
}
/* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;} /* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\') *ptr2++=*ptr++;
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b'; break;
case 'f': *ptr2++='\f'; break;
case 'n': *ptr2++='\n'; break;
case 'r': *ptr2++='\r'; break;
case 't': *ptr2++='\t'; break;
case 'u': /* transcode utf16 to utf8. */
uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
{
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
uc2=parse_hex4(ptr+3);ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 1: *--ptr2 =(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=0;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
}
/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str)
{
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
if (!str) return cJSON_strdup("");
ptr=str;while ((token=*ptr),token && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
ptr2=out;ptr=str;
*ptr2++='\"';
while (*ptr)
{
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
else
{
*ptr2++='\\';
switch (token=*ptr++)
{
case '\\': *ptr2++='\\'; break;
case '\"': *ptr2++='\"'; break;
case '\b': *ptr2++='b'; break;
case '\f': *ptr2++='f'; break;
case '\n': *ptr2++='n'; break;
case '\r': *ptr2++='r'; break;
case '\t': *ptr2++='t'; break;
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
}
}
}
*ptr2++='\"';*ptr2++=0;
return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item,const char *value);
static char *print_value(cJSON *item,int depth,int fmt);
static const char *parse_array(cJSON *item,const char *value);
static char *print_array(cJSON *item,int depth,int fmt);
static const char *parse_object(cJSON *item,const char *value);
static char *print_object(cJSON *item,int depth,int fmt);
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
/* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
{
const char *end=0;
cJSON *c=cJSON_New_Item();
ep=0;
if (!c) return 0; /* memory fail */
end=parse_value(c,skip(value));
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
if (return_parse_end) *return_parse_end=end;
return c;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
/* Render a cJSON item/entity/structure to text. */
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{
if (!value) return 0; /* Fail on null. */
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
if (*value=='\"') { return parse_string(item,value); }
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
if (*value=='[') { return parse_array(item,value); }
if (*value=='{') { return parse_object(item,value); }
ep=value;return 0; /* failure. */
}
/* Render a value to text. */
static char *print_value(cJSON *item,int depth,int fmt)
{
char *out=0;
if (!item) return 0;
switch ((item->type)&255)
{
case cJSON_NULL: out=cJSON_strdup("null"); break;
case cJSON_False: out=cJSON_strdup("false");break;
case cJSON_True: out=cJSON_strdup("true"); break;
case cJSON_Number: out=print_number(item);break;
case cJSON_String: out=print_string(item);break;
case cJSON_Array: out=print_array(item,depth,fmt);break;
case cJSON_Object: out=print_object(item,depth,fmt);break;
}
return out;
}
/* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='[') {ep=value;return 0;} /* not an array! */
item->type=cJSON_Array;
value=skip(value+1);
if (*value==']') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0; /* memory fail */
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if ((new_item=cJSON_New_Item()),new_item==0) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_value(child,skip(value+1)));
if (!value) return 0; /* memory fail */
}
if (*value==']') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an array to text */
static char *print_array(cJSON *item,int depth,int fmt)
{
char **entries;
char *out=0,*ptr,*ret;int len=5;
cJSON *child=item->child;
int numentries=0,i=0,fail=0;
/* How many entries in the array? */
while (child) numentries++,child=child->next;
/* Explicitly handle numentries==0 */
if (!numentries)
{
out=(char*)cJSON_malloc(3);
if (out) strcpy(out,"[]");
return out;
}
/* Allocate an array to hold the values for each */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
memset(entries,0,numentries*sizeof(char*));
/* Retrieve all the results: */
child=item->child;
while (child && !fail)
{
ret=print_value(child,depth+1,fmt);
entries[i++]=ret;
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
child=child->next;
}
/* If we didn't fail, try to malloc the output string */
if (!fail) out=(char*)cJSON_malloc(len);
/* If that fails, we fail. */
if (!out) fail=1;
/* Handle failure. */
if (fail)
{
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
cJSON_free(entries);
return 0;
}
/* Compose the output array. */
*out='[';
ptr=out+1;*ptr=0;
for (i=0;i<numentries;i++)
{
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
cJSON_free(entries[i]);
}
cJSON_free(entries);
*ptr++=']';*ptr++=0;
return out;
}
/* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='{') {ep=value;return 0;} /* not an object! */
item->type=cJSON_Object;
value=skip(value+1);
if (*value=='}') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0;
value=skip(parse_string(child,skip(value)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if ((new_item=cJSON_New_Item()),new_item==0) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_string(child,skip(value+1)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
}
if (*value=='}') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt)
{
char **entries=0,**names=0;
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
cJSON *child=item->child;
int numentries=0,fail=0;
/* Count the number of entries. */
while (child) numentries++,child=child->next;
/* Explicitly handle empty object case */
if (!numentries)
{
out=(char*)cJSON_malloc(fmt?depth+4:3);
if (!out) return 0;
ptr=out;*ptr++='{';
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
*ptr++='}';*ptr++=0;
return out;
}
/* Allocate space for the names and the objects */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
names=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!names) {cJSON_free(entries);return 0;}
memset(entries,0,sizeof(char*)*numentries);
memset(names,0,sizeof(char*)*numentries);
/* Collect all the results into our arrays: */
child=item->child;depth++;if (fmt) len+=depth;
while (child)
{
names[i]=str=print_string_ptr(child->string);
entries[i++]=ret=print_value(child,depth,fmt);
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
child=child->next;
}
/* Try to allocate the output string */
if (!fail) out=(char*)cJSON_malloc(len);
if (!out) fail=1;
/* Handle failure */
if (fail)
{
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
cJSON_free(names);cJSON_free(entries);
return 0;
}
/* Compose the output: */
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
for (i=0;i<numentries;i++)
{
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
*ptr++=':';if (fmt) *ptr++='\t';
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) *ptr++=',';
if (fmt) *ptr++='\n';*ptr=0;
cJSON_free(names[i]);cJSON_free(entries[i]);
}
cJSON_free(names);cJSON_free(entries);
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
*ptr++='}';*ptr++=0;
return out;
}
/* Get Array size/item / object item. */
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
/* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
/* Add item to array/object. */
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
/* Replace array/object items with new ones. */
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
/* Create basic types: */
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
/* Create Arrays: */
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
/* Duplication */
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
{
cJSON *newitem,*cptr,*nptr=0,*newchild;
/* Bail on bad ptr */
if (!item) return 0;
/* Create new item */
newitem=cJSON_New_Item();
if (!newitem) return 0;
/* Copy over all vars */
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
/* If non-recursive, then we're done! */
if (!recurse) return newitem;
/* Walk the ->next chain for the child. */
cptr=item->child;
while (cptr)
{
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
if (!newchild) {cJSON_Delete(newitem);return 0;}
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
cptr=cptr->next;
}
return newitem;
}
void cJSON_Minify(char *json)
{
char *into=json;
while (*json)
{
if (*json==' ') json++;
else if (*json=='\t') json++; // Whitespace characters.
else if (*json=='\r') json++;
else if (*json=='\n') json++;
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
else *into++=*json++; // All other characters.
}
*into=0; // and null-terminate.
}

146
source/soft/cJSON.h Normal file
View File

@@ -0,0 +1,146 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
typedef struct cJSON_Hooks {
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
/* Update array items. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
extern void cJSON_Minify(char *json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#ifdef __cplusplus
}
#endif
#endif

109
source/soft/crc.c Normal file
View File

@@ -0,0 +1,109 @@
#include "crc.h"
uint8_t crc_crc8(const uint8_t *data,int num)
{
uint8_t crc = 0;
uint16_t j,i;
for (j = 0; j < num; j++)
{
crc ^= *(data+j);
for ( i = 0; i < 8; i++)
{
if ((crc & 0x01) != 0)
{
crc >>= 1;
crc ^= 0x8c;
}
else
{
crc >>= 1;
}
}
}
return crc;
}
void crc_crc16(const uint8_t *data, int len,uint8_t *lb,uint8_t *hb)
{
if (len > 0)
{
uint16_t crc = 0xFFFF;
int i = 0;
for (; i < len; i++)
{
crc = (uint16_t)(crc ^ (data[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (uint16_t)((crc >> 1) ^ 0xA001) : (uint16_t)(crc >> 1);
}
}
uint8_t hi = (uint8_t)((crc & 0xFF00) >> 8); //高位置
uint8_t lo = (uint8_t)(crc & 0x00FF); //低位置
*lb=lo;*hb=hi;
}
}
uint32_t crc_crc32(const uint8_t *data,int size)
{
uint32_t temp,crc=0xffffffff;
int i=0,j=0;
if((size%4)!=0)
{
return 0;
}
while(i<size)
{
temp=data[i]|(data[i+1]<<8)|(data[i+2]<<16)|(data[i+3]<<24);
i+=4;
for(j=0;j<32;j++)
{
if((crc^temp)&0x80000000)
crc=0x04c11db7^(crc<<1);
else
crc<<=1;
temp<<=1;
}
crc&=0xffffffff;
}
return crc;
}
void crc_sumcheck(const uint8_t *data,int size,uint8_t *chka,uint8_t *chkb)
{
if(chka==0) return;
if(chkb==0) return;
*chka=0;
*chkb=0;
for(int i=0;i<size;i++)
{
*chka+=data[i];
*chkb+=*chka;
}
}

29
source/soft/crc.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef crc_h__
#define crc_h__
#include "stdint.h"
#include "bytearray.h"
uint8_t crc_crc8(const uint8_t *data,int num);
void crc_crc16(const uint8_t *data, int len,uint8_t *lb,uint8_t *hb);
uint32_t crc_crc32(const uint8_t *data,int size);
void crc_sumcheck(const uint8_t *data,int size,uint8_t *chka,uint8_t *chkb);
#endif

81
source/soft/debug.c Normal file
View File

@@ -0,0 +1,81 @@
//#include "if_rtt.h"
//#include "log.h"
#include "stdio.h"
#include "stdarg.h"
#include "debug.h"
#include "string.h"
#ifdef RT_THREAD
#include "rtthread.h"
#define DBG_DEV mylog()
#else
#define DBG_DEV rtt()
#endif
#define CONSOLEBUF_SIZE 1024
typedef struct{
int inited;
#ifdef RT_THREAD
struct rt_mutex mutex;
#endif
}self_def;
static self_def g_data;
int debug_init(void)
{
if(g_data.inited==0)
{
#ifdef RT_THREAD
rt_mutex_init(&g_data.mutex,"debug_mutex",RT_IPC_FLAG_FIFO);
#endif
//DBG_DEV->init();
//DBG_DEV->write((const uint8_t *)"\r\n",2);
g_data.inited=1;
DBG_LOG("debug inited.\r\n");
}
return 0;
}
void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...)
{
if(g_data.inited==0) return;
va_list args;
size_t length;
static char log_buf[CONSOLEBUF_SIZE];
static const char *level_str[]={"[info] ","[log] ","[warn] ","[err] "};
static int level_str_len[]={7,6,7,6};
if(level<DBG_LEVEL_INFO||level>DBG_LEVEL_ERR) return;
#ifdef RT_THREAD
rt_mutex_take(&g_data.mutex,RT_WAITING_FOREVER);
#endif
memcpy(log_buf,level_str[level],level_str_len[level]);
length=level_str_len[level];
length+=sprintf(log_buf + length,"%s|%s|%d| ",file,fun,line);
va_start(args, fmt);
length += vsnprintf(log_buf + length, sizeof(log_buf) - length - 1, fmt, args);
if (length > CONSOLEBUF_SIZE - 1)
length = CONSOLEBUF_SIZE - 1;
va_end(args);
memcpy(&log_buf[length],"\r\n",2);
length+=2;
log_buf[length]=0;length++;
//DBG_DEV->write((const uint8_t *)log_buf,length);
printf("%s",log_buf);
#ifdef RT_THREAD
rt_mutex_release(&g_data.mutex);
#endif
}

57
source/soft/debug.h Normal file
View File

@@ -0,0 +1,57 @@
#include "stdint.h"
#include "stdio.h"
/*r{ 修改日志打印等级 }c*/
#define DBG_LOG_LEVEL DBG_LEVEL_INFO
/*r{ 定义打印数据等级 }c*/
#define DBG_LEVEL_INFO 0
#define DBG_LEVEL_LOG 1
#define DBG_LEVEL_WARN 2
#define DBG_LEVEL_ERR 3
#if (DBG_LOG_LEVEL<=DBG_LEVEL_INFO)
#define DBG_INFO( ml_msg_, ...) \
DBG_LOG_(DBG_LEVEL_INFO, (ml_msg_), ##__VA_ARGS__)
#else
#define DBG_INFO( ml_msg_, ...)
#endif
#if (DBG_LOG_LEVEL<=DBG_LEVEL_LOG)
#define DBG_LOG( ml_msg_, ...) \
DBG_LOG_(DBG_LEVEL_LOG, (ml_msg_), ##__VA_ARGS__)
#else
#define DBG_LOG( ml_msg_, ...)
#endif
#if (DBG_LOG_LEVEL<=DBG_LEVEL_WARN)
#define DBG_WARN( ml_msg_, ...) \
DBG_LOG_(DBG_LEVEL_WARN, (ml_msg_), ##__VA_ARGS__)
#else
#define DBG_WARN( ml_msg_, ...)
#endif
#if (DBG_LOG_LEVEL<=DBG_LEVEL_ERR)
#define DBG_ERR( ml_msg_, ...) \
DBG_LOG_(DBG_LEVEL_ERR, (ml_msg_), ##__VA_ARGS__)
#else
#define DBG_ERR( ml_msg_, ...)
#endif
#define DBG_LOG_(type_,msg_,...)\
debug_log(__FILE__,__func__,__LINE__,type_,(msg_),##__VA_ARGS__)
int debug_init(void);
void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...);

View File

@@ -0,0 +1,556 @@
#include "myjson.h"
#include "board.h"
#include "debug.h"
#include "mystdlib.h"
#include "bytearray.h"
// json<6F>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊjson,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱָ<CAB1><D6B8>
cJSON *json_parse(const char *jstr)
{
cJSON *json=cJSON_Parse(jstr);
if(json){
return tappend(json,cJSON_Delete);
}
return json;
}
/*r{ json ת<>б<EFBFBD> }c*/
list_def *jarray_to_list(cJSON *jarray,obj_def *obj)
{
param_check(obj);
param_check(obj->to_obj_fun);
param_check(obj->obj_size);
param_check(jarray);
list_def *l=list_creat(obj->obj_size,obj->sub,obj->del,0);
void *o;
int array_size;
if(jarray->type!=cJSON_Array){
DBG_WARN("json:%s not a array obj.",jarray->string?jarray->string:"null");
goto err;
}
array_size=cJSON_GetArraySize(jarray);
for(int i=0;i<array_size;i++)
{
o=obj->to_obj_fun(cJSON_GetArrayItem(jarray,i));
if(o==0)
{
DBG_WARN("json:%s conversion failed.",jarray->string?jarray->string:"null");
goto err;
}
list_append(l,o);
if(obj->del_fun) obj->del_fun(o);
}
err:
return l;
}
/*r{ jsonת<6E><D7AA><EFBFBD><EFBFBD> }c*/
static void *json_to_int(cJSON *j)
{
if(j->type==cJSON_Number)
{
int *ret=malloc(sizeof(int));
param_check(ret);
*ret=j->valueint;
return ret;
}
return 0;
}
static obj_def g_obj_int={
.obj_size=sizeof(int),
.to_obj_fun=json_to_int,
.del_fun=free,
.sub=INT_SUB,
.del=INT_DEL
};
obj_def *obj_int(void)
{
return &g_obj_int;
}
/*r{ jsonת<6E>ַ<EFBFBD><D6B7><EFBFBD> }c*/
static void *json_to_str(cJSON *j)
{
if(j->type==cJSON_String)
{
int len=strlen(j->valuestring)+1;
char *ret=malloc(len);
char **ret_ptr=malloc(sizeof(char *));
param_check(ret);
param_check(ret_ptr);
memcpy(ret,j->valuestring,len+1);
*ret_ptr=ret;
return ret_ptr;
}
return 0;
}
static obj_def g_obj_str={
.obj_size=sizeof(char *),
.to_obj_fun=json_to_str,
.del_fun=free,
.sub=STR_SUB,
.del=STR_DEL
};
obj_def *obj_str(void)
{
return &g_obj_str;
}
static void *json_to_range(cJSON *j)
{
sch_range *s=malloc(sizeof(sch_range));
param_check(s);
JSON_GET_INT(cJSON_GetObjectItem(j,"Max"),s->max);
JSON_GET_INT(cJSON_GetObjectItem(j,"Min"),s->min);
if(s->min>s->max){
DBG_WARN("range is empty.");
}
return s;
}
static obj_def g_obj_range={
.obj_size=sizeof(sch_range),
.to_obj_fun=json_to_range,
.del_fun=free,
.sub=0,
.del=0
};
obj_def *obj_range(void)
{
return &g_obj_range;
}
// <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><CEA7>
int range_in_range(sch_range *r,int num)
{
if(num>=r->min&&num<=r->max)
return 1;
else
return 0;
}
static void *json_to_task(cJSON *j)
{
sch_task *task=calloc(1,sizeof(sch_range));
JSON_GET_STR(cJSON_GetObjectItem(j,"TaskBrief"),task->brief);
JSON_GET_INT(cJSON_GetObjectItem(j,"TaskID"),task->task_id);
JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIndex"),task->index);
JSON_GET_INT(cJSON_GetObjectItem(j,"ErrJumpTo"),task->err_jump);
JSON_GET_INT(cJSON_GetObjectItem(j,"RetryCount"),task->retry);
JSON_GET_INT(cJSON_GetObjectItem(j,"ParamCount"),task->param_num);
JSON_GET_INT(cJSON_GetObjectItem(j,"ReturnCount"),task->return_num);
task->params_info=jarray_to_list(cJSON_GetObjectItem(j,"ParamInfo"),obj_str());
task->returns_info=jarray_to_list(cJSON_GetObjectItem(j,"ReturnInfo"),obj_str());
task->params=jarray_to_list(cJSON_GetObjectItem(j,"ParamVal"),obj_int());
task->ranges=jarray_to_list(cJSON_GetObjectItem(j,"TestStandard"),obj_range());
JSON_GET_INT(cJSON_GetObjectItem(j,"ExecuteErrCode"),task->failed_code);
task->ret_failed_code=jarray_to_list(cJSON_GetObjectItem(j,"ResultErrCode"),obj_int());
return task;
}
static int _list_del_task(void *p)
{
sch_task *t=p;
CHECK_DO(t->brief,free);
CHECK_DO(t->params_info,list_delete);
CHECK_DO(t->returns_info,list_delete);
CHECK_DO(t->params,list_delete);
CHECK_DO(t->ranges,list_delete);
CHECK_DO(t->ret_failed_code,list_delete);
CHECK_DO(t->ch_errcode,list_delete);
return 0;
}
static obj_def g_obj_task={
.obj_size=sizeof(sch_task),
.to_obj_fun=json_to_task,
.del_fun=free,
.sub=0,
.del=_list_del_task
};
obj_def *obj_task(void)
{
return &g_obj_task;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
array_def *task_to_array(sch_task *t)
{
array_def *a=arr_creat();
arr_append(a,(uint8_t)t->task_id);
arr_append(a,(uint8_t)t->index);
arr_append(a,(uint8_t)t->retry);
arr_append(a,(uint8_t)t->err_jump);
arr_append(a,(uint8_t)(t->param_num&0x0f)|(t->return_num<<4));
for(int i=0;i<list_length(t->params);i++)
{
arr_append(a,(uint8_t)(list_get_int(t->params,i)&0xff));
arr_append(a,(uint8_t)(list_get_int(t->params,i)>>8));
}
if(list_length(t->params)!=t->param_num)
{
DBG_WARN("name=%s param_num!=params.size().",t->brief);
}
if(t->return_num>list_length(t->returns_info))
{
DBG_WARN("name=%s return_num>returns_info.size().",t->brief);
}
if(list_length(t->ch_errcode)!=list_length(t->ranges))
{
DBG_WARN("name=%s ch_errcode.size()!=ranges.size().",t->brief);
}
return a;
}
// ack==0<>ɹ<EFBFBD>
task_returns *task_check_returns(sch_task *t,int ack,array_def *data)
{
int size=sizeof(task_returns)+sizeof(reurn_item)*t->return_num;
task_returns *res=malloc(size);
param_check(res);
res->size=size;
memset(res,0,size);
if(t->ch_errcode==0) t->ch_errcode=list_creat_int();
list_clear(t->ch_errcode);
res->index=t->index;
res->id=t->task_id;
res->ack=ack;
if(res->ack==0){
res->exe_err=0;
}else{
res->exe_err=t->failed_code;
list_append_int(t->ch_errcode,t->failed_code);
}
if(arr_length(data)/2<t->return_num){
DBG_WARN("task=%s, data size too less.",t->brief);
}else{
for(int i=0;i<t->return_num;i++)
{
reurn_item *item=&res->items[i];
int value=arr_get(data,i*2)|(arr_get(data,i*2+1)<<8);
item->value=value;
if(list_length(t->ranges)>i)
{
if(range_in_range(list_get(t->ranges,i),value))
item->err=0;
else{
if(list_length(t->ret_failed_code)>i)
{
item->err=list_get_int(t->ret_failed_code,i);
list_append_int(t->ch_errcode,item->err);
}
}
}
}
}
return res;
}
static void *json_to_errcode(cJSON *j)
{
sch_errcode *e=calloc(1,sizeof(sch_errcode));
param_check(e);
JSON_GET_INT(cJSON_GetObjectItem(j,"MajorErrCode"),e->err);
JSON_GET_STR(cJSON_GetObjectItem(j,"Info"),e->info);
e->suberr=jarray_to_list(cJSON_GetObjectItem(j,"SubErrCode"),obj_int());
return e;
}
static int _list_del_errcode(void *p)
{
sch_errcode *e=p;
CHECK_DO(e->info,free);
CHECK_DO(e->suberr,list_delete);
return 0;
}
static obj_def g_obj_errcode={
.obj_size=sizeof(sch_errcode),
.to_obj_fun=json_to_errcode,
.del_fun=free,
.sub=0,
.del=_list_del_errcode
};
obj_def *obj_errcode(void)
{
return &g_obj_errcode;
}
// <20><><EFBFBD><EFBFBD>1<EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><CEA7>
int errcode_in_range(sch_errcode *e,int subcode)
{
param_check(e);
for(int i=0;i<list_length(e->suberr);i++)
{
if(subcode==list_get_int(e->suberr,i))
return 1;
}
return 0;
}
static void *_json_to_scheme(cJSON *j)
{
scheme_def *s=calloc(1,sizeof(scheme_def));
param_check(s);
JSON_GET_INT(cJSON_GetObjectItem(j,"PlanID"),s->plan_id);
JSON_GET_STR(cJSON_GetObjectItem(j,"PlanBrief"),s->brief);
s->slave_soft_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckSoftVersion"),obj_int());
s->slave_hard_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckHardVersion"),obj_int());
JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutS"),s->timeout_s);
JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutM"),s->timeout_m);
JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIDMax"),s->task_id_max);
s->errs=jarray_to_list(cJSON_GetObjectItem(j,"MajorErrInfo"),obj_errcode());
s->tasks=jarray_to_list(cJSON_GetObjectItem(j,"TaskArray"),obj_task());
return s;
}
static int _list_del_scheme(void *p)
{
scheme_def *t=p;
CHECK_DO(t->brief,free);
CHECK_DO(t->slave_soft_versions,list_delete);
CHECK_DO(t->slave_hard_versions,list_delete);
CHECK_DO(t->errs,list_delete);
CHECK_DO(t->tasks,list_delete);
CHECK_DO(t->ch_errcode,list_delete);
return 0;
}
static obj_def g_obj_scheme={
.obj_size=sizeof(scheme_def),
.to_obj_fun=_json_to_scheme,
.del_fun=free,
.sub=0,
.del=_list_del_scheme
};
obj_def *obj_scheme(void)
{
return &g_obj_scheme;
}
scheme_def *json_to_scheme(cJSON *j)
{
param_check(j);
obj_def *obj=obj_scheme();
scheme_def *s=obj->to_obj_fun(j);
return s;
}
void scheme_delete(scheme_def *s)
{
obj_def *obj=obj_scheme();
param_check(s);
obj->del(s);
obj->del_fun(s);
}
// <20><><EFBFBD><EFBFBD>idת<64><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
#define TASKSID_MAX_SIZE 0x100
static array_def *scheme_taskid_to_array(scheme_def *s)
{
param_check(s);
array_def *res=arr_creat();
param_check(res);
arr_append(res,s->plan_id&0xff);
arr_append(res,(s->plan_id>>8)&0xff);
arr_append(res,(s->plan_id>>16)&0xff);
arr_append(res,(s->plan_id>>24)&0xff);
for(int i=0;i<list_length(s->tasks);i++)
{
sch_task *t=list_get(s->tasks,i);
arr_append(res,t->task_id);
}
int size=arr_length(res);
if(size<TASKSID_MAX_SIZE){
arr_append_num(res,TASKSID_MAX_SIZE-size,0xff);
}else{
DBG_WARN("taskid array size too larg.");
}
return res;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
#define TASKS_MAX_SIZE (0x700-4)
static array_def *scheme_tasks_to_array(scheme_def *s)
{
param_check(s);
array_def *res=arr_creat();
param_check(res);
for(int i=0;i<list_length(s->tasks);i++)
{
sch_task *t=list_get(s->tasks,i);
array_def *a=task_to_array(t);
arr_appends_from(res,a);
arr_delete(a);
}
int size=arr_length(res);
if(size<TASKS_MAX_SIZE)
{
arr_append_num(res,TASKS_MAX_SIZE-size,0xff);
}else{
DBG_WARN("tasks array size too larg.");
}
return res;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
array_def *scheme_to_byte_array(scheme_def *s)
{
param_check(s);
array_def *res=arr_creat();
param_check(res);
array_def *src;
src=scheme_taskid_to_array(s);
arr_appends_from(res,src);
arr_delete(src);
src=scheme_tasks_to_array(s);
arr_appends_from(res,src);
arr_delete(src);
return res;
}
// ͳ<>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
int scheme_get_returns_num(scheme_def *s)
{
int num=0;
for(int i=0;i<list_length(s->tasks);i++)
{
sch_task *t=list_get(s->tasks,i);
num+=t->return_num;
}
return num;
}
// <20><><EFBFBD><EFBFBD>0<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><31><CAA7>
int scheme_check_ack(array_def *data,int index)
{
param_check(index>=0);
param_check(index<arr_length(data)*8);
uint8_t temp=arr_get(data,index/8);
if((temp&(1<<(index%8)))!=0)
{return 1;}else{return 0;}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>0
int scheme_fine_majercode(scheme_def *s,int subcode)
{
for(int i=0;i<list_length(s->errs);i++)
{
sch_errcode *e=list_get(s->errs,i);
if(errcode_in_range(e,subcode))
return e->err;
}
return 0;
}
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
scheme_returns *scheme_check_returns(scheme_def *s,array_def *data)
{
int size=0;
size+=sizeof(scheme_returns);
size+=sizeof(task_returns)*list_length(s->tasks);
size+=sizeof(reurn_item)*scheme_get_returns_num(s);
scheme_returns *res=malloc(size);
param_check(res);
memset(res,0,size);
res->size=size;
if(s->ch_errcode==0) s->ch_errcode= list_creat_int();
list_clear(s->ch_errcode);
int start=16;
int off=0;
for(int i=0;i<list_length(s->tasks);i++)
{
int ack=scheme_check_ack(data,i);
sch_task *t=list_get(s->tasks,i);
array_def *arr_temp=arr_mid(data,start,t->return_num*2);
task_returns *task_ret=task_check_returns(t,ack,arr_temp);
arr_delete(arr_temp);
memcpy(&res->data[off],task_ret,task_ret->size);
off+=task_ret->size;
start+=t->return_num*2;
list_append_from(s->ch_errcode,t->ch_errcode);
}
if(list_length(s->ch_errcode)>0)
{
res->errcode=scheme_fine_majercode(s,list_get_int(s->ch_errcode,0));
}else{
res->errcode=0;
}
return res;
}

View File

@@ -0,0 +1,156 @@
#ifndef myjson_h__
#define myjson_h__
#include "cjson.h"
#include "list.h"
#include "bytearray.h"
#define JSON_GET_INT(j,v) {\
if(j->type==cJSON_Number)\
{\
v=j->valueint;\
}else{\
DBG_WARN("%s not a int value.",#j);\
}}
// <20><>ȡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>v==0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
#define JSON_GET_STR(j,v) {\
if(j->type==cJSON_String)\
{\
int len=strlen(j->valuestring)+1;\
if(v==0){\
v=malloc(len);\
}\
memcpy(v,j->valuestring,len);\
}else{\
DBG_WARN("%s not a str value.",#j);\
}}
typedef void *(*json_to_obj)(cJSON *j);
typedef void (*del_obj)(void *obj);
typedef struct {
int obj_size;
json_to_obj to_obj_fun;
del_obj del_fun;
// <20><>Щ<EFBFBD><D0A9><EFBFBD>б<EFBFBD><D0B1>Ļص<C4BB>
sub_fun_def sub;
del_fun_def del;
}obj_def;
obj_def *obj_int(void);
obj_def *obj_str(void);
list_def *jarray_to_list(cJSON *jarray,obj_def *obj);
cJSON *json_parse(const char *jstr);/*temp_ptr*/
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ
typedef struct {
int max;
int min;
}sch_range;
obj_def *obj_range(void);
int range_in_range(sch_range *r,int num);
// <20><><EFBFBD><EFBFBD>
typedef struct{
char *brief;
int task_id;
int index;
int param_num;
list_def *params_info;//str
list_def *params;//int
list_def *ranges;//sch_range
int return_num;
list_def *returns_info;//str
int err_jump;
int retry;
int failed_code;
list_def *ret_failed_code;//int
list_def *ch_errcode;//int
}sch_task;
__packed
typedef struct{
uint16_t value;
uint8_t err;
}reurn_item;
__packed
typedef struct{
uint8_t size;
uint8_t index;
uint8_t id;
uint8_t ack;
uint8_t exe_err;
reurn_item items[0];
}task_returns;
obj_def *obj_task(void);
array_def *task_to_array(sch_task *t);
task_returns *task_check_returns(sch_task *t,int ack,array_def *data);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
typedef struct{
int err;
char *info;
list_def *suberr;//int
}sch_errcode;
obj_def *obj_errcode(void);
int errcode_in_range(sch_errcode *e,int subcode);
typedef struct{
int plan_id;
char *brief;
list_def *slave_soft_versions;//int
list_def *slave_hard_versions;//int
int timeout_s;
int timeout_m;
int task_id_max;
list_def *errs;//sch_errcode
list_def *tasks;//sch_task
list_def *ch_errcode;//int
}scheme_def;
obj_def *obj_scheme(void);
scheme_def *json_to_scheme(cJSON *j);
void scheme_delete(scheme_def *s);
array_def *scheme_to_byte_array(scheme_def *s);
__packed
typedef struct{
uint16_t size;
uint8_t errcode;
uint8_t data[0];
}scheme_returns;
scheme_returns *scheme_check_returns(scheme_def *s,array_def *data);
#endif

View File

@@ -0,0 +1,556 @@
#include "myjson.h"
#include "board.h"
#include "debug.h"
#include "mystdlib.h"
#include "bytearray.h"
// json<6F>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊjson,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱָ<CAB1><D6B8>
cJSON *json_parse(const char *jstr)
{
cJSON *json=cJSON_Parse(jstr);
if(json){
return tappend(json,cJSON_Delete);
}
return json;
}
/*r{ json ת<>б<EFBFBD> }c*/
list_def *jarray_to_list(cJSON *jarray,obj_def *obj)
{
param_check(obj);
param_check(obj->to_obj_fun);
param_check(obj->obj_size);
param_check(jarray);
list_def *l=list_creat(obj->obj_size,obj->sub,obj->del,0);
void *o;
int array_size;
if(jarray->type!=cJSON_Array){
DBG_WARN("json:%s not a array obj.",jarray->string?jarray->string:"null");
goto err;
}
array_size=cJSON_GetArraySize(jarray);
for(int i=0;i<array_size;i++)
{
o=obj->to_obj_fun(cJSON_GetArrayItem(jarray,i));
if(o==0)
{
DBG_WARN("json:%s conversion failed.",jarray->string?jarray->string:"null");
goto err;
}
list_append(l,o);
if(obj->del_fun) obj->del_fun(o);
}
err:
return l;
}
/*r{ jsonת<6E><D7AA><EFBFBD><EFBFBD> }c*/
static void *json_to_int(cJSON *j)
{
if(j->type==cJSON_Number)
{
int *ret=malloc(sizeof(int));
param_check(ret);
*ret=j->valueint;
return ret;
}
return 0;
}
static obj_def g_obj_int={
.obj_size=sizeof(int),
.to_obj_fun=json_to_int,
.del_fun=free,
.sub=INT_SUB,
.del=INT_DEL
};
obj_def *obj_int(void)
{
return &g_obj_int;
}
/*r{ jsonת<6E>ַ<EFBFBD><D6B7><EFBFBD> }c*/
static void *json_to_str(cJSON *j)
{
if(j->type==cJSON_String)
{
int len=strlen(j->valuestring)+1;
char *ret=malloc(len);
char **ret_ptr=malloc(sizeof(char *));
param_check(ret);
param_check(ret_ptr);
memcpy(ret,j->valuestring,len+1);
*ret_ptr=ret;
return ret_ptr;
}
return 0;
}
static obj_def g_obj_str={
.obj_size=sizeof(char *),
.to_obj_fun=json_to_str,
.del_fun=free,
.sub=STR_SUB,
.del=STR_DEL
};
obj_def *obj_str(void)
{
return &g_obj_str;
}
static void *json_to_range(cJSON *j)
{
sch_range *s=malloc(sizeof(sch_range));
param_check(s);
JSON_GET_INT(cJSON_GetObjectItem(j,"Max"),s->max);
JSON_GET_INT(cJSON_GetObjectItem(j,"Min"),s->min);
if(s->min>s->max){
DBG_WARN("range is empty.");
}
return s;
}
static obj_def g_obj_range={
.obj_size=sizeof(sch_range),
.to_obj_fun=json_to_range,
.del_fun=free,
.sub=0,
.del=0
};
obj_def *obj_range(void)
{
return &g_obj_range;
}
// <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><CEA7>
int range_in_range(sch_range *r,int num)
{
if(num>=r->min&&num<=r->max)
return 1;
else
return 0;
}
static void *json_to_task(cJSON *j)
{
sch_task *task=calloc(1,sizeof(sch_range));
JSON_GET_STR(cJSON_GetObjectItem(j,"TaskBrief"),task->brief);
JSON_GET_INT(cJSON_GetObjectItem(j,"TaskID"),task->task_id);
JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIndex"),task->index);
JSON_GET_INT(cJSON_GetObjectItem(j,"ErrJumpTo"),task->err_jump);
JSON_GET_INT(cJSON_GetObjectItem(j,"RetryCount"),task->retry);
JSON_GET_INT(cJSON_GetObjectItem(j,"ParamCount"),task->param_num);
JSON_GET_INT(cJSON_GetObjectItem(j,"ReturnCount"),task->return_num);
task->params_info=jarray_to_list(cJSON_GetObjectItem(j,"ParamInfo"),obj_str());
task->returns_info=jarray_to_list(cJSON_GetObjectItem(j,"ReturnInfo"),obj_str());
task->params=jarray_to_list(cJSON_GetObjectItem(j,"ParamVal"),obj_int());
task->ranges=jarray_to_list(cJSON_GetObjectItem(j,"TestStandard"),obj_range());
JSON_GET_INT(cJSON_GetObjectItem(j,"ExecuteErrCode"),task->failed_code);
task->ret_failed_code=jarray_to_list(cJSON_GetObjectItem(j,"ResultErrCode"),obj_int());
return task;
}
static int _list_del_task(void *p)
{
sch_task *t=p;
CHECK_DO(t->brief,free);
CHECK_DO(t->params_info,list_delete);
CHECK_DO(t->returns_info,list_delete);
CHECK_DO(t->params,list_delete);
CHECK_DO(t->ranges,list_delete);
CHECK_DO(t->ret_failed_code,list_delete);
CHECK_DO(t->ch_errcode,list_delete);
return 0;
}
static obj_def g_obj_task={
.obj_size=sizeof(sch_task),
.to_obj_fun=json_to_task,
.del_fun=free,
.sub=0,
.del=_list_del_task
};
obj_def *obj_task(void)
{
return &g_obj_task;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
array_def *task_to_array(sch_task *t)
{
array_def *a=arr_creat();
arr_append(a,(uint8_t)t->task_id);
arr_append(a,(uint8_t)t->index);
arr_append(a,(uint8_t)t->retry);
arr_append(a,(uint8_t)t->err_jump);
arr_append(a,(uint8_t)(t->param_num&0x0f)|(t->return_num<<4));
for(int i=0;i<list_length(t->params);i++)
{
arr_append(a,(uint8_t)(list_get_int(t->params,i)&0xff));
arr_append(a,(uint8_t)(list_get_int(t->params,i)>>8));
}
if(list_length(t->params)!=t->param_num)
{
DBG_WARN("name=%s param_num!=params.size().",t->brief);
}
if(t->return_num>list_length(t->returns_info))
{
DBG_WARN("name=%s return_num>returns_info.size().",t->brief);
}
if(list_length(t->ch_errcode)!=list_length(t->ranges))
{
DBG_WARN("name=%s ch_errcode.size()!=ranges.size().",t->brief);
}
return a;
}
// ack==0<>ɹ<EFBFBD>
task_returns *task_check_returns(sch_task *t,int ack,array_def *data)
{
int size=sizeof(task_returns)+sizeof(reurn_item)*t->return_num;
task_returns *res=malloc(size);
param_check(res);
res->size=size;
memset(res,0,size);
if(t->ch_errcode==0) t->ch_errcode=list_creat_int();
list_clear(t->ch_errcode);
res->index=t->index;
res->id=t->task_id;
res->ack=ack;
if(res->ack==0){
res->exe_err=0;
}else{
res->exe_err=t->failed_code;
list_append_int(t->ch_errcode,t->failed_code);
}
if(arr_length(data)/2<t->return_num){
DBG_WARN("task=%s, data size too less.",t->brief);
}else{
for(int i=0;i<t->return_num;i++)
{
reurn_item *item=&res->items[i];
int value=arr_get(data,i*2)|(arr_get(data,i*2+1)<<8);
item->value=value;
if(list_length(t->ranges)>i)
{
if(range_in_range(list_get(t->ranges,i),value))
item->err=0;
else{
if(list_length(t->ret_failed_code)>i)
{
item->err=list_get_int(t->ret_failed_code,i);
list_append_int(t->ch_errcode,item->err);
}
}
}
}
}
return res;
}
static void *json_to_errcode(cJSON *j)
{
sch_errcode *e=calloc(1,sizeof(sch_errcode));
param_check(e);
JSON_GET_INT(cJSON_GetObjectItem(j,"MajorErrCode"),e->err);
JSON_GET_STR(cJSON_GetObjectItem(j,"Info"),e->info);
e->suberr=jarray_to_list(cJSON_GetObjectItem(j,"SubErrCode"),obj_int());
return e;
}
static int _list_del_errcode(void *p)
{
sch_errcode *e=p;
CHECK_DO(e->info,free);
CHECK_DO(e->suberr,list_delete);
return 0;
}
static obj_def g_obj_errcode={
.obj_size=sizeof(sch_errcode),
.to_obj_fun=json_to_errcode,
.del_fun=free,
.sub=0,
.del=_list_del_errcode
};
obj_def *obj_errcode(void)
{
return &g_obj_errcode;
}
// <20><><EFBFBD><EFBFBD>1<EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><CEA7>
int errcode_in_range(sch_errcode *e,int subcode)
{
param_check(e);
for(int i=0;i<list_length(e->suberr);i++)
{
if(subcode==list_get_int(e->suberr,i))
return 1;
}
return 0;
}
static void *_json_to_scheme(cJSON *j)
{
scheme_def *s=calloc(1,sizeof(scheme_def));
param_check(s);
JSON_GET_INT(cJSON_GetObjectItem(j,"PlanID"),s->plan_id);
JSON_GET_STR(cJSON_GetObjectItem(j,"PlanBrief"),s->brief);
s->slave_soft_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckSoftVersion"),obj_int());
s->slave_hard_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckHardVersion"),obj_int());
JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutS"),s->timeout_s);
JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutM"),s->timeout_m);
JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIDMax"),s->task_id_max);
s->errs=jarray_to_list(cJSON_GetObjectItem(j,"MajorErrInfo"),obj_errcode());
s->tasks=jarray_to_list(cJSON_GetObjectItem(j,"TaskArray"),obj_task());
return s;
}
static int _list_del_scheme(void *p)
{
scheme_def *t=p;
CHECK_DO(t->brief,free);
CHECK_DO(t->slave_soft_versions,list_delete);
CHECK_DO(t->slave_hard_versions,list_delete);
CHECK_DO(t->errs,list_delete);
CHECK_DO(t->tasks,list_delete);
CHECK_DO(t->ch_errcode,list_delete);
return 0;
}
static obj_def g_obj_scheme={
.obj_size=sizeof(scheme_def),
.to_obj_fun=_json_to_scheme,
.del_fun=free,
.sub=0,
.del=_list_del_scheme
};
obj_def *obj_scheme(void)
{
return &g_obj_scheme;
}
scheme_def *json_to_scheme(cJSON *j)
{
param_check(j);
obj_def *obj=obj_scheme();
scheme_def *s=obj->to_obj_fun(j);
return s;
}
void scheme_delete(scheme_def *s)
{
obj_def *obj=obj_scheme();
param_check(s);
obj->del(s);
obj->del_fun(s);
}
// <20><><EFBFBD><EFBFBD>idת<64><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
#define TASKSID_MAX_SIZE 0x100
static array_def *scheme_taskid_to_array(scheme_def *s)
{
param_check(s);
array_def *res=arr_creat();
param_check(res);
arr_append(res,s->plan_id&0xff);
arr_append(res,(s->plan_id>>8)&0xff);
arr_append(res,(s->plan_id>>16)&0xff);
arr_append(res,(s->plan_id>>24)&0xff);
for(int i=0;i<list_length(s->tasks);i++)
{
sch_task *t=list_get(s->tasks,i);
arr_append(res,t->task_id);
}
int size=arr_length(res);
if(size<TASKSID_MAX_SIZE){
arr_append_num(res,TASKSID_MAX_SIZE-size,0xff);
}else{
DBG_WARN("taskid array size too larg.");
}
return res;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
#define TASKS_MAX_SIZE (0x700-4)
static array_def *scheme_tasks_to_array(scheme_def *s)
{
param_check(s);
array_def *res=arr_creat();
param_check(res);
for(int i=0;i<list_length(s->tasks);i++)
{
sch_task *t=list_get(s->tasks,i);
array_def *a=task_to_array(t);
arr_appends_from(res,a);
arr_delete(a);
}
int size=arr_length(res);
if(size<TASKS_MAX_SIZE)
{
arr_append_num(res,TASKS_MAX_SIZE-size,0xff);
}else{
DBG_WARN("tasks array size too larg.");
}
return res;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
array_def *scheme_to_byte_array(scheme_def *s)
{
param_check(s);
array_def *res=arr_creat();
param_check(res);
array_def *src;
src=scheme_taskid_to_array(s);
arr_appends_from(res,src);
arr_delete(src);
src=scheme_tasks_to_array(s);
arr_appends_from(res,src);
arr_delete(src);
return res;
}
// ͳ<>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
int scheme_get_returns_num(scheme_def *s)
{
int num=0;
for(int i=0;i<list_length(s->tasks);i++)
{
sch_task *t=list_get(s->tasks,i);
num+=t->return_num;
}
return num;
}
// <20><><EFBFBD><EFBFBD>0<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><31><CAA7>
int scheme_check_ack(array_def *data,int index)
{
param_check(index>=0);
param_check(index<arr_length(data)*8);
uint8_t temp=arr_get(data,index/8);
if((temp&(1<<(index%8)))!=0)
{return 1;}else{return 0;}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>0
int scheme_fine_majercode(scheme_def *s,int subcode)
{
for(int i=0;i<list_length(s->errs);i++)
{
sch_errcode *e=list_get(s->errs,i);
if(errcode_in_range(e,subcode))
return e->err;
}
return 0;
}
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
scheme_returns *scheme_check_returns(scheme_def *s,array_def *data)
{
int size=0;
size+=sizeof(scheme_returns);
size+=sizeof(task_returns)*list_length(s->tasks);
size+=sizeof(reurn_item)*scheme_get_returns_num(s);
scheme_returns *res=malloc(size);
param_check(res);
memset(res,0,size);
res->size=size;
if(s->ch_errcode==0) s->ch_errcode= list_creat_int();
list_clear(s->ch_errcode);
int start=16;
int off=0;
for(int i=0;i<list_length(s->tasks);i++)
{
int ack=scheme_check_ack(data,i);
sch_task *t=list_get(s->tasks,i);
array_def *arr_temp=arr_mid(data,start,t->return_num*2);
task_returns *task_ret=task_check_returns(t,ack,arr_temp);
arr_delete(arr_temp);
memcpy(&res->data[off],task_ret,task_ret->size);
off+=task_ret->size;
start+=t->return_num*2;
list_append_from(s->ch_errcode,t->ch_errcode);
}
if(list_length(s->ch_errcode)>0)
{
res->errcode=scheme_fine_majercode(s,list_get_int(s->ch_errcode,0));
}else{
res->errcode=0;
}
return res;
}

View File

@@ -0,0 +1,156 @@
#ifndef myjson_h__
#define myjson_h__
#include "cjson.h"
#include "list.h"
#include "bytearray.h"
#define JSON_GET_INT(j,v) {\
if(j->type==cJSON_Number)\
{\
v=j->valueint;\
}else{\
DBG_WARN("%s not a int value.",#j);\
}}
// <20><>ȡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>v==0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
#define JSON_GET_STR(j,v) {\
if(j->type==cJSON_String)\
{\
int len=strlen(j->valuestring)+1;\
if(v==0){\
v=malloc(len);\
}\
memcpy(v,j->valuestring,len);\
}else{\
DBG_WARN("%s not a str value.",#j);\
}}
typedef void *(*json_to_obj)(cJSON *j);
typedef void (*del_obj)(void *obj);
typedef struct {
int obj_size;
json_to_obj to_obj_fun;
del_obj del_fun;
// <20><>Щ<EFBFBD><D0A9><EFBFBD>б<EFBFBD><D0B1>Ļص<C4BB>
sub_fun_def sub;
del_fun_def del;
}obj_def;
obj_def *obj_int(void);
obj_def *obj_str(void);
list_def *jarray_to_list(cJSON *jarray,obj_def *obj);
cJSON *json_parse(const char *jstr);/*temp_ptr*/
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ
typedef struct {
int max;
int min;
}sch_range;
obj_def *obj_range(void);
int range_in_range(sch_range *r,int num);
// <20><><EFBFBD><EFBFBD>
typedef struct{
char *brief;
int task_id;
int index;
int param_num;
list_def *params_info;//str
list_def *params;//int
list_def *ranges;//sch_range
int return_num;
list_def *returns_info;//str
int err_jump;
int retry;
int failed_code;
list_def *ret_failed_code;//int
list_def *ch_errcode;//int
}sch_task;
__packed
typedef struct{
uint16_t value;
uint8_t err;
}reurn_item;
__packed
typedef struct{
uint8_t size;
uint8_t index;
uint8_t id;
uint8_t ack;
uint8_t exe_err;
reurn_item items[0];
}task_returns;
obj_def *obj_task(void);
array_def *task_to_array(sch_task *t);
task_returns *task_check_returns(sch_task *t,int ack,array_def *data);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
typedef struct{
int err;
char *info;
list_def *suberr;//int
}sch_errcode;
obj_def *obj_errcode(void);
int errcode_in_range(sch_errcode *e,int subcode);
typedef struct{
int plan_id;
char *brief;
list_def *slave_soft_versions;//int
list_def *slave_hard_versions;//int
int timeout_s;
int timeout_m;
int task_id_max;
list_def *errs;//sch_errcode
list_def *tasks;//sch_task
list_def *ch_errcode;//int
}scheme_def;
obj_def *obj_scheme(void);
scheme_def *json_to_scheme(cJSON *j);
void scheme_delete(scheme_def *s);
array_def *scheme_to_byte_array(scheme_def *s);
__packed
typedef struct{
uint16_t size;
uint8_t errcode;
uint8_t data[0];
}scheme_returns;
scheme_returns *scheme_check_returns(scheme_def *s,array_def *data);
#endif

588
source/soft/list.c Normal file
View File

@@ -0,0 +1,588 @@
#include "list.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "board.h"
#include "mystdlib.h"
#include "debug.h"
#include "bytearray.h"
#include "rtthread.h"
#define LIST_APPEND_SKIP 10
typedef struct{
int32_t next;
int32_t prev;
uint32_t data[0];
}list_node_def;
struct _list_def{
int32_t all;
int32_t used;
int32_t block_size;
int32_t block_size4;
rt_mutex_t mutex;
int32_t head;
int32_t tail;
sub_fun_def sub;
del_fun_def del;
str_fun_def str;
uint32_t data[0];
};
//#define list_enter_mutex(l)\
// rt_mutex_take((l)->mutex,RT_WAITING_FOREVER)
//
//#define list_exit_mutex(l)\
// rt_mutex_release((l)->mutex)
#define list_enter_mutex(l)
#define list_exit_mutex(l)
#define rt_mutex_create(...) 0
#define rt_mutex_delete(l)
list_def *list_creat(int block_size,sub_fun_def sub,del_fun_def del,str_fun_def str)
{
static uint16_t count=0;
char s1[16]={0};
sprintf(s1,"list_mut#%d",count);
int size=0;
int block_size4;
list_def *l;
size+=sizeof(list_def);
// 4字节对齐
block_size4=((block_size+3)/4)*4;
size+=(sizeof(list_node_def)+block_size4)*LIST_APPEND_SKIP;
l=malloc(size);
param_check(l);
l->all=LIST_APPEND_SKIP;
l->used=0;
l->block_size=block_size;
l->block_size4=block_size4;
l->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO);
l->head=-1;
l->tail=-1;
l->sub=sub;
l->del=del;
l->str=str;
// 初始化列表
list_node_def *node;
node=(list_node_def *)l->data;
for(int i=0;i<l->all;i++)
{
node->next=-1;
node->prev=-1;
node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4);
}
count++;
return l;
}
// 对于数据里有指针数据的成员,需要提供del函数
void _list_delete(list_def **l)
{
param_check(l);
param_check(*l);
list_enter_mutex(*l);
if((*l)->del)
{
for(int i=0;i<(*l)->used;i++)
{
(*l)->del(list_get(*l,i));
}
}
list_exit_mutex(*l);
rt_mutex_delete((*l)->mutex);
free(*l);
*l=0;
}
int list_block_size4(list_def *l)
{
param_check(l);
return l->block_size4;
}
//static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
//{
// for(int i=0;i<num_4byte;i++)
// {
// dst[i]=src[i];
// }
//}
static list_def *list_expend(list_def *l)
{
int size=0;
int cpysize=0;
list_def *r;
size+=sizeof(list_def);
size+=(sizeof(list_node_def)+l->block_size4)*(l->all);
cpysize=size;
size+=(sizeof(list_node_def)+l->block_size4)*(LIST_APPEND_SKIP);
r=malloc(size);
param_check(r);
cpy4byte((uint32_t *)r,(uint32_t *)l,cpysize/4);
// 初始化列表
list_node_def *node;
node=(list_node_def *)((uint32_t)r->data+r->all*(sizeof(list_node_def)+r->block_size4));
for(int i=0;i<LIST_APPEND_SKIP;i++)
{
node->next=-1;
node->prev=-1;
node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+r->block_size4);
}
r->all+=LIST_APPEND_SKIP;
free(l);
return r;
}
// 查找一个未使用的节点
static list_node_def *list_unused_node(list_def *l,int *index)
{
list_node_def *node=0;
node=(list_node_def *)l->data;
for(int i=0;i<l->all;i++)
{
if((node->next==-1)&&(node->prev==-1)){
if(index) *index=i;
return node;
}
node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4);
}
return node;
}
// 取得指定序号的节点
static list_node_def *list_node(list_def *l,int index)
{
list_node_def *node;
param_check(index>=0&&index<l->all);
node=(list_node_def *)((uint32_t)l->data+index*(sizeof(list_node_def)+l->block_size4));
return node;
}
// 取得节点的物理索引
static int list_phy_index(list_def *l,list_node_def *n)
{
return ((uint32_t)n-(uint32_t)l->data)/(sizeof(list_node_def)+l->block_size4);
}
/*
// 改为统一使用insert函数
list_def *list_append(list_def **l,void *data)
{
param_check(l);
param_check(*l);
list_def *r=*l;
if((*l)->used>=(*l)->all)
{
r=list_expend(*l);
}
list_node_def *node;
int index;
node=list_unused_node(r,&index);
param_check(node);
memcpy(node->data,data,r->block_size);
if(r->head==-1&&r->tail==-1)
{
r->head=index;
r->tail=index;
node->next=index;
node->prev=index;
}
else if(r->head!=-1&&r->tail!=-1)
{
node->prev=r->tail;
node->next=list_node(r,r->tail)->next;
list_node(r,r->tail)->next=index;
r->tail=index;
list_node(r,r->head)->prev=index;
}
else
{
param_check(0);
}
r->used++;
*l=r;
return r;
}
*/
// 返回指定index的已使用节点
static list_node_def *list_used_node(list_def *l,int index)
{
list_node_def *node=0;
if(index>l->used/2)
{
index=l->used-1-index;
node=list_node(l,l->tail);
for(int i=0;i<index;i++)
{
node=list_node(l,node->prev);
}
}
else{
node=list_node(l,l->head);
for(int i=0;i<index;i++)
{
node=list_node(l,node->next);
}
}
return node;
}
// 获取第index项数据,不删除
// index支持负数-1表示最后一项
// 返回数据引用
void *list_get(list_def *l,int index)
{
param_check(l);
void *ret=0;
list_enter_mutex(l);
list_node_def *node;
if(index<0) index=l->used+index;
if((index>=0&&index<l->used)==0)
ret=0;
else{
node=list_used_node(l,index);
param_check(node);
ret=node->data;
}
list_exit_mutex(l);
return ret;
}
// 删除第index项数据
// index支持负数-1表示最后一项
void list_remove(list_def *l,int index)
{
param_check(l);
list_node_def *node;
int phy_index;
if(index<0) index=l->used+index;
list_enter_mutex(l);
if((index>=0&&index<l->used)){
node=list_used_node(l,index);
param_check(node);
phy_index=list_phy_index(l,node);
if(l->used==1)
{
l->head=-1;
l->tail=-1;
}
else
{
if(l->head==phy_index)
{
l->head=node->next;
}
if(l->tail==phy_index)
{
l->tail=node->prev;
}
list_node(l,node->prev)->next=node->next;
list_node(l,node->next)->prev=node->prev;
}
node->next=-1;
node->prev=-1;
if(l->del) l->del(node->data);
l->used--;
}
list_enter_mutex(l);
}
// 获取指定index的数据随后删除
// 返回数据的临时指针
// 对于存在动态指针的对象由于take之后会自动删除take操作会出现野指针
// 建议使用list_get + list_remove的方式代替list_take
void *list_take(list_def *l,int index)
{
param_check(l);
void *p;
p=list_get(l,index);
void *t=tmalloc(l->block_size);
param_check(t);
memcpy(t,p,l->block_size);
list_remove(l,index);
return t;
}
// 清空
void list_clear(list_def *l)
{
param_check(l);
list_enter_mutex(l);
while(l->used>0)
{
list_remove(l,0);
}
list_exit_mutex(l);
}
int list_length(list_def *l)
{
param_check(l);
return l->used;
}
// 在指定位置插入
// index为节点插入之后所在的位置
list_def *_list_insert(list_def **l,void *data,int index)
{
param_check(l);
param_check(*l);
list_enter_mutex(*l);
if(index<0) index=(*l)->used+index+1;
if((index>=0&&index<=(*l)->used)==0){
list_exit_mutex(*l);
return *l;
}
list_def *r=*l;
if((*l)->used>=(*l)->all)
{
r=list_expend(*l);
}
list_node_def *node;
int phy_index;
node=list_unused_node(r,&phy_index);
param_check(node);
memcpy(node->data,data,r->block_size);
if(r->head==-1&&r->tail==-1)
{
r->head=phy_index;
r->tail=phy_index;
node->next=phy_index;
node->prev=phy_index;
}
else if(r->head!=-1&&r->tail!=-1)
{
list_node_def *n;
int n_phy_index;
if(index<r->used)
{
n=list_used_node(r,index);
n_phy_index=list_phy_index(r,n);
list_node(r,n->prev)->next=phy_index;
node->prev=n->prev;
node->next=n_phy_index;
n->prev=phy_index;
if(index==0)
{
r->head=phy_index;
}
}
else
{
node->prev=r->tail;
node->next=list_node(r,r->tail)->next;
list_node(r,r->tail)->next=phy_index;
r->tail=index;
list_node(r,r->head)->prev=phy_index;
}
}
else
{
param_check(0);
}
r->used++;
*l=r;
list_exit_mutex(*l);
return r;
}
void list_sort(list_def *l)
{
param_check(l);
list_enter_mutex(l);
if(l->sub){
_list_sort(l,l->sub);
}
else{
DBG_WARN("obj->sub fun is null.");
}
list_exit_mutex(l);
}
// 在列表内返回1不在返回0
int list_contains(list_def *l,void *d)
{
param_check(l);
list_enter_mutex(l);
if(l->sub)
{
for(int i=0;i<list_length(l);i++)
{
if(l->sub(list_get(l,i),d)==0){
list_exit_mutex(l);
return 1;
}
}
}
else{
DBG_WARN("obj->sub fun is null.");
}
list_exit_mutex(l);
return 0;
}
// 交换两个位置
void list_swap(list_def *l,int index_a,int index_b)
{
param_check(l);
list_enter_mutex(l);
void *a_=list_get(l,index_a);
void *b_=list_get(l,index_b);
void *t_=0;
if(a_&&b_)
{
t_=calloc(1,sizeof(l->block_size4));
cpy4byte(t_,a_,l->block_size4/4);
cpy4byte(a_,b_,l->block_size4/4);
cpy4byte(b_,t_,l->block_size4/4);
free(t_);
}
list_exit_mutex(l);
}
// 向后循环移动
void list_shift(list_def *l)
{
param_check(l);
list_enter_mutex(l);
if(l->used>0){
l->head=list_node(l,l->head)->next;
l->tail=list_node(l,l->tail)->next;
}
list_exit_mutex(l);
}
// 输出打印字符串
char *list_string(list_def *l)
{
param_check(l);
list_enter_mutex(l);
array_def *d=arr_creat();
param_check(d);
int len=0;
char *s=0;
arr_append(d,'(');
if(l->str)
{
for(int i=0;i<list_length(l);i++)
{
s=l->str(list_get(l,i));
len=strlen(s);
arr_appends(d,s,len);
free(s);
arr_append(d,',');
arr_append(d,' ');
}
}
arr_append(d,')');
len=arr_length(d);
s=malloc(len+1);
param_check(s);
memcpy(s,arr_data(d),len);
arr_delete(d);
s[len]=0;
list_exit_mutex(l);
return s;
}
// int sub函数
int _list_int_sub(void *a,void *b)
{
return *(int *)a-*(int *)b;
}
// int 打印函数
char *_list_int_str(void *a)
{
char *s=malloc(20);
param_check(s);
sprintf(s,"%d",*(int *)a);
return s;
}
// str sub函数
int _list_str_sub(void *a,void *b)
{
char *a_=*(char **)a;
char *b_=*(char **)b;
return strcmp(a_,b_);
}
// str删除函数
int _list_str_del(void *d)
{
char **c=d;
if(*c) free(*c);
return 0;
}
// str 打印函数
char *_list_str_str(void *a)
{
char *a_=*(char **)a;
int len=strlen(a_);
char *s=malloc(len+1);
param_check(s);
memcpy(s,a_,len+1);
return s;
}
// 延迟删除,不需要修改指针
void _list_delete_later(list_def *l)
{
_list_delete(&l);
}

90
source/soft/list.h Normal file
View File

@@ -0,0 +1,90 @@
#ifndef list_h__
#define list_h__
#include "stdint.h"
#include "stdlib.h"
struct _list_def;
typedef struct _list_def list_def;
typedef int (*sub_fun_def)(void *a,void *b);
typedef int (*del_fun_def)(void *p);
// 生成打印字符串指针列表获取后会使用free释放
typedef char *(*str_fun_def)(void *p);
#define INT_SUB _list_int_sub
#define INT_DEL 0
#define INT_STR _list_int_str
#define STR_SUB _list_str_sub
#define STR_DEL _list_str_del
#define STR_STR _list_str_str
/*r{ 基本操作函数 }c*/
list_def *list_creat(int block_size,sub_fun_def sub,del_fun_def del,str_fun_def str);
void *list_get(list_def *l,int index);
void list_remove(list_def *l,int index);
void *list_take(list_def *l,int index);/*temp_ptr*/
void list_clear(list_def *l);
int list_length(list_def *l);
int list_block_size4(list_def *l);
void list_sort(list_def *l);
int list_contains(list_def *l,void *d);
void list_swap(list_def *l,int index_a,int index_b);
char *list_string(list_def *l);
void list_shift(list_def *l);
/*r{ 宏函数 }c*/
#define list_creat_int() list_creat(sizeof(int),INT_SUB,INT_DEL,INT_STR)
#define list_creat_str() list_creat(sizeof(char *),STR_SUB,STR_DEL,STR_STR)
#define list_delete(l) _list_delete(&(l))
#define list_insert(l,data,index) _list_insert(&(l),data,index)
#define list_append(l,data) list_insert(l,data,-1)
#define list_insert_int(l,int_,index) list_insert(l,(uint32_t []){int_},index)
#define list_append_int(l,int_) list_insert_int(l,int_,-1)
#define list_append_str(l,str) list_insert_str(l,str,-1)
#define list_get_int(l,index) (*(int *)list_get(l,index))
#define list_get_str(sl,index) (*(char **)list_get(sl,index))
#define list_take_str(sl,index) (*(char **)list_take(sl,index))
#define list_take_int(l,index) (*(int *)list_take(l,index))
#define list_insert_str(l,str,index)\
{\
char *c=malloc(strlen(str)+1);\
param_check(c);\
memcpy(c,str,strlen(str)+1);\
list_insert(l,(uint32_t []){(uint32_t)(c)},index);}
// 要保证ab的类型相同
#define list_append_from(a,b) \
for(int i=0;i<list_length(b);i++) {list_append(a,list_get(b,i));}
#define list_appends(a,d,num) \
for(int i=0;i<num;i++) {list_append(a,&d[i]);}
// 转化为列表的临时指针
#define list_temp(l) tappend(l,_list_delete_later)
/*r{ 用户不应直接调用的函数 }c*/
list_def *_list_insert(list_def **l,void *data,int index);
void _list_delete(list_def **l);
void _list_delete_later(list_def *l);
int _list_int_sub(void *a,void *b);
char *_list_int_str(void *a);
int _list_str_sub(void *a,void *b);
int _list_str_del(void *d);
char *_list_str_str(void *a);
void _list_sort(list_def *l,sub_fun_def sub);
#endif

45
source/soft/mymisc.c Normal file
View File

@@ -0,0 +1,45 @@
#include "rtthread.h"
#include "stdlib.h"
#include "stdint.h"
#include "stdio.h"
typedef struct{
void (*later_fun)(void *t);
void *t;
rt_timer_t timer;
}later_def;
static void later_fun_exe(void *t)
{
later_def *l=t;
rt_timer_delete(l->timer);
if(l->later_fun){
l->later_fun(l->t);
}
free(l);
}
// 延迟一段时间调用函数
void later_execute(void (*fun)(void *t),void *t,int ms)
{
static uint16_t count;
char s1[16]={0};
sprintf(s1,"later_t#%d",count);
later_def *l=calloc(1,sizeof(later_def));
l->later_fun=fun;
l->t=t;
l->timer=rt_timer_create(s1,later_fun_exe,l,
rt_tick_from_millisecond(ms),
RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER);
rt_timer_start(l->timer);
count++;
}

20
source/soft/mymisc.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef mymisc_h__
#define mymisc_h__
void later_execute(void (*fun)(void *t),void *t,int ms);
#endif

352
source/soft/mystdlib.c Normal file
View File

@@ -0,0 +1,352 @@
#include "stdint.h"
#include "string.h"
#include "rtthread.h"
#include "board.h"
#include "debug.h"
typedef struct
{
uint8_t *membase; // 内存池
uint8_t memrdy; // 内存管理是否就绪
uint16_t *memmap; // 内存管理状态表
// 内存管理参数
uint32_t memtblsize ; // 内存表大小
uint32_t memblksize; // 内存分块大小
uint32_t memsize ; // 内存总大小
void *mutex;
}mallco_dev;
#define SRAM_USER_SIZE (64*1024)
#define MEM_BLOCK_SIZE (32)
#define MEM_MAX_SIZE (((SRAM_USER_SIZE))*MEM_BLOCK_SIZE/(MEM_BLOCK_SIZE+2))
#define MEM_ALLOC_TABLE_SIZE ((MEM_MAX_SIZE/MEM_BLOCK_SIZE)&(~3))
#define SRAM_USER_ADDR ((uint32_t)g_sram_mem)
//分配的内存都是双字对齐的
#define MEM_BASE ((uint8_t *)(SRAM_USER_ADDR+MEM_ALLOC_TABLE_SIZE*2))
#define MEMMAP_BASE ((uint16_t *)(SRAM_USER_ADDR))
static uint8_t g_sram_mem[SRAM_USER_SIZE];
//内存管理控制器
static mallco_dev g_self;
//内存管理初始化
void mem_init(void)
{
mallco_dev *self=&g_self;
if(self->memrdy) return;
self->memtblsize = MEM_ALLOC_TABLE_SIZE;
self->memblksize = MEM_BLOCK_SIZE;
self->memsize = MEM_MAX_SIZE;
self->membase=MEM_BASE;
self->memmap=MEMMAP_BASE;
memset(self->memmap, 0,self->memtblsize*2);
memset(self->membase, 0,self->memsize);
self->mutex=rt_mutex_create("mem",RT_IPC_FLAG_FIFO);
self->memrdy=1;
}
// 获取内存使用率
// 返回值:使用率(0~100)
int mem_perused(void)
{
mallco_dev *self=&g_self;
uint32_t used=0;
uint32_t i;
for(i=0;i<self->memtblsize;i++)
{
if(self->memmap[i])used++;
}
//return (used*100)/(self->memtblsize);
return used;
}
// 内存分配(内部调用)
// size:要分配的内存大小(字节)
// 返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
static uint32_t mem_malloc(uint32_t size)
{
mallco_dev *self=&g_self;
signed long offset=0;
uint16_t nmemb;
uint16_t cmemb=0;
uint32_t i;
uint32_t ret=0xffffffff;
if(size==0)return ret;
rt_mutex_take(self->mutex,RT_WAITING_FOREVER);
nmemb=size/self->memblksize;
if(size%self->memblksize)nmemb++;
for(offset=self->memtblsize-1;offset>=0;offset--)
{
if(!self->memmap[offset])cmemb++;
else cmemb=0;
if(cmemb==nmemb)
{
for(i=0;i<nmemb;i++)
{
self->memmap[offset+i]=nmemb;
}
ret= (offset*self->memblksize);
break;
}
}
rt_mutex_release(self->mutex);
return ret;
}
//释放内存(内部调用)
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
static int mem_free(uint32_t offset)
{
mallco_dev *self=&g_self;
int i;
int ret=1;
rt_mutex_take(self->mutex,RT_WAITING_FOREVER);
if(offset<self->memsize)
{
int index=offset/self->memblksize;
int nmemb=self->memmap[index];
for(i=0;i<nmemb;i++)
{
self->memmap[index+i]=0;
}
ret= 0;
}
rt_mutex_release(self->mutex);
return ret;
}
void *malloc(uint32_t size)
{
mallco_dev *self=&g_self;
uint32_t offset;
void *ret_addr=NULL;
offset=mem_malloc(size);
if (offset!=0XFFFFFFFF)
{
ret_addr=(void*)((uint32_t)self->membase+offset);
}
return ret_addr;
}
static void self_free(void *ptr)
{
mallco_dev *self=&g_self;
uint32_t offset;
if(ptr==NULL)
{
return;
}
else
{
offset=(uint32_t)ptr-(uint32_t)self->membase;
mem_free(offset);
}
}
void *calloc(size_t nmemb, size_t size)
{
void *p;
p=malloc(nmemb*size);
if(p) memset(p,0,size);
return p;
}
void *realloc(void *p,size_t size)
{
param_check(0);
return NULL;
}
#define MEM_TEMP_PTR_NUM 400
typedef void (*del_fun_def)(void *t);
typedef struct{
void *temp_ptr[MEM_TEMP_PTR_NUM];
void *del_ptr[MEM_TEMP_PTR_NUM];
int used;
uint32_t bitmap[(MEM_TEMP_PTR_NUM+31)/32];
void *mutex;
}temp_def;
static temp_def g_tempptr;
// 在位图中找到一个0/1
static int bitmap_find(uint32_t *bitmap,int num,int bit)
{
for(int i=0;i<num;i++)
{
if((bitmap[i/32]&(1<<(i%32)))==(bit<<(i%32)))
{
return i;
}
}
return -1;
}
// 设置位图中指定位
static void bitmap_set(uint32_t *bitmap,int index)
{
bitmap[index/32]|=1<<(index%32);
}
static void bitmap_clear(uint32_t *bitmap,int index)
{
bitmap[index/32]&=~(1<<(index%32));
}
static int bitmap_get(uint32_t *bitmap,int index)
{
return (bitmap[index/32]&(1<<(index%32)))==(1<<(index%32));
}
static void *tempptr_append(temp_def *t,void *p,void *del_fun)
{
if(p==NULL) return p;
void *ret=NULL;
if(del_fun==0) del_fun=self_free;
if(t->used<MEM_TEMP_PTR_NUM)
{
int index=bitmap_find(t->bitmap,MEM_TEMP_PTR_NUM,0);
param_check(index>=0);
t->temp_ptr[index]=p;
t->del_ptr[index]=del_fun;
bitmap_set(t->bitmap,index);
ret= p;
t->used++;
}
else{
param_check(0);
}
if(ret==NULL) ((del_fun_def)del_fun)(p);
return ret;
}
// 查询指针是否已存在
static int tempptr_find(temp_def *t,void *p)
{
int index;
for(int i=0;i<MEM_TEMP_PTR_NUM;i++)
{
if(bitmap_get(t->bitmap,i))
{
if(t->temp_ptr[i]==p)
{
return 1;
}
}
}
return 0;
}
static void tempptr_free(void)
{
int index;
void *p=NULL;
del_fun_def del=NULL;
temp_def *t=&g_tempptr;
rt_mutex_take(t->mutex,RT_WAITING_FOREVER);
if(index=bitmap_find(t->bitmap,MEM_TEMP_PTR_NUM,1),index>=0)
{
// DBG_LOG("%s:free tempptr",__func__);
p=t->temp_ptr[index];
t->temp_ptr[index]=0;
del=(del_fun_def)t->del_ptr[index];
bitmap_clear(t->bitmap,index);
t->used--;
}
rt_mutex_release(t->mutex);
if(del) del(p);
}
void tempptr_init(void)
{
temp_def *t=&g_tempptr;
t->mutex=rt_mutex_create("tempptr",RT_IPC_FLAG_FIFO);
rt_thread_idle_sethook(tempptr_free);
}
// 申请临时内存,在任务结束后自动释放
void *tmalloc(uint32_t size)
{
void *p;
temp_def *t=&g_tempptr;
p=malloc(size);
rt_mutex_take(t->mutex,RT_WAITING_FOREVER);
p=tempptr_append(&g_tempptr,p,NULL);
rt_mutex_release(t->mutex);
return p;
}
// 把指针添加为临时指针
void *tappend(void *p,void *del)
{
mallco_dev *self=&g_self;
temp_def *t=&g_tempptr;
void *ret=NULL;
rt_mutex_take(t->mutex,RT_WAITING_FOREVER);
if(((uint32_t)p>=(uint32_t)self->membase)&&
((uint32_t)p<(uint32_t)(self->membase+self->memsize)))
{
if(tempptr_find(t,p)==0)
{
ret= tempptr_append(t,p,del);
}
}
rt_mutex_release(t->mutex);
return ret;
}
// 释放内存,如果在临时表中则退出
void free(void *p)
{
if(p==NULL) return;
mallco_dev *self=&g_self;
temp_def *t=&g_tempptr;
int ret=0;
rt_mutex_take(t->mutex,RT_WAITING_FOREVER);
ret=tempptr_find(t,p);
rt_mutex_release(t->mutex);
if(ret){
return;
}else{
self_free(p);
}
}

27
source/soft/mystdlib.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef mystdlib_h__
#define mystdlib_h__
#include "stdint.h"
void mem_init(void);
int mem_perused(void);
void tempptr_init(void);
void *tmalloc(uint32_t size);
void *tappend(void *p,void *del);
#endif

344
source/soft/mystring.c Normal file
View File

@@ -0,0 +1,344 @@
#include "stdlib.h"
#include "mystdlib.h"
#include "mystring.h"
#include "bytearray.h"
#include "board.h"
#include "string.h"
/*
*
* 从左向右找到字符串s中首次出现字符c的指针,没找到返回0
* 例如 char *s=str_find_char_right("abcdef",'c')
* s="cdef"
*
*/
const char *str_find_char_right(const char *s,char c)
{
while(*s){
if(*s==c) return s;
s++;
}
return 0;
}
/*
*
* 从左向右找到字符串s中首次出现字符c的指针,没找到返回0,
* 指针p是向右检索的终点
* 例如 char *s=str_find_char_right("abcdef",'c')
* s="cdef"
*
*/
const char *str_find_char_right_p(const char *s, const char *const p, char c)
{
while (*s++)
{
if (*s == c) return s;
if (s >= p) break;
}
return 0;
}
/*
*
* 从右向左找到字符串s中首次出现字符c的指针,没找到返回0
* 指针p是向左检索的终点s检索开始
* char *t="abcdef";
* char *s;
* s=str_find_char_left(t,t+4,'b');
* s="bcdef"
*
*/
const char *str_find_char_left(const char *const p,const char *s,char c)
{
while(*s--)
{
if(*s==c) return s;
if(s<=p) break;
}
return 0;
}
/*
*
* 计算字符串 s 的长度
*
*/
int str_len(const char *s)
{
int len=0;
while(*s++) len++;
return len;
}
/*
*
* 把 s2 中的内容复制到 s1 中,长度为 n
*
*/
void str_memcpy(char *s1,const char *s2,int n)
{
while(n--)
*s1++=*s2++;
}
/*
*
* 把 s2 中第一个 c 字符前的字符复制到 s1 中,如果没找到则全部复制,返回复制的字符个数
*
*/
int str_cpystr(char *s1,const char *s2,char c)
{
int len;
const char *str=str_find_char_right((char *)s2,c);
if(str==0) len=str_len(s2);
else len=str-s2;
str_memcpy(s1,s2,len);
s1[len]=0;
return len;
}
/*
*
* 把整数字符串传化为int,直到遇到非数字字符
*
*/
static int str_ainttoi(const char *s)
{
int ret=0;
int sig=1;
if(*s=='-'){
s++;
sig=-1;
}
while(*s)
{
if(*s>='0'&&*s<='9')
{
ret*=10;
ret+=*s-'0';
}
else return ret;
s++;
}
return ret*sig;
}
int str_ahextoi(const char *s)
{
int ret=0;
while(*s)
{
if(*s>='0'&&*s<='9')
{
ret*=16;
ret+=*s-'0';
}
else if(*s>='a'&&*s<='f')
{
ret*=16;
ret+=*s-'a'+10;
}
else if(*s>='A'&&*s<='F')
{
ret*=16;
ret+=*s-'A'+10;
}
else return ret;
s++;
}
return ret;
}
int str_atoi(const char *s)
{
if(s[0]=='0'&&((s[1]=='x')||(s[1]=='X'))){
return str_ahextoi(&s[2]);
}else{
return str_ainttoi(s);
}
}
/*
*
* 把字符串以字符c分割为列表
*
*/
list_def *str_split(const char *s,char c)
{
int len=str_len(s)+1;
char *t=malloc(len);
char *ptr1,*ptr2;
list_def *l=list_creat_str();
str_memcpy(t,s,len);
ptr1=t;
ptr2=t;
while(*ptr1)
{
if(*ptr1==c){
*ptr1=0;
list_append_str(l,ptr2);
ptr2=ptr1+1;
}
ptr1++;
}
list_append_str(l,ptr2);
free(t);
return list_temp(l);
}
/*
*
* 把字符串转化为数字列表每个数字之间分隔符是c
*
*/
list_def *str_atod_list(const char *s, char c)
{
list_def *sl=str_split(s,c);
list_def *dl=list_creat_int();
for(int i=0;i<list_length(sl);i++)
{
int n;
char *d=list_get_str(sl,i);
n=str_atoi(d);
list_append_int(dl,n);
}
return tappend(dl,0);
}
/*
*
* 判断字符是否是空白字符,是返回1,不是返回0
*
*/
static inline int str_is_empty_char(char c)
{
const char table[]="\t\n\v\f\r ";
if(str_find_char_right(table,c)!=0)
return 1;
else
return 0;
}
/*
*
* 判断字符串是否是可打印,是返回1,不是返回0
*
*/
int str_is_print_str(const char *str,int len)
{
for(int i=0;i<len;i++)
{
// 既不是空白字符也不是可打印字符
if(!(str_is_empty_char(str[i])||(str[i]>=' '&&str[i]<='~')))
return 0;
}
return 1;
}
/*
*
* 去除字符串中多余的空白字符 '\t', '\n', '\v', '\f', '\r', and ' ',返回临时指针
*
*/
char *str_simplified(const char *str)
{
int is_empty=0;
array_def *arr=arr_creat();
param_check(arr);
while(str_is_empty_char(*str)){
str++;
}
while(*str){
if(str_is_empty_char(*str)==0){
if(is_empty==1){
arr_append(arr,' ');
is_empty=0;
}
arr_append(arr,*str);
}else{
is_empty=1;
}
str++;
}
char *ret=tmalloc(arr_length(arr)+1);
param_check(ret);
memcpy(ret,arr_data(arr),arr_length(arr));
ret[arr_length(arr)]=0;
arr_delete(arr);
return ret;
}
/*
*
* 给字符串指针设置值
*
*/
void _str_set(char **p,const char *str)
{
param_check(p);
int len=0;
if(str)
len=str_len(str);
else
len=0;
if(*p!=0)
{
free(*p);
}
*p=malloc(len+1);
str_cpystr(*p,str,len);
(*p)[len]=0;
}
/*
*
* 创建一个字符串副本
*
*/
char *str_duplicate(char *p)
{
int len=str_len(p);
char *s=malloc(len+1);
param_check(s);
str_cpystr(s,p,len+1);
return s;
}

50
source/soft/mystring.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef mystring_h__
#define mystring_h__
#include "list.h"
#ifdef __cplusplus
extern "C" {
#endif
const char *str_find_char_right(const char *s, char c);
const char *str_find_char_right_p(const char *s,const char *const p, char c);
const char *str_find_char_left(const char *const p,const char *s, char c);
int str_ahextoi(const char *s);
int str_atoi(const char *s);
int str_len(const char *s);
int str_cpystr(char *s1, const char *s2, char c);
list_def *str_split(const char *s,char c);/*temp_ptr*/
list_def *str_atod_list(const char *s, char c);/*temp_ptr*/
char *str_simplified(const char *str);/*temp_ptr*/
char *str_duplicate(char *p);
int str_is_print_str(const char *str,int len);
#define str_set(p,str) _str_set(&p,str)
#define str_temp(p) tappend(p,0)
void _str_set(char **p,const char *str);
#ifdef __cplusplus
}
#endif
#endif

296
source/soft/signal.c Normal file
View File

@@ -0,0 +1,296 @@
#include "signal.h"
#include "board.h"
#include "stdlib.h"
#include "stdio.h"
#include "debug.h"
typedef struct{
void *mutex;
signal_list *head;
}self_def;
static self_def g_self;
int signal_init(void)
{
self_def *s=&g_self;
if(s->mutex==0)
{
s->mutex=rt_mutex_create("signal_",RT_IPC_FLAG_FIFO);
}
return 0;
}
static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
{
for(int i=0;i<num_4byte;i++)
{
dst[i]=src[i];
}
}
#define SLOT_FUN_RUN(fun,param) \
((slot_fun_def)(fun))(param[0],param[1],param[2],\
param[3],param[4],param[5],param[6],param[7])
typedef void (*slot_fun_def)(uint32_t a,uint32_t b,uint32_t c,uint32_t d,uint32_t e,uint32_t f,uint32_t g,uint32_t h);
static void slot_run(void *t)
{
param_check(t);
slot_run_def *s=t;
int msg_size=sizeof(slot_msg_def)+sizeof(uint32_t)*8;
slot_msg_def *msg=calloc(1,msg_size);
while(s->run)
{
rt_mq_recv(s->mb,msg,msg_size,RT_WAITING_FOREVER);
SLOT_FUN_RUN(msg->fun,msg->param);
}
free(msg);
}
// 创建一个线程
sig_thread thread_creat(int pro)
{
static uint16_t count=0;
char name[20]={0};
slot_run_def *run=calloc(1,sizeof(slot_run_def));
run->run=1;
sprintf(name,"sig_mq#%d",count);
run->mb=rt_mq_create(name,(sizeof(slot_msg_def)+sizeof(uint32_t)*8),50,RT_IPC_FLAG_FIFO);
sprintf(name,"sig_t#%d",count);
rt_thread_t rt_t=rt_thread_create(name,slot_run,run,2048,pro,20);
rt_thread_startup(rt_t);
count++;
return run->mb;
}
void thread_delete(sig_thread t)
{
// 删除线程需要删除与此线程相关的所有信号槽
// 删除消息队列
param_check(0);
}
// 如果这个类的信号已注册
static signal_list *find(void *sig_obj,void *signal_)
{
self_def *s=&g_self;
signal_list *l=s->head;
while(l!=0)
{
if(l->signal_==signal_&&l->sig_obj==sig_obj)
return l;
l=l->next;
}
return 0;
}
int connect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot)
{
self_def *s=&g_self;
signal_def *sig;
sig=signal_find(signal_);
if(sig==0) return -1;
rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
slot_list *slo=calloc(1,sizeof(slot_list));
param_check(slo);
slo->fun=slot;
slo->mb=t;
slo->next=0;
slo->obj=slot_obj;
signal_list *sig_l=find(sig_obj,signal_);
if(sig_l==0){
sig_l=calloc(1,sizeof(signal_list));
param_check(sig_l);
sig_l->signal_=signal_;
sig_l->sig_obj=sig_obj;
sig_l->next=s->head;
s->head=sig_l;
}
slo->next=sig_l->head;
sig_l->head=slo;
//DBG_LOG("signal connect:%08x",slo);
rt_mutex_release(s->mutex);
return 0;
}
int disconnect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot)
{
self_def *s=&g_self;
signal_list *sig;
sig=find(sig_obj,signal_);
if(sig==0) return -1;
int ret=-1;
rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
slot_list *next=sig->head;
slot_list *prev=0;
while(next!=0)
{
if(next->fun==slot&&next->obj==slot_obj)
{
if(prev) prev->next=next->next;
else sig->head=next->next;
//DBG_LOG("signal disconnect:%08x",next);
free(next);
ret=0;
break;
}
prev=next;
next=next->next;
}
rt_mutex_release(s->mutex);
return ret;
}
// 消除与指定对象相关的所有信号槽连接
int disconnect_sig(void *sig_obj)
{
self_def *s=&g_self;
rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
signal_list *sig=s->head;
signal_list *prev_sig=0;
while(sig!=0)
{
if(sig->sig_obj==sig_obj)
{
slot_list *next=sig->head;
while(next!=0)
{
sig->head=next->next;
free(next);
next=sig->head;
}
if(prev_sig) prev_sig=sig->next;
else s->head=sig->next;
free(sig);
break;
}
prev_sig=sig;
sig=sig->next;
}
rt_mutex_release(s->mutex);
return 0;
}
// 消除与指定对象相关的所有信号槽连接
int disconnect_slot(void *slot_obj)
{
self_def *s=&g_self;
rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
signal_list *sig=s->head;
while(sig!=0)
{
slot_list *next=sig->head;
slot_list *prev=0;
while(next!=0)
{
if(next->obj==slot_obj)
{
if(prev) prev->next=next->next;
else sig->head=next->next;
free(next);
break;
}
prev=next;
next=next->next;
}
sig=sig->next;
}
rt_mutex_release(s->mutex);
return 0;
}
signal_def *signal_find(void *signal_)
{
extern const int signalstruct$$Base;
extern const int signalstruct$$Limit;
signal_def *start=(signal_def *)&signalstruct$$Base;
signal_def *end=(signal_def *)&signalstruct$$Limit;
for(signal_def *t=start;t<end;t++)
{
if(t->signal_==signal_)
{
return t;
}
}
return 0;
}
// 发送信号
int _signal_emit(void *sig_obj,void *signal_,uint32_t *param,int param_num)
{
self_def *s=&g_self;
signal_list *sig=find(sig_obj,signal_);
if(sig==0) return -1;
if(param_num>7) return -2;
int size=sizeof(slot_msg_def)+sizeof(uint32_t)*(8);
slot_msg_def *m=malloc(size);
rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
slot_list *h=sig->head;
m->param_num=param_num;
m->src=signal_;
while(h)
{
m->fun=h->fun;
if(h->obj)
{
cpy4byte(m->param+1,param,param_num);
m->param[0]=(uint32_t)h->obj;
}else{
cpy4byte(m->param,param,param_num);
}
if(h->mb){
rt_mq_send(h->mb,m,size);
}else{
SLOT_FUN_RUN(m->fun,m->param);
}
h=h->next;
}
rt_mutex_release(s->mutex);
free(m);
return 0;
}

96
source/soft/signal.h Normal file
View File

@@ -0,0 +1,96 @@
#ifndef signal_h__
#define signal_h__
#include "stdint.h"
#include "rtthread.h"
#include <rthw.h>
#include "string.h"
#define signal void
#define emit
typedef struct _slot_list{
struct _slot_list *next;
void *fun;
void *mb;
void *obj;
}slot_list;
typedef struct _signal_list{
struct _signal_list *next;
slot_list *head;
void *sig_obj;
void *signal_;
}signal_list;
typedef struct{
const char *name;
void *signal_;
// slot_list *head;
}signal_def;
typedef struct{
void *fun;
void *src;
int param_num;
uint32_t param[0];
}slot_msg_def;
typedef struct{
void *mb;
int run;
}slot_run_def;
typedef void * sig_thread;
#define signal_export(name_) \
const static char __sig_##name_##_name[] SECTION(".rodata.sigstr") = #name_; \
RT_USED static signal_def _signal_##name_ SECTION("signalstruct")= \
{\
.name=__sig_##name_##_name,\
.signal_=name_,\
};
sig_thread thread_creat(int pro);
void thread_delete(sig_thread t);
signal_def *signal_find(void *signal_);
int connect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot);
int disconnect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot);
int signal_init(void);
int disconnect_sig(void *sig_obj);
int disconnect_slot(void *slot_obj);
int _signal_emit(void *sig_obj,void *signal_,uint32_t *param,int param_num);
#endif

131
source/soft/sort.c Normal file
View File

@@ -0,0 +1,131 @@
#include "list.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "board.h"
#include "mystdlib.h"
// 计算对应节点序号
#define GET_FATHER_INDEX(index) (((index)-1)/2)
#define GET_LEFT_INDEX(index) ((((index)+1)*2)-1)
#define GET_RIGHT_INDEX(index) (((index)+1)*2)
//static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
//{
// for(int i=0;i<num_4byte;i++)
// {
// dst[i]=src[i];
// }
//}
// 数据下沉
// 输入:待排序列,要下沉的父节点序号,待排序列长度
static void heap_sink(list_def *l, sub_fun_def sub,int start,int size)
{
int left, right, index;
int temp_size=list_block_size4(l);
void *temp=malloc(temp_size);
void *l_left,*l_right,*l_i,*l_index;
param_check(temp);
for (int i = start; i < size;)
{
left = GET_LEFT_INDEX(i);
right = GET_RIGHT_INDEX(i);
l_left=list_get(l,left);
l_right=list_get(l,right);
if (right < size)
{
if(sub(l_left,l_right)>0)
{
cpy4byte(temp,l_left,temp_size/4);
index = left;
}
else
{
cpy4byte(temp,l_right,temp_size/4);
index = right;
}
}
else if (left < size)
{
cpy4byte(temp,l_left,temp_size/4);
index = left;
}
else
{
// 序号超出堆范围
break;
}
// 子节点比父节点小
l_i=list_get(l,i);
if(sub(temp,l_i)<=0)
break;
l_index=list_get(l,index);
//array[index] = array[i];
cpy4byte(l_index,l_i,temp_size/4);
//array[i] = temp;
cpy4byte(l_i,temp,temp_size/4);
i = index;
}
free(temp);
}
// 把序列初始化为大顶堆
static void heap_init(list_def *l, sub_fun_def sub,int size)
{
// 最后一层没有子节点,所以从倒数第二层开始
// 当然,从最后一层开始也不影响结果
for (int i = size/2; i > 0; i--)
{
heap_sink(l, sub,i - 1, size);
}
}
void _list_sort(list_def *l,sub_fun_def sub)
{
param_check(l);
param_check(sub);
int temp_size=list_block_size4(l);
void *temp=malloc(temp_size);
void *l_i,*l_0;
int size=list_length(l);
heap_init(l, sub,size);
//heap_print(array, size);
for (int i = size; i > 0; i--)
{
l_0=list_get(l,0);
l_i=list_get(l,i-1);
//temp = array[0];
cpy4byte(temp,l_0,temp_size/4);
//array[0] = array[i-1];
cpy4byte(l_0,l_i,temp_size/4);
//array[i - 1] = temp;
cpy4byte(l_i,temp,temp_size/4);
heap_sink(l,sub,0, i - 1);
}
free(temp);
}

0
source/soft/sort.h Normal file
View File