home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / f / forthmac / !Forthmacs / docs / html / arm_hardw < prev    next >
Encoding:
Text File  |  1997-05-01  |  16.0 KB  |  336 lines

  1. <!-- Forthmacs Formatter generated HTML V.2 output -->
  2. <html>
  3. <head>
  4. <title>Hardware Diagnostics in Forth</title>
  5. </head>
  6. <body>
  7. <h1>Hardware Diagnostics in Forth</h1>
  8. <hr>
  9. <p>
  10. <p>
  11. <h2>fine tools ...</h2>
  12. <p>
  13. Forth has been long used for large numbers of hardware projects, both commercial 
  14. and private.  RISC OS Forthmacs is exceptionally stable and needs only very few 
  15. resources on the computer.  
  16. <p>
  17. Here's how you can write Forth programs to diagnose your hardware.  The programs 
  18. can range from very simple things like reading a register to very complicated 
  19. things like performing communications protocols.  Each higher level of tests can 
  20. build on the lower levels.  At any time, you can interactively execute any part 
  21. of the test, without having to build a command interpreter into your program.  
  22. <p>
  23. This document describes how to do very simple things interactively.  It is also 
  24. possible to save your work in a file and to make sequences of tests run 
  25. automatically.  
  26. <p>
  27. <p>
  28. <h2>Warning</h2>
  29. <p>
  30. The examples in the rest of this document assume that you are running on a 
  31. stand-alone system, and that there really are I/O devices located at the 
  32. addresses mentioned.  If you are running RISC OS Forthmacs under RISC OS or 
  33. Unix, both won't allow you to access device registers, so the examples in this 
  34. paper will cause a core dump of the Forth process.  
  35. <p>
  36. In fact, most of these examples assume that you are trying to debug a board 
  37. whose registers begin at virtual address (hex) 3340000.  In RISC OS computers 
  38. this would be a Simple Exp.  card with fast access, this might not be right for 
  39. your system, so please pick an address for your system where you know there is 
  40. some device or memory.  
  41. <p>
  42. <p>
  43. <h2>Getting started</h2>
  44. <p>
  45. The way to get Forth running on your machine is system-dependent, so we won't go 
  46. into that topic here.  We assume that you have already figured out how to get 
  47. Forth going, and that it is prompting you with <em>ok</em> .  
  48. <p>
  49. <p>
  50. <h2>Poking at registers</h2>
  51. <p>
  52. The first hurdle to cross when debugging a new board is usually reading and 
  53. writing the device registers.  With most programming environments or monitors, 
  54. if the register doesn't work, you are stuck.  Not so with Forth.  Suppose that 
  55. you have a 32-bit register at address (hex) 3340000.  You can read it with: 
  56. <p><pre>    3340000  @  .</pre><p>
  57. <strong>@</strong> says to read a 32-bit word from the preceding address.  <strong>.</strong> 
  58. says to print the result.  <strong>@</strong> is pronounced "fetch".  In 
  59. general, the <strong>@</strong> symbol is pronounced <em>fetch</em> in Forth 
  60. terminology.  There must be one or more spaces separating symbols! 
  61. <p>
  62. Note: The Forth parser is really simple; it just grabs the next sequence of 
  63. non-blank characters (called a <em>word</em> in the jargon) from the terminal 
  64. and looks up that word in its internal dictionary.  If it finds the word, it 
  65. executes some associated code.  If it doesn't find the word, it tries to parse 
  66. the word as a number.  If that fails, it complains.  
  67. <p>
  68. Note: <strong>@</strong> accesses a 32-bit location, the address must be 
  69. long-aligned.  If your device is 8 bits wide, use <code><A href="_smal_BE#16C">c@</A></code> 
  70. in this and future examples; also use <code><A href="_smal_BB#169">c!</A></code> 
  71. instead of <strong>!</strong> .  
  72. <p>
  73. There is a problem with 16-bit registers in ARM based computers, ARM cpus don't 
  74. support word-wide 16-bit data access.  You can use W@ and W! but both 
  75. instructions use two byte-wide memory accesses, so this might not be what you 
  76. wanted.  Or you use 32-bit normal accesses and mask-off the other 
  77. <p>
  78. The most likely result of trying this exercise on a prototype peripheral board 
  79. is that the board won't respond to the cycle, so the CPU will get a bus error, 
  80. print a message, and abort back to Forth.  
  81. <p>
  82. On a working device, instead of getting an error, Forth will display the 
  83. contents of the register you accessed.  
  84. <p>
  85. <p>
  86. <h2>Scope Loops</h2>
  87. <p>
  88. No, you don't have to get out your assembly language reference manual and try to 
  89. figure out how to poke in a tiny loop.  Here's how to make a loop: 
  90. <p>
  91. <p><pre>
  92. 3340000 constant reg-addr
  93. : test   begin  reg-addr @    drop  key? until  ;
  94. </pre><p>
  95. <p>
  96. This creates a loop which will repeatedly read a register at location 3340000.  <code><A href="_smal_AF#155">begin</A></code> 
  97. ...  <code><A href="_smal_BS#23A">key?</A></code> <code><A href="_smal_BC#31A">until</A></code> 
  98. means to keep doing everything between the <code><A href="_smal_AF#155">begin</A></code> 
  99. and the <code><A href="_smal_BS#23A">key?</A></code> until a key is typed on the 
  100. keyboard.  The <code><A href="_smal_BG#1CE">drop</A></code> is needed to get rid 
  101. of the value that was read from the register, which is left on a stack.  That 
  102. stack would eventually overflow if not for the <code><A href="_smal_BG#1CE">drop</A>.</code> 
  103. The loop is called <strong>test</strong> , and it is a new command which you 
  104. have just created, you could have called it anything you wanted, instead of <strong>test</strong> 
  105. .  
  106. <p>
  107. Remember that there will be an address exception if the physical address hasn't 
  108. been accepted by the MMU.  Now you can try the loop.  
  109. <p><pre>  test</pre><p>
  110. <p>
  111. In general, the way to execute a Forth command is by typing its name.  
  112. <p>
  113. So now the machine is sitting there banging away at your register.  You can try 
  114. to find a scope that still has some probes attached and figure out why your 
  115. register isn't responding.  
  116. <p>
  117. It wasn't actually necessary to have given the loop a name.  You could have just 
  118. typed: 
  119. <p><pre>  begin  reg-addr @ drop  again</pre><p>
  120. <p>
  121. This is different from almost all Forth dialects, RISC OS Forthmacs knows about 
  122. temporary compilation and forgets about the compiled code afterwards.  
  123. <p>
  124. However, by giving the command a name, you save it away so you can use it later, 
  125. just by typing the name.  It's not saved on disk, just in memory, so if you 
  126. reboot, the new command will be lost.  It would be nice if you could save your 
  127. work on disk, but in a lot of stand-alone debugging cases there is no disk on 
  128. the machine.  To learn how you can save your work, read the "Creating 
  129. Stand-Alone Forths" chapter 
  130. <p>
  131. <p>
  132. <h2>Writing to registers</h2>
  133. <p>
  134. Now that you can read your register, no doubt you want to write to it too.  
  135. <p><pre>  1234 reg-addr !</pre><p>
  136. writes the 32-bit word 1234 (hex) to the address left by the word <strong>reg-addr</strong> 
  137. (which we defined earlier).  If you want to write a byte instead of a 32-bit 
  138. word, use <code><A href="_smal_BB#169">c!</A>.</code> 
  139. <p><pre>  reg-addr @ .</pre><p>
  140. reads back the register and prints the value, so you can verify that the write 
  141. actually worked.  
  142. <p>
  143. <p>
  144. <h2>Do Loops</h2>
  145. <p>
  146. An obvious thing to do now is to write a bunch of different values to the 
  147. register and see if they all work.  
  148. <p>
  149. <p><pre>
  150. : test-loop
  151.    ffff 0  do
  152.       i  reg-addr !     ( write a value to the register )
  153.       reg-addr @        ( read it back )  ( register value on stack )
  154.       i <>   ( see if the value read back is different from the one written )
  155.       if    ." Error - wrote "    i .    ." read "   reg-addr @ .  cr
  156.       then
  157.    loop ;
  158. </pre><p>
  159. <p>
  160. The indentation is optional.  If you were writing this test on-the-fly while 
  161. sitting in the lab, you would probably not bother with indentation.  Similarly, 
  162. everything inside parentheses is a comment and may be omitted.  When you are 
  163. writing Forth programs to save (presumably using a Unix editor), please don't 
  164. omit the comments or the indentation, because that would make your work hard to 
  165. understand later.  
  166. <p>
  167. How does this test-loop work? Let's go over it line-by-line.  <em>ffff 0</em> 
  168. are the arguments to the <code><A href="_smal_AP#1BF">do</A></code> ...  <code><A href="_smal_AW#256">loop</A></code> 
  169. construct.  The loop starts at 0 and ends when the loop index reaches (hex) 
  170. ffff.  The last time through the loop, the index has the value (hex) fffe.  The 
  171. firs thing inside the loop is <em>i reg-addr !</em> .  Previously we used the 
  172. literal number <em>1234</em> as the value to store into location reg-addr.  This 
  173. time we use the loop index <strong>i</strong> .  The loop index is <em>always</em> 
  174. called <strong>i</strong> .  If you use nested loops, the index of the next 
  175. outer loop is called <strong>j</strong> .  
  176. <p>
  177. The next thing we do inside the loop is read back the register.  Previously we 
  178. printed the value as soon as we read it; this time we will let the program look 
  179. at and decide if it's okay.  But where is the value kept? It's on the stack, 
  180. just like on an HP calculator.  In fact almost every operator in Forth takes its 
  181. operands from the stack and leaves its results on the same stack.  I will assume 
  182. that this concept is familiar to you; if it isn't, let me know and I will either 
  183. explain it to you or loan you a book which does so.  Anyway, the register value 
  184. is now sitting on the stack.  The next thing we do is compare that value to the 
  185. loop index <strong>i</strong> .  The operator <code><A href="_smal_BI#110"><></A></code> 
  186. (not-equal) compares the top two things on the stack and leaves true if they are 
  187. not equal or false if they are equal.  
  188. <p>
  189. If the numbers are equal, all is well.  If they are different, we need to print 
  190. an error message.  That is where the <code><A href="_smal_AW#226">if</A></code> 
  191. ...  <code><A href="_smal_BK#2F2">then</A></code> construct comes in.  Here is 
  192. the strange part: The stuff you want to do if the condition is true goes <code><A href="_smal_AH#157">between</A></code> 
  193. <code><A href="_smal_AW#226">if</A></code> and <code><A href="_smal_BK#2F2">then</A>,</code> 
  194. not after <code><A href="_smal_BK#2F2">then</A></code> as one would expect.  
  195. This is unfortunate, but it is not the end of the world.  The condition that is 
  196. tested comes BEFORE the <code><A href="_smal_AW#226">if</A>;</code> in this case 
  197. the condition is the true/false value left on the stack by the <code><A href="_smal_BI#110"><></A></code> 
  198. operator.  If this seems strange to you, consider that it is very simple, yet 
  199. completely general.  It is also possible to specify an <code><A href="_smal_BP#1D7">else</A></code> 
  200. clause (details later).  
  201. <p>
  202. The only thing remaining for this test-loop is to describe how the error message 
  203. is printed.  The construct <em>." ... "</em> , pronounced "dot-quote, prints 
  204. whatever is inside the quotes.  The first space after the first quote is 
  205. mandatory and is not printed.  Any subsequent spaces before the next quote are 
  206. part of the string and are printed.  Next we print the loop index with <strong>i .</strong> 
  207. .  As you have probably guessed, <strong>.</strong> just means print whatever 
  208. number is on the stack.  Next we print another string, followed by the value 
  209. read back from the register.  Finally, <code><A href="_smal_AV#195">cr</A></code> 
  210. prints a carriage-return and linefeed.  
  211. <p>
  212. <p>
  213. <h2>Extensibility</h2>
  214. <p>
  215. Earlier we saw how to make a word called <em>test</em> which could then be 
  216. executed by typing its name.  Once you have made a word, you can then use it as 
  217. part of another word, thus building on top of your previous work.  For example, 
  218. suppose that there is a dma address register on your board, and that its address 
  219. is (hex) 3340804.  You can define a word to store a value into that register as 
  220. follows: 
  221. <p><pre>  : dma!  3340804 !  ;</pre><p>
  222. This defines a new word called <strong>dma!</strong> which takes an argument and 
  223. stores it into the prescribed location.  This word can be used as: 
  224. <p><pre>  f00000 dma!</pre><p>
  225. which will store f00000 into the dma register.  Now, suppose that as part of a 
  226. test, you need to automatically set the dma register.  You can use your word 
  227. dma! as part of another word.  
  228. <p><pre>  : init-dma  f00000 dma!  ;</pre><p>
  229. This is a trivial example, but it serves to illustrate the style of building up 
  230. your application in small incremental steps.  Don't hesitate to build words 
  231. which only have a few components; the overhead of calling a word from one at 
  232. higher level is quite small, and the advantages of small words are many 
  233. (readability, ease of debugging, possibility of reuse).  
  234. <p>
  235. <p>
  236. <h2>Variables</h2>
  237. <p>
  238. Define a variable with 
  239. <p><pre>  variable foo</pre><p>
  240. The new variable <strong>foo</strong> has space for a 32-bit word.  Put a number 
  241. in the variable with: 
  242. <p><pre>  129876 foo !</pre><p>
  243. and get it back with 
  244. <p><pre>  foo @</pre><p>
  245. The number to be stored is taken from the stack, and the number fetched is left 
  246. on the stack.  When you typed the 129876, that number was actually left on the 
  247. stack, and <strong>foo !</strong> picked it up and put in the variable foo.  <strong>foo @</strong> 
  248. retrieved it from the variable and returned it to the stack.  
  249. <p>
  250. <p>
  251. <h2>Constants</h2>
  252. <p>
  253. A constant is a symbolic name for a number.  In other words, when you type the 
  254. name of a constant, it just leaves its number on the stack.  One way of making a 
  255. constant is the obvious: 
  256. <p><pre>  : mem-base  100000  ;</pre><p>
  257. Now the word mem-base is equivalent to the number 100000.  A slightly more 
  258. efficient form of this is: 
  259. <p><pre>  100000 constant mem-base</pre><p>
  260. A word defined with <code><A href="_smal_AP#18F">constant</A></code> will 
  261. execute somewhat faster than one defined the other way (but you would probably 
  262. never notice the difference).  
  263. <p>
  264. <p>
  265. <h2>C Language Analogies</h2>
  266. <p>
  267. <p><pre>
  268.         C                               Forth
  269. while( condition ) {                    BEGIN  condition  WHILE
  270.         loop-body                               loop-body
  271. }                                       REPEAT
  272. do {                                    BEGIN
  273.         loop-body                               loop-body
  274. until ( condition )                     condition  UNTIL
  275. for( i=start_value;                     end_value
  276.       i<end_value;                      start_value
  277.       i += increment ) {                DO
  278.         loop-body                               loop-body
  279. }                                       increment +LOOP
  280. for( i=start value;                     end value
  281.       i<end value;                      start value
  282.       i++ ) {                           DO
  283.         loop-body                               loop-body
  284. }                                       LOOP
  285. if ( condition ) {                      condition
  286.         true_clause                     IF      true_clause
  287. } else {                                ELSE    false_clause
  288.         false_clause                    THEN
  289. }
  290. if ( condition ) {                      condition
  291.         true_clause                     IF      true_clause
  292. }                                       THEN
  293. </pre><p>
  294. <p>
  295. Forth Notes: 
  296. <p>
  297. "condition" is any sequence of Forth words that has the effect of leaving a 
  298. number on the stack.  If the number the stack is 0, the condition value is 
  299. false, otherwise it is true.  
  300. <p>
  301. Within a do loop, the word <strong>i</strong> will put the loop index on the 
  302. stack.  
  303. <p>
  304. <p>
  305. <h2>One More Thing ...</h2>
  306. <p>
  307. You may want to do a scope loop which can be easily interrupted.  You can always 
  308. abort back to RISC OS Forthmacs with Shift-Ctrl-F12.  A nicer way, however, is 
  309. the following: 
  310. <p><pre>  : scope-loop   begin  1234 reg-addr !  key? until  ;</pre><p>
  311. This word will continuously write 1234 to location <em>reg-addr</em> until you 
  312. type any key.  The word <code><A href="_smal_BS#23A">key?</A></code> returns 
  313. true (which happens to be equal to -1) if a key has been depressed, and false 
  314. (0) if not.  
  315. <p>
  316. <p>
  317. <h2>Other Wonderful Features</h2>
  318. <p>
  319. Forth includes, among other things, a resident assembler, so you can write 
  320. little bits of assembly code if you need to.  It has a built-in visual line 
  321. editor, so you can edit command lines as you type them.  There are packages for 
  322. defining structures and bit fields, similar to C.  A built-in decompiler allows 
  323. you to interactively decompile any Forth word that you have previously defined.  
  324. Try typing <code><A href="_smal_BR#2C9">see</A></code> followed by the name of 
  325. any Forth command, or any Forth word you have already defined.  
  326. <p>
  327. <p>
  328. <h2>Line Editing</h2>
  329. <p>
  330. While you are typing a Forth command line, you can move around in the line and 
  331. edit it.  Have a look at the chapter <strong>Typing Forth Command Lines</strong> 
  332. .  
  333. <p>
  334. </body>
  335. </html>
  336.