|Description||This application note shows how string characters are stored in and accessed from memory. This application is intended for use in the Workshop 4 – Designer environment. The 4DGL code of the Designer project can be copied and pasted to an empty ViSi project and it will compile normally. The code can also be integrated to that of an existing ViSi project.|
|Supported Processor||PICASO, DIABLO16|
|Supported Environment||Designer, ViSi|
This application note shows how string characters are stored in and accessed from memory. This application is intended for use in the Workshop 4 – Designer environment. The 4DGL code of the Designer project can be copied and pasted to an empty ViSi project and it will compile normally. The code can also be integrated to that of an existing ViSi project.
This application note requires:
- Any of the following 4D Picaso display modules:
and other superseded modules which support the ViSi Genie environment
- The target module can also be a Diablo16 display
Visit www.4dsystems.com.au/products to see the latest display module products that use the Diablo16 processor. The display module used in this application note is the uLCD-32PTU, which is a Picaso display. This application note is applicable to Diablo16 display modules as well.
for non-gen4 displays(uLCD-xxx)
for gen4 displays (gen4-uLCD-xxx)
- micro-SD (µSD) memory card
- Workshop 4 IDE (installed according to the installation document)
- Any Arduino board with a UART serial port
- 4D Arduino Adaptor Shield (optional) or connecting wires
- Arduino IDE
When downloading an application note, a list of recommended application notes is shown. It is assumed that the user has read or has a working knowledge of the topics presented in these recommended application notes.
At the time of writing of this application note, there exists only one variable data type in 4DGL. This is the var data type, which is a 16-bit signed integer variable. Since it is 16-bit wide, the var variable is also a word. It is also possible to declare an array of var or word variables. Each element of a var variable array therefore is a 16-bit wide signed integer or a word.
There are no specific variable data types for character arrays and strings. In 4DGL, character arrays and strings are stored inside var variable arrays. Since a character is one-byte wide, each element of a var variable array can store two characters.
There are several ways of entering string data into a variable array, two of which are using the functions “to(…)” (in combination with the function “print(…)”) and “str_PutByte(…)”. Another one is direct assignment using word-aligned pointers.
Likewise, there are several ways of accessing string data stored inside a word array. One way is to treat the word array containing the string as it is – a collection of word elements. Another way is to treat it as a region in memory where a string is stored. The former requires the use of word-aligned pointers, while the latter requires the use of byte-aligned pointers and the string class functions.
This application note discusses and elaborates the concepts above through examples.
For instructions on how to launch Workshop 4, how to open a Designer project, and how to change the target display, kindly refer to the section “Setup Procedure” of the application note
For instructions on how to launch Workshop 4, how to open a ViSi project, and how to change the target display, kindly refer to the section “Setup Procedure” of the application note
For instructions on how to create a new Designer project, please refer to the section “Create a New Project” of the application note
For instructions on how to create a new ViSi project, please refer to the section “Create a New Project” of the application note
There are several ways of assigning a string to a word array. One way is to stream a literal string constant to the word array using the functions “to(outstream)” and “print(…)”. To store the string “HELLO WORLD” for instance, we write,
Note that we had to declare the word array “buffer” which has a size of 10. This means that there are 10 word elements in the array. Each word element can contain a pair of bytes. The total number of bytes that buffer can hold is 20. To know the number of bytes that a word array can hold, simply multiply the array size by two. To illustrate,
Character or byte capacity = array size X 2
The function “print(…)” then streams the characters of the literal string constant “HELLO WORLD” to the word array buffer. Note that “HELLO WORLD” will be automatically terminated with a NULL character.
Inside a word array element there are two bytes of available memory – one of which may be pertained to as the high byte and the other the low byte. To illustrate using the word array “buffer”,
When characters are streamed to a word array, the processor starts with the first element (buffer in this example). Inside the first element, the low byte is filled first before the high byte (little endian order). After filling both bytes of the first element, the processor proceeds to the second element (buffer in this example). This process is repeated until all of the characters are saved. The string is then terminated with a NULL character. To illustrate,
Below is a screenshot image of the project “stringsBasics1.4dg” attached to this application note.
Again we declare the word array buffer, which has a size of 10. The word variable n will be used for indexing into the word array.
The literal string constant “HELLO WORLD” is now streamed to buffer.
The while-wend loop eliminates the need for repetitive statements when printing the content of the elements of a word array.
The above will print the values of all elements of the word array buffer (from buffer to buffer). Each element value will be printed on a new line, and the contents will be printed as hexadecimal vales. The section “Run the Program” shows the output of the example code “stringsBasics1.4dg”.
One way of accessing a character of a string saved to a word array is to use a word-aligned pointer, such as that shown in line 16 of the code “stringsBasics1.4dg”.
Here buffer is actually a pointer that holds the starting address of the memory location of the actual word array, and n is the offset of the pointer into that array.
would print “4548”.
would print “4C4C”.
To print only the low-byte character, we use the number format specifier “[HEX2]” with the function “print(…)”. This limits the length of the printed value to two hexadecimal digits.
To print only the high-byte character, we perform a bit-shifting operation then print the result up to two hexadecimal digits only.
With each increment of n, the pointer offsets into the next word element of the array, hence the term “word-aligned”. To change the first character of the string from ‘H’ to ‘X’ using a word-aligned pointer, we could write,
Since we know that ‘H’ is stored in the low byte of buffer, we clear the low byte of buffer while at the same time preserving the high byte by ANDing buffer with 0xFF00. Then we set the value of the low byte while preserving the value of the high byte by ORring buffer with 0x00nn, where nn is the desired value.
To replace the space character with a ‘+’, we could write,
To replace the last character (‘D’) with ‘A’, we could write,
Here a literal constant word value is directly assigned to buffer. This shorthand method can be also be used when assigning a character to the high or low byte of a word element, provided of course that the other byte is known.
To print the new value of the string, we write,
The final value of the string should be “XELLO+WORLA”. Open the attached Designer project “stringsBasics1b.4dg” to see the complete code for this section (Accessing a Character in the String using Word-Aligned Pointers).
As you may have already observed in the previous section, accessing a character inside a string stored in a word array using a word-aligned pointer is not straightforward. Note also that there are no data types (as of the time of writing of this application note) specific for characters (or other one-byte wide variables), such that we had to deal with characters using word-aligned pointers. The string class functions in 4DGL allow us to handle strings in an easier (or the normal) way, as will be shown in the following discussions.
Assuming that the word array buffer now contains the string “HELLO WORLD”, we first need to declare a word variable ptr.
Then we assign to ptr the starting address of the string stored in the word array buffer by writing
The word variable ptr now points to the address of letter ‘H’, which is the first character of the string in the word array buffer. To access a character we can use str_GetByte(…), which is another 4DGL string class function. For instance, to print ‘H’ in hexadecimal, we write,
To print the character as it is we write,
Note the difference between the format specifiers.
To print the seventh character, we write,
Note that offsetting the pointer ptr by 6 advances it to the address of the seventh character. Offsetting ptr by 1 advances it to the address of the second character or byte, hence the term “byte-aligned”. Compare this to the “ordinary” word-aligned pointers of the previous section, which advance by increments of two bytes or one word when being offset by a certain value. Note that grouping of the characters of the string by pairs and performing masking and bit-shifting were not needed when accessing the characters. Lastly, note also that we didn’t have to worry about the little-endian order of storage of the string inside the word array buffer.
To put a character into a string, we use the function “str_PutByte(…)”. To replace the first character in buffer with ‘X’ for example, we write,
To replace the space character with ‘+’ we write,
To replace ‘D’ with ‘A’ we write,
To print the modified string, we could write
or, since we have a byte-aligned pointer, we could write,
The Designer project for this section (Accessing a Character in the String using Byte-Aligned Pointers) is “stringsBasics2.4dg”.
For instructions on how to save a Designer project, how to connect the target display to the PC, how to select the program destination, and how to compile and download a program, please refer to the section “Run the Program” of the application note
For instructions on how to save a ViSi project, how to connect the target display to the PC, how to select the program destination, and how to compile and download a program, please refer to the section “Run the Program” of the application note
The uLCD-32PTU and uLCD-35DT display modules are commonly used as examples, but the procedure is the same for other displays.
After compiling the code “stringsBasics1.4dg” and uploading the program to the display module, the output should look like as shown below.
After compiling the code “stringsBasics1b.4dg” and uploading the program to the display module, the output should look like as shown below.
After compiling the code “stringsBasics2.4dg” and uploading the program to the display module, the output should look like as shown below.