All the source programs appearing and explained in this article are recorded on the attached CD-ROM [TN].
In "PMC T-Shell Practical Methods of Application" in Vol. 82 of this magazine, we explained the method of employing C language as one application development technique using PMC T-Shell. In this issue, as a continuation of that, we will explain one more development technique--the technique of developing programs by making MicroScript and C language cooperate.
Concerning MicroScript
MicroScript is a language processing environment that is loaded as standard equipment on PMC T-Shell. With it, there is the advantage of being able to easily develop applications that possess a GUI.
In the previous issue, we explained a program that realizes simple GUI parts using C language, but inside that, it was necessary to use system calls provided by PMC T-Shell and PMC T-Kernel Extension, and knowledge of those was required.
On the other hand, with MicroScript, we arrange figure elements (things such as polygons and images, which we call segments) inside the screen, and we can easily describe programs that carry out processing by receiving actions (press operations, etc.) from the user vis-à-vis those figure elements. For example, if we implement in MicroScript the program we took last in the previous issue, it becomes as in List 1 (actually, outside of this, preparation of a little additional code and some figure elements (segments) by means of the figure editor will become necessary).
In comparison to the method based on C language, in which various initial settings and the like were necessary, the program we ought to describe has become remarkably small, and even calling up the APIs of PMC T-Shell and PMC T-Kernel Extension is unnecessary.
Moreover, in the method based on C language, applications had to receive and process events that had occurred. On the other hand, in MicroScript, we can pair together segments and actions toward them (operations such as press, click, and double click) and define subroutines. And then, we describe inside those subroutines processing for when events that satisfy those conditions have occurred.
For example, we write
ACTION subroutine name (parameters . . . ) PRESS MS_EXIT
as the definition of a subroutine that runs when the segment called MS_EXIT is pressed. This means that control moves to this subroutine if the MS_EXIT segment is pressed.
In this manner, in MicroScript, it has become easy to implement event driven applications [1]. Moreover, the syntax itself possesses the atmosphere of BASIC or LOGO, and learning it is also easy.
The Reason for Making C Language and MicroScript Cooperate
As we explained in the previous issue, there are respective merits and demerits to development based on C language and development based on MicroScript. Therefore, let's try thinking, in particular, from the side of developing an application that possesses a GUI.
As for the merit of utilizing MicroScript, we can arrange various figure elements on the screen and easily write the processes that respond interactively to the operations of the user toward these. As mentioned above, the event processing events that the operating system possesses have nicely been made abstract, and there are also no cases in which one is bothered with the description of complex event processing or drawing processing. One can develop by concentrating on the original processing necessary to the application.
Moreover, because MicroScript has adopted an execution method based on an interpreter format, efficient development is possible even in cases in which the correction and execution phases are frequently repeated. In applications that possess a GUI, in particular in screen development where trial and error cannot be avoided, this point is a great merit of MicroScript.
On the other hand, there are also aspects at which MicroScript is weak. It cannot freely draw arbitrary figures and characters at arbitrary places inside a screen. Additionally, there are also limits to freely opening and closing windows and accessing files. Furthermore, one can mention that conversion into intermediate code is carried out, and thus if we compare it to execution in native code, there are cases where consideration toward efficiency falling is necessary.
Continuing on, let's try considering the merits of utilizing C language. It becomes an inside-out relationship with the case of MicroScript. In other words, you directly use the functions of PMC T-Shell and PMC T-Kernel Extension, and thus on the other hand of being able to freely control screen drawing, window management, and file access, sufficient knowledge of PMC T-Shell and PMC T-Kernel Extension become necessary.
As we have mentioned above, development based on C language and MicroScript have their respective merits. Accordingly, in PMC T-Shell, by using in parallel and making both C language and MicroScript programs cooperate in a manner that makes use of the merits of both, it has come about that we can configure them as one application.
In other words, dividing according to use in which for the GUI (design) parts, where an overall framework and trial and error are necessary, we utilize MicroScript, and for the finely detailed control that cannot be realized with that we use C language, becomes possible.
In the subsection below, we will go on to explain the techniques of cooperation between C language and MicroScript while changing examples.
Methods of Cooperation between C Language and MicroScript
As we explained in the previous issue also, in carrying out cooperation between programs based on MicroScript and C language, several techniques are conceivable. In this article, among those, we will explain a method in which we employ cooperation by using an inter-process message between MicroScript and a process base application described by means of C language.
In handling inter-process messaging in a C language program, we mainly use b_snd_msg(), b_rcv_msg(), and b_clr_msg, which are provided in T-Kernel Extension (please refer to the PMC T-Kernel Extension manual for the respective full details). Also, on the MicroScript side, we use the PROCESS statement, the MSEND statement, and the MRECV statement.
With cooperation between C language and MicroScript, we move the processing forward according to the following plan.
|
Execute the program based on MicroScript |
|
Execute the program based on C language that you want to cooperate by means of the PROCESS statement from MicroScript (or, execute beforehand and put in place the program based on C language that you want to cooperate) |
|
Send out a request to the program based on C language from MicroScript |
|
|
|
|
|
|
|
From the program based on C language, we respond to MicroScript |
|
|
|
|
|
In this manner, at the point in time processing that is difficult to realize in MicroScript has become necessary, transmitting a message vis-à-vis a program based on C language that is cooperating is the basic plan. By replying to MicroScript with the results that were processed in the program based on C language, we can realize processing by mutually cooperating [2].
Well then, from the next section, while giving examples in concrete terms we will proceed with an explanation of what kind of implementation we actually make.
Messages in PMC T-Kernel are things for communicating among particular processes. The message queue is attached to a process. Moreover, we do not make a mailbox in the manner of T-Kernel or ITRON, rather at the necessary time we directly send a message by means of b_snd_msg(), and we directly receive a message with b_rcv_msg() [3].
An inter-process message is not a simple byte string, rather it must be contents in accordance with a message structure. Moreover, inter-process messages are not things that are used only among applications that the user has created, rather they are frequently used (in the dark) also in order for the system to proceed with processing. For that reason, messages are classified for each use into 31 types, and the ones that can be freely used among the applications the user has created are limited to eight types among the 31 types.
Sending and Receiving of Messages among C Language-Based Processes
First, to begin with, we will give examples in which we send and receive messages among processes described by means of C language. In the sending and receiving of inter-process messages, we mainly use the following APIs defined in PMC T-Kernel Extension.
- b_snd_msg()
Transmission of message
- b_rcv_msg()
Reception of message
- b_clr_msg()
Clearing of message
b_snd_msg() transmits a message vis-à-vis a particular process, and b_rcv_msg() receives the message that was transmitted. b_clr_msg() deletes messages that have collected in the message queue of the process.
We show in List 2 (prog_1-main.c) an example in which we receive a message. Moreover, we show in List 3 (prog_2-main.c) an example in which we transmit a message.
There is a program execution sequence, so please execute first without fail prog_1. When you begin execution with prog_1, you immediately enter into wait for reception of a message based on b_rcv_msg(). Next, when you execute prog_2, you transmit a message vis-à-vis prog_1 of a moment ago [4], and then you terminate as is. prog_1 receives the message sent from prog_2, displays the received contents as a debugging message, and then terminates.
By doing things in this manner, we can carry out synchronous processing by using inter-process messaging between two different processes.
Sending and Receiving of Messages among C Language-Based Programs and MicroScript
Continuing on, we will give an example in which we carry out interchange using inter-process messaging between a process described by means of C language and an application based on MicroScript.
In using inter-process messages in MicroScript, we employ the following instructions.
- MSEND
Transmission of an inter-process message
- MRECV
Reception of an inter-process message
The MSEND statement, if we talk about it in terms of the method based on C language of a moment ago, corresponds to b_snd_msg(), and the MRECV statement corresponds to b_rcv_msg().
In a case where we use inter-process messages in MicroScript, the messages that can utilized are limited to eight types. What we call these eight types are the same message types we can freely use in applications that were previously mentioned. To put this another way, it comes down to saying that in MicroScript, messages of the type that the system uses in the dark cannot be handled (both reception and transmission of them are impossible).
Moreover, in a case where we use inter-process messages in MicroScript, in the process based on C language that does the receiving, a message with the following structure must be interpreted as the thing that was transmitted.
typedef struct { W msg_type; /* Message type */ W msg_size; /* Message size */ W ext_size; UB msg_body[1]; /* Actually, variable length */ } MSCRIPT_MSG;
Compared to the MESSAGE structure, attention is necessary to the fact that the item called ext_size has been added before msg_body (furthermore, in PMC T-Shell, 0 is always stored in this value). Moreover, msg_size becomes a value to which this ext_size part is added.
In List 4 (prog_3-main.c), we show the C language-based program that receives the message with b_rcv_msg(), and in List 5 (prog_m2), we show the MicroScript that transmits
In this example also, it is necessary to by all means execute and put in place beforehand prog_3. When we execute prog_m1 on the MicroScript side, it immediately transmits a message vis-à-vis prog_3, and then terminates as is. prog_3 that has received the message makes the debug output of the received contents and terminates.
In up to the previous section, we have explained the basics of cooperation between MicroScript and C language. From this section, we shall give slightly more complicated application examples.
As we mentioned in the beginning, MicroScript is not very good at a drawing straight lines and curved lines at arbitrary spots on the screen. On the other hand, preparing and putting into place beforehand figures/images called buttons and switches, and making the system display figures decided upon as GUI parts and acquiring user actions to them can be accomplished easily [5].
Accordingly, let's try test manufacturing an application (the source program is recorded in this issue's attached CD-ROM) of the type in which we decide to implement only the GUI in MicroScript, and then, when screen drawing has become necessary, we send out a request to a C language process using an inter-process message and make it do the screen drawing there.
|
|
When we start up this application, the screen in Fig. 1 appears. Here, when we type characters from the keyboard, the characters are input in the text box portion. The four button that are at the top edge are things for selecting the contents we wish to draw. The selector in the middle part is something for selecting color. Select the color you like from the eight colors. The lower half of the screen is the part for displaying the contents drawn by the C language-based program.
After clicking either "Straight Line," "Rectangular Frame," or "Circle/Ellipse," click two appropriate locations in the region of the lower half of the screen. By means of these operations, you specify the start point and the end point. For example, after clicking the "Straight Line" button, respectively click appropriate locations (upper left part and lower right part, etc.). When you do that, a straight line connecting the clicked parts will be drawn on the screen in the selected color.
|
|
If it's a rectangular frame, the application draws a square in which the start point and the end point are made the outermost points; and, if it's a circle/ellipse, the application draws a circle (ellipse) inscribed in a frame in which the start point and the end point are made the outermost points. After a click on "Character String," click just one time in the region in the lower part of the screen. When you do that, you make the point clicked the upper left start point, and you draw the character string that has been input in the text box (Fig. 2).
Configuration and Message Contents
In order to create this application, we make it so that we force a division of roles between MicroScript and C language in the following manner.
MicroScript Side [prog_m3] |
|
C Language Side [prog_4] |
|
Inter-process messaging is done with the following content |
|
Contents of the Process Based on C Language
First, we will briefly explain the contents from the C language-based process that serves as the child process.
At the point in time the process has started up, it immediately stores the process ID of the self process in the global name [prog_4]. This is something for the purpose of making it so that we can give and receive messages from the MicroScript script we wish to cooperate with. This is the same thing we carried out between prog_3 (the C language-based process) and prog_m2 (MicroScript script) in the previous section [10].
If the process has succeed in the basic initialization, the process enters a loop in which it continuously issues b_rcv_msg(). In this C language-based process, as long as a message that matches a request is not transmitted in, processing is not carried out, and the process continues to wait until it receives a message.
After receiving a message, the process searches for contents that match the header. This is for the purpose of making it so that there will not be any malfunction even if a message with unrelated contents is transmitted in the same message type. We take the four-byte region immediately after the message length (msg_size and ext_size), and we load the character string "SMPL" there as an identifier. If the character string "SMPL" exists in the identifier of a received message, the process makes the judgment that the received contents are certainly something that has been sent in from a cooperating opposite address. Furthermore, at this point in time, the process has not acquired the overall message. We make it so that the actual acquiring is done after doing a confirmation of these headers. Moreover, deletion of the message also has not yet been carried out (in b_rcv_msg(), we specify NOCLR).
Once we have confirmed the header and judged it as a message that it is all right to receive, next we receive the message in its entirety. If we receive the entirety, because it is not necessary for the message to be left at the top of a queue, we delete the message by specifying CLR in b_rcv_msg().
Last, from the number of the request contents that is described in the header portion of the contents, the process judges the contents to be processed, and then executes the respective processing.
During each processing, at the point in time the process has finished the processing from start to end, it sends a message in return to the transmission source of the request. In this example, we have made it so that it only returns with an error code whether or not a error has occurred during processing, but, if necessary, it is also possible to embed arbitrary binary data inside the message and reply.
When the message transmission corresponding to the reply is completed, the process once again returns to the previous wait for reception of message loop, and then enters into waiting until receiving a message corresponding to a request.
Furthermore, in this program, we have used the following APIs in order to find out the window that possesses the request transmission source process plus that window's drawing environment (window management APIs inside PMC T-Shell).
- b_wlst_wnd()
Window list up
- b_wget_gid()
Retrieve window drawing environment ID
b_wlst_wnd() is normally used in retrieving a window ID list that corresponds to a list of the windows that are open. However, as a special function, it possesses a function through which a specific process acquires a list of windows that are opened. Here, utilizing that function, we are making it so that we find out the window ID of the opposite window that is opened and acquire the drawing environment ID from that window ID.
We are doing something that is a little confusing, but this is because MicroScript cannot find out the window ID of its own window that is opened. On the cooperating C language process side, we are making it so that we guess the window ID of the window that is opened in the MicroScript opposite and retrieving the drawing environment ID from that.
Also, we have made it so that we have a general-purpose memory drawing environment as the work region. As to why, this is because we cannot make all the resources common, since the C language-based process and the MicroScript script at the cooperation address are different processes. For that reason, on the side of the C language-based process, we prepare a general-purpose memory drawing environment in order to preserve the contents corresponding to the screen display contents, and through appropriate timing we copy and display those in the MicroScript script window at the cooperation address.
However, because this C language-based process does not do anything other than a passive operation, we have made it so that redrawing timing is measured on the MicroScript side. In other words, on the MicroScript side, at appropriate points in time, we are transmitting a request corresponding to redrawing to the C language-based process, and the new contents are displayed on the screen.
Contents of the MicroScript Side
On the MicroScript side, we have mainly implemented only parts that correspond to the GUI. On top of the window, button types for selecting the contents you wish to draw, selectors for use in specifying the color, and an area for showing frames corresponding to a work region are arranged [11].
Concerning the respective segments, when we do pointer operations such as strike the touch panel, we execute the respective corresponding event. Because generated events are sent vis-à-vis segments, we go on to implement processing in regard to operations such as pointer presses and clicks for each segment. In concrete terms, we utilize the ACTION statement as shown at the beginning of prog_m1.
As a part outside of the GUI, there is also a part that moves processing forward by giving and receiving messages with a C language-based process at a cooperation address. In this example, the process at the cooperation address is the C language-based application called prog_4; in order to exchange messages with this process, it is necessary to find out the process ID of the opposite. In this case, as we explained previously, because the opposite's process ID is stored in the global name called [prog_4], we can acquire those contents by means of getgnm(). Furthermore, in a case where this global name doesn't exist, the program judges it as an error and the transmission and reception of messages is not carried out (we have made it so that it terminates MicroScript itself in a case where the program has judged an error at the point in time of initialization processing during startup).
When transmitting a message, caution concerning data strings is necessary. The opposite process we wish to cooperate with is described in C language, and the contents that will be given and received are defined with structures. However, MicroScript cannot handle the structures in C language. Therefore, it comes down to describing the contents as arbitrary strings. For this reason, the messages we exchange use type B arrays.
When transmitting a message, we secure a region that can only store the contents we will transmit, and we write in order there the contents in accord with the contents we would like to transmit (we make into byte strings and store the contents that correspond to W type, H type, and TC type character strings). Moreover, in this example, because we have implemented on the premise of little endian for the CPU endian, correction is necessary in a case where we are using a big endian CPU.
When we transmit a message to an opposite we would like to cooperate with, continuing on, we wait for a reply from the opposite. When the reply is received, in the same manner as the case of the previous C language-based process, we confirm the contents corresponding to the header. If it is judged that it has been received from the assumed opposite, we make it so that the program further interprets the received contents. In this example, because we have made it so that only an error code comes back in reply as the result for the requested contents, we do a read-in of the error code.
In this manner, we make it so that we proceed with processing while maintaining cooperation by transmitting to an opposite messages corresponding to requests, and receiving from the opposite messages corresponding to the results of those requests.
Method of Using the Cooperation Example
We will now explain the method of using the sample program that we took up here last.
First, in the beginning, we start up and put in place prog_4, which will become the child process. Because MicroScript prog_m3 that will become the parent process is made so that it proceeds with processing on the premise that prog_4 has completed startup, please be careful [12]. If the program succeeds at startup, prog_4 displays a self process ID as a debug message, and then enters as is into a message reception wait loop.
Next, the program starts up MicroScript prog_m3 that will become the parent process. Immediately after startup, the parent process transmits a request corresponding to start communications and initialization vis-à-vis child process prog_4. At this time, if prog_4 hadn't been started up and initialization had failed, MicroScript prog_m3 would regard it as an error having occurred, and it would terminate as is.
Moreover, among the request contents received in child process prog_4, we output a portion of the contents as a debug message. We can confirm with the debug message what type of requests have been received and the processing that is being done. When an error occurs, because we output those contents in a debug message, we can also find out its cause.
If the program succeeds in initialization, it enters into a so-called event loop on the MicroScript side, and it displays the window in Fig. 1.
Describing only in C language the GUI application taken up last is, of course, also possible. In this case, one must go on to implement one by one the basic things in the development of a GUI, such as opening windows, arranging parts such as buttons, and processing corresponding to the execution of the respective parts. Accordingly, even if we are just simply specifying two appropriate points on the screen and drawing a line, knowledge of such concerning PMC T-Kernel Extension and PMC T-Shell is necessary.
On the other hand, if we use MicroScript, the labor in implementation is greatly reduced, because MicroScript processes for us the GUI, where there is a lot of effort and trouble in that type of implementation.
In this article, we have explained a concrete example of GUI application development using PMC T-Shell. In the program we took up last, we developed the drawing portion in C language, and then we adopted the form of calling that up from MicroScript. Because the overall framework of the application is realized in MicroScript, making improvements while repeating through trial and error the user interface and design can be carried out efficiently.
MicroScript can be easily learned if you have acquired knowledge of one general programming language or another. It also has become easy to adopt a division of labor system in which multiple persons in charge are matched to each's field of charge and technical skill.
Through this article, we believe that you have understood that efficient development, in which by using PMC T-Shell's MicroScript and C language in parallel and making use of the respective merits, can proceed. We would be happy if the reader feels the possibilities of T-Engine by making full use of the functions of PMC T-Shell.
____________________
List 1 prog_m1 (parts execution example based on MicroScript) |
# # - prog_m1 - # # (C) Copyright 2003 by Personal Media Corporation. # VERSION 3 # # Press processing vis-à-vis MS_EXIT # ACTION PD_PRESS(seg:S, idx:I, x:I, y:I) PRESS MS_EXIT LOCAL flg:B # == 0 : outside range != 0 : inside range flg = 0 # Overlapping the picture inside press MOVE MS_FRAM_P:seg.X, seg.Y, @ # Event loop while pressing MS_EXIT REPEAT IF (($PDX > seg.X) && ($PDX < seg.X + seg.W) && \ ($PDY > seg.Y) && ($PDY < seg.Y + seg.H)) # Inside parts region IF (flg == 0) flg = 1 APPEAR MS_FRAM_P ENDIF ELSE # Outside parts region flg = 0 DISAPPEAR MS_FRAM_P ENDIF IF ($PDB == 0) # Released the PD DISAPPEAR MS_FRAM_P BREAK ENDIF ENDREPEAT DISAPPEAR MS_FRAM_P # MS_EXIT was clicked IF (flg != 0) FINISH ENDIF END # # Start of program # PROLOGUE FULLWIND APPEAR MS_EXIT END |
List 2 prog_1-main.c (reception side: receives message from prog_2-main.c) |
/* * prog_1-main.c (T-Shell Sample/Main) * * (C) Copyright 2003 by Personal Media Corporation. */ #include <basic.h> #include <btron/outer.h> #include <tcode.h> #include <stdio.h> #include <stdlib.h> /* Internal variables */ LOCAL TC PROG_1_NM[8] = { /* [prog_1] */ TK_p, TK_r, TK_o, TK_g, TK_USCR, TK_1, TNULL }; /* ---------------------------------------------------- main(cli style main) */ /* * main(cli style main) */ EXPORT W main(W ac, TC *av[]) { W rv; W l; W pid; /* Self process ID */ W mpid; /* Process ID of message transmission source */ W msize; /* Message size (byte units) */ MESSAGE dmy; /* Message temporary reception use */ MESSAGE *msg; /* Received message */ rv = 0; msg = NULL; /* Acquisition of self process ID */ pid = b_prc_sts(0, NULL, NULL); if (pid < ER_OK) { rv = pid; printf("b_prc_sts : %d, %d\n", rv, rv >> 16); goto EXIT; } /* Create global name and store self process ID */ rv = b_cre_nam(PROG_1_NM, pid, N_FORCE | DELEXIT); if (rv < ER_OK) { printf("b_cre_nam : %d, %d\n", rv, rv >> 16); goto EXIT; } /* Message reception wait */ for ( ; ; ) { /* Free previous reception region */ if (msg != NULL) { free(msg); msg = NULL; } /* Message temporary reception */ mpid = b_rcv_msg(MM_TYPE7, &dmy, sizeof(MESSAGE), WAIT|NOCLR); if ((mpid < ER_OK) && (mpid != ER_PAR)) { /* Error occurred (ER_PAR ignore) */ rv = mpid; printf("b_rcv_msg(dummy) : %d, %d\n", rv, rv >> 16); break; } /* Reject if not an application message 7 */ if (dmy.msg_type != MS_TYPE7) { /* Not needed, so discard */ b_clr_msg(MM_ALL, MM_ALL); continue; } /* Secure reception region */ msize = dmy.msg_size + sizeof(W) * 2; msg = (MESSAGE *)(malloc(msize)); if (msg == NULL) { rv = ER_NOMEM; printf("memory allocation error.\n"); break; } /* Reception */ rv = b_rcv_msg(MM_TYPE7, msg, msize, NOWAIT | CLR); if (rv < ER_OK) { /* Error occurred */ printf("b_rcv_msg(main) : %d, %d\n", rv, rv >> 16); break; } else if (rv != mpid) { /* Process of transmission source different (no normal startup) */ printf("not match process ID\n"); ; /* Return to loop */ } else { /* Show the received contents and terminate */ printf("sender PID : %d\n", mpid); printf("all message size : %d\n", msize); printf("MESSAGE.msg_type : 0x%08x\n", msg->msg_type); printf("MESSAGE.msg_size : 0x%08x\n", msg->msg_size); printf("MESSAGE.msg_body :\n"); for (l = 0; l < msg->msg_size; l++) { printf("%02x ", msg->msg_body.ANYMSG.msg_str[l]); } printf("\n"); break; } } EXIT: if (msg != NULL) { free(msg); } b_ext_prc(rv); return rv; } -------------------- # # @(#)Makefile (prog_1) # For use with GNU make # # make method # make # Create release use regular version # make mode=debug # Create for use in debugging # make clean # Delete all files created with make # make install # Install in prescribed place (for actual machine use only) # # Version version = 0x1000 # Set release use to default #mode = # Source dependencies-related file (automatically created) DEPS = Dependencies DEPENDENCIES_OUTPUT := $(DEPS) # Application standard rules include $(BD)/bappl/etc/makerules # ---------------------------------------------------------------------------- # Create target TARGET = prog_1 # Search path of source file S = ./ ../src VPATH = $(S) # Header file directory addition HEADER := $(S) $(HEADER) # Source file SRC = main.c OBJ = $(addsuffix .o, $(basename $(SRC))) WC_SRC = $(filter %.C, $(SRC)) DBFLAGS += -l ifeq ($(mode), debug) CFLAGS += -Wall endif # ---------------------------------------------------------------------------- .PHONY: all clean INST = $(addprefix $(TARGET), .bz .map) INST2 = $(addprefix $(TARGET), .out) all: $(INST) $(TARGET).out: $(OBJ) $(LINK.o) $(LDOBJS) $^ $(LOADLIBES) $(LDLIBS) $(OUTPUT_OPTION) clean: $(RM) $(OBJ) $(RM) $(WC_SRC:%.C=%.c) $(DBSRC) $(RM) $(INST) $(INST2) *.lst $(DEPS) # Compression archive $(TARGET).bz: $(INST2) $(CP) $(TARGET).out _t $(STRIP) _t $(MKBTF) -o$@ -a0x8003 -c -tprog_1 \ 9.$(CPU_TYPE)._t $(RM) _t # Source dependencies related $(WC_SRC:%.C=%.c): ifdef DEPENDENCIES_OUTPUT $(DEPS): ; touch $(DEPS) else $(DEPS): $(SRC) ; $(MAKEDEPS) $@ $? endif include $(DEPS) |
List 3 prog_2-main.c (transmission side: transmits message to prog_1-main.c) |
/* * prog_2-main.c (T-Shell Sample/Main) * * (C) Copyright 2003 by Personal Media Corporation. */ #include <basic.h> #include <btron/outer.h> #include <tcode.h> #include <stdio.h> /* Internal type declarations */ typedef struct { W msg_type; /* Same as MESSAGE.msg_type */ W msg_size; /* Same as MESSAGE.msg_size */ W data; /* Suitable contents */ } MSG_SAMPLE; /* Internal variables */ LOCAL TC PROG_1_NM[8] = { /* [QP] */ TK_p, TK_r, TK_o, TK_g, TK_USCR, TK_1, TNULL }; /* --------------------------------------------------- Main(cli style main) */ /* * main(cli style main) */ EXPORT W main(W ac, TC *av[]) { W rv; W spid; MSG_SAMPLE msg; rv = 0; /* Acquisition of the transmission target process ID */ rv = b_get_nam(PROG_1_NM, &spid); if (rv < ER_OK) { printf("b_get_nam : %d, %d\n", rv, rv >> 16); } else { /* Prepare contents to be transmitted */ msg.msg_type = MS_TYPE7; msg.msg_size = sizeof(MSG_SAMPLE) - offsetof(MSG_SAMPLE, data); msg.data = 0x12345678; /* Suitable contents */ /* Transmit message */ rv = b_snd_msg(spid, (MESSAGE *)(&msg), NOWAIT); if (rv < ER_OK) { printf("b_snd_msg : %d, %d\n", rv, rv >> 16); } } b_ext_prc(rv); return rv; } -------------------- # # @(#)Makefile (prog_2) # For use with GNU make # # make method # make # Create release use regular version # make mode=debug # Create for use in debugging # make clean # Delete all files created with make # make install # Install in the prescribed place (for actual machine use only) # # Version version = 0x1000 # Set release use to default #mode = # Source dependencies-related file (automatically created) DEPS = Dependencies DEPENDENCIES_OUTPUT := $(DEPS) # Application standard rules include $(BD)/bappl/etc/makerules # ---------------------------------------------------------------------------- # Create target TARGET = prog_2 # Search path of source file S = ./ ../src VPATH = $(S) # Header file directory addition HEADER := $(S) $(HEADER) # Source file SRC = main.c OBJ = $(addsuffix .o, $(basename $(SRC))) WC_SRC = $(filter %.C, $(SRC)) DBFLAGS += -l ifeq ($(mode), debug) CFLAGS += -Wall endif # ---------------------------------------------------------------------------- .PHONY: all clean INST = $(addprefix $(TARGET), .bz .map) INST2 = $(addprefix $(TARGET), .out) all: $(INST) $(TARGET).out: $(OBJ) $(LINK.o) $(LDOBJS) $^ $(LOADLIBES) $(LDLIBS) $(OUTPUT_OPTION) clean: $(RM) $(OBJ) $(RM) $(WC_SRC:%.C=%.c) $(DBSRC) $(RM) $(INST) $(INST2) *.lst $(DEPS) # Compression archive $(TARGET).bz: $(INST2) $(CP) $(TARGET).out _t $(STRIP) _t $(MKBTF) -o$@ -a0x8003 -c -tprog_2 \ 9.$(CPU_TYPE)._t $(RM) _t # Source dependencies related $(WC_SRC:%.C=%.c): ifdef DEPENDENCIES_OUTPUT $(DEPS): ; touch $(DEPS) else $(DEPS): $(SRC) ; $(MAKEDEPS) $@ $? endif include $(DEPS) |
List 4 prog_3-main.c (reception side: receives message from prog_m2) |
/* * prog_3-main.c (T-Shell Sample/Main) * * (C) Copyright 2003 by Personal Media Corporation. */ #include <basic.h> #include <btron/outer.h> #include <tcode.h> #include <stdio.h> #include <stdlib.h> /* Internal type declarations */ typedef struct { /* Format handed over from MSCRIPT */ W msg_type; /* Same as MESSAGE.msg_type */ W msg_size; /* Same as MESSAGE.msg_size */ W ext_size; /* Ordinarily 0 in T-Shell */ UB msg_body[1]; /* Same as MESSAGE.msg_body */ } MSCRIPT_MSG; /* Internal variables */ LOCAL TC PROG_1_NM[8] = { /* [prog_3] */ TK_p, TK_r, TK_o, TK_g, TK_USCR, TK_3, TNULL }; /* ---------------------------------------------------- main(cli style main) */ /* * main(cli style main) */ EXPORT W main(W ac, TC *av[]) { W rv; W l; W pid; /* Self process ID */ W mpid; /* Message transmission source process ID*/ W msize; /* Message size(byte units) */ MESSAGE dmy; /* Message temporary reception use */ MSCRIPT_MSG *msg; /* Received message */ rv = 0; msg = NULL; /* Acquisition of self process ID */ pid = b_prc_sts(0, NULL, NULL); if (pid < ER_OK) { rv = pid; printf("b_prc_sts : %d, %d\n", rv, rv >> 16); goto EXIT; } /* Create global name */ rv = b_cre_nam(PROG_1_NM, pid, N_FORCE | DELEXIT); if (rv < ER_OK) { printf("b_cre_nam : %d, %d\n", rv, rv >> 16); goto EXIT; } /* Message reception wait */ for ( ; ; ) { /* Free previous reception region */ if (msg != NULL) { free(msg); msg = NULL; } /* Message temporary reception */ mpid = b_rcv_msg(MM_TYPE7, &dmy, sizeof(MESSAGE), WAIT|NOCLR); if ((mpid < ER_OK) && (mpid != ER_PAR)) { /* Error occurred (ER_PAR ignore) */ rv = mpid; printf("b_rcv_msg(dummy) : %d, %d\n", rv, rv >> 16); break; } /* Refuse if not application message 7 */ if (dmy.msg_type != MS_TYPE7) { /* Not needed, so discard */ b_clr_msg(MM_ALL, MM_ALL); continue; } /* Secure reception region */ msize = dmy.msg_size + sizeof(W) * 2; msg = (MSCRIPT_MSG *)(malloc(msize)); if (msg == NULL) { rv = ER_NOMEM; printf("memory allocation error.\n"); break; } /* Reception */ rv = b_rcv_msg(MM_TYPE7, (MESSAGE *)(msg), msize, NOWAIT|CLR); if (rv < ER_OK) { /* Error occurred */ printf("b_rcv_msg(main) : %d, %d\n", rv, rv >> 16); break; } else if (rv != mpid) { /* Process of transmission source different (no normal startup) */ printf("not match process ID\n"); ; /* Return to loop */ } else { /* Show the received contents and terminate */ printf("sender PID : %d\n", mpid); printf("all message size : %d\n", msize); printf("MESSAGE.msg_type : 0x%08x\n", msg->msg_type); printf("MESSAGE.msg_size : 0x%08x\n", msg->msg_size); printf("MESSAGE.ext_size : 0x%08x\n", msg->ext_size); printf("MESSAGE.msg_body :\n"); for (l = 0; l < (msg->msg_size - sizeof(W)); l++) { printf("%02x ", msg->msg_body[l]); } printf("\n"); break; } } EXIT: if (msg != NULL) { free(msg); } b_ext_prc(rv); return rv; } -------------------- # # @(#)Makefile (prog_3) # For use with GNU make # # make method # make # Create release use regular version # make mode=debug # Create for use in debugging # make clean # Delete all files created with make # make install # Install in the prescribed place (for actual machine use only) # # Version version = 0x1000 # Set release use to default #mode = # Source dependencies-related file (automatically created) DEPS = Dependencies DEPENDENCIES_OUTPUT := $(DEPS) # Application standard rules include $(BD)/bappl/etc/makerules # ---------------------------------------------------------------------------- # Create target TARGET = prog_3 # Search path of source file S = ./ ../src VPATH = $(S) # Header file directory addition HEADER := $(S) $(HEADER) # Source file SRC = main.c OBJ = $(addsuffix .o, $(basename $(SRC))) WC_SRC = $(filter %.C, $(SRC)) DBFLAGS += -l ifeq ($(mode), debug) CFLAGS += -Wall endif # ---------------------------------------------------------------------------- .PHONY: all clean INST = $(addprefix $(TARGET), .bz .map) INST2 = $(addprefix $(TARGET), .out) all: $(INST) $(TARGET).out: $(OBJ) $(LINK.o) $(LDOBJS) $^ $(LOADLIBES) $(LDLIBS) $(OUTPUT_OPTION) clean: $(RM) $(OBJ) $(RM) $(WC_SRC:%.C=%.c) $(DBSRC) $(RM) $(INST) $(INST2) *.lst $(DEPS) # Compression archive $(TARGET).bz: $(INST2) $(CP) $(TARGET).out _t $(STRIP) _t $(MKBTF) -o$@ -a0x8003 -c -tprog_3 \ 9.$(CPU_TYPE)._t $(RM) _t # Source dependencies related $(WC_SRC:%.C=%.c): ifdef DEPENDENCIES_OUTPUT $(DEPS): ; touch $(DEPS) else $(DEPS): $(SRC) ; $(MAKEDEPS) $@ $? endif include $(DEPS) |
List 5 prog_m2 (transmission side: transmits message to prog_3-main.c) |
# # - prog_m2 - # # (C) Copyright 2003 by Personal Media Corporation. # VERSION 3 # # Start of program # PROLOGUE LOCAL spid:I; LOCAL data:I[1]; # Acquisition of global name spid = getgnm("prog_3") IF (valid(spid)) # Prepare contents to be transmitted data[0] = 0x12345678 # Suitable contents # Transmit message MSEND spid, 7, 4, data ELSE LOG "not found [prog_3]" ENDIF # Terminate FINISH END |
prog_m3 |
# # - prog_m3 - # # (C) Copyright 2003 by Personal Media Corporation. # # Basically implemented in little endian # prog_4, which becomes the opposite address for cooperation, must be executed first # # Basic declarations VERSION 3 # Number of version used DEBUG 0 # debug mode # Constants DEFINE ER_OK 0 DEFINE NULL 0 DEFINE TNULL 0x0000 DEFINE True 1 DEFINE False 0 DEFINE WND_XPOS 0 # Horizontal position DEFINE WND_YPOS 0 # Vertical position DEFINE WND_WIDTH 240 # Width DEFINE WND_HEIGHT 296 # Height DEFINE SMPL_MSGTYPE 7 # Message type used (MS_TYPE7 equivalent) DEFINE SMPL_MSGMASK 0x80 # Message type used (MM_TYPE7 equivalent) DEFINE PROG_4_NM "prog_4" # Global name cooperation target sets DEFINE MSGRCV_TMOUT 5 # Request reply wait([sec units]) DEFINE MSG_MAGIC0 ('S' - 0x2300) # Identifier DEFINE MSG_MAGIC1 ('M' - 0x2300) # Identifier DEFINE MSG_MAGIC2 ('P' - 0x2300) # Identifier DEFINE MSG_MAGIC3 ('L' - 0x2300) # Identifier DEFINE HD_MAGIC0 0 DEFINE HD_MAGIC1 1 DEFINE HD_MAGIC2 2 DEFINE HD_MAGIC3 3 DEFINE HD_TYPE0 7 # cmd_type UW type DEFINE HD_TYPE1 6 DEFINE HD_TYPE2 5 DEFINE HD_TYPE3 4 DEFINE HD_ERR0 11 # err_code ERR(W) type DEFINE HD_ERR1 10 DEFINE HD_ERR2 9 DEFINE HD_ERR3 8 DEFINE MTREQ_START 0x00010001 # Requests DEFINE MTREQ_FINISH 0x00010002 DEFINE MTREQ_REDRAW 0x00010003 DEFINE MTREQ_LINE 0x00010004 DEFINE MTREQ_BOX 0x00010005 DEFINE MTREQ_CIRCLE 0x00010006 DEFINE MTREQ_TEXT 0x00010007 DEFINE MTRSP_NORMAL 0x00020001 # Replies DEFINE REDRAW_TIME 100 # Redraw frequency time([msec] units) # Global variables VARIABLE isBusy:B # True : execution processing in progress VARIABLE act_type:I # Execution contents(< 0 : processing undecided) VARIABLE sel_col:I # Selected color(permutation number) VARIABLE sp:I[2] # Start point VARIABLE ep:I[2] # End point VARIABLE col_tbl:I[8] # Table of colors # ------------------------------------------------------------- prog_4 Calls(key) # # Find [prog_4] of call target # FUNC srch_prog4() LOCAL pid:I pid = getgnm(PROG_4_NM) IF (!(valid(pid))) pid = -1 ENDIF EXIT pid END # # Send request to prog_4 # FUNC snd_msg(msg_dat:B[], msg_len:I) LOCAL rv:I LOCAL pid:I rv = 0 # Find call target(confirm existence each time) pid = srch_prog4() IF (pid > ER_OK) # Send request MSEND pid, SMPL_MSGTYPE, msg_len, msg_dat IF ($ERR != ER_OK) rv = -$ERR ELSE rv = pid ENDIF ENDIF EXIT rv END # # Receive reply from prog_4 # FUNC rcv_msg(ret_dat:B[], ret_len:I, ppid:I) LOCAL rv:I LOCAL pid:I LOCAL type:I LOCAL len:I LOCAL buf:B[4095] rv = ER_OK $MMASK = SMPL_MSGMASK # Reception MRECV SMPL_MSGMASK, pid, type, len, buf: MSGRCV_TMOUT IF ($ERR != ER_OK) # Reception error rv = -$ERR ELSEIF (pid != ppid) # Message from something unrelated rv = 0 ELSE # Return contents rv = len REPEAT len ret_dat[$CNT] = buf[$CNT] IF (($CNT + 1) >= ret_len) BREAK ENDIF ENDREPEAT ENDIF EXIT rv END # # Send and receive messages with prog_4 # FUNC snr_msg(snd_dat:B[], snd_len:I, rcv_dat:B[], rcv_len:I, isPeriod:B) LOCAL rv:I LOCAL pid:I rv = ER_OK # Make busy temporarily IF (!(isPeriod)) $PDS = 14 isBusy = True ENDIF # Transmission pid = snd_msg(snd_dat, snd_len) IF (pid > ER_OK) # Reception (receive reply) rv = rcv_msg(rcv_dat, rcv_len, pid) ELSE # Failure rv = pid ENDIF # Release busy IF (!(isPeriod)) $PDS = 0 isBusy = False ENDIF EXIT rv END # ------------------------------------------ prog_4 Calls (processing of structures) # # Setting the header part # FUNC head_setup(msg_dat:B[], type:I) # Setting the identifiers msg_dat[HD_MAGIC0] = MSG_MAGIC0 msg_dat[HD_MAGIC1] = MSG_MAGIC1 msg_dat[HD_MAGIC2] = MSG_MAGIC2 msg_dat[HD_MAGIC3] = MSG_MAGIC3 # Setting the type numbers msg_dat[HD_TYPE0] = ((type & 0xff000000) >> 24) msg_dat[HD_TYPE1] = ((type & 0x00ff0000) >> 16) msg_dat[HD_TYPE2] = ((type & 0x0000ff00) >> 8) msg_dat[HD_TYPE3] = (type & 0x000000ff) EXIT END # # Setting int(W)-type contents in arbitrary positions # FUNC set_intdat(msg_dat:B[], idx:I, val:I) msg_dat[idx + 3] = ((val & 0xff000000) >> 24) msg_dat[idx + 2] = ((val & 0x00ff0000) >> 16) msg_dat[idx + 1] = ((val & 0x0000ff00) >> 8) msg_dat[idx ] = (val & 0x000000ff) EXIT END # # Setting H(UH)-type contents in arbitrary position # FUNC set_worddat(msg_dat:B[], idx:I, val:I) msg_dat[idx + 1] = ((val & 0xff00) >> 8) msg_dat[idx ] = (val & 0x00ff) EXIT END # # Setting TC string contents in arbitrary positions # # Call # msg_dat[]:B : Contents you want to send # idx:I : Position you want to set # dat_str[]:C : Contents you want to set # dat_len:I : Contents length you want to set (TC units) # # Return # None # FUNC set_tcstrdat(msg_dat:B[], idx:I, dat_str:C[], dat_len:I) REPEAT dat_len msg_dat[idx + 1] = ((dat_str[$CNT] & 0xff00) >> 8) msg_dat[idx ] = (dat_str[$CNT] & 0x00ff) idx = idx + 2 ENDREPEAT EXIT END # # Collation of reply contents # FUNC check_ret(msg_dat:B[]) LOCAL type:I type = -1 # Initial value type undefined # Compare identifiers IF ((msg_dat[HD_MAGIC0] == MSG_MAGIC0) && \ (msg_dat[HD_MAGIC1] == MSG_MAGIC1) && \ (msg_dat[HD_MAGIC2] == MSG_MAGIC2) && \ (msg_dat[HD_MAGIC3] == MSG_MAGIC3)) # Acquire type type = ((msg_dat[HD_TYPE0] << 24) | \ (msg_dat[HD_TYPE1] << 16) | \ (msg_dat[HD_TYPE2] << 8) | \ (msg_dat[HD_TYPE3] )) ENDIF EXIT type END # # Acquire error code of reply contents # FUNC get_errcode(msg_dat:B[]) LOCAL rv:I # Acquisition of contents (because multiplying by -1 is received as ERR) rv = -((msg_dat[HD_ERR0] << 24) | (msg_dat[HD_ERR1] << 16) | \ (msg_dat[HD_ERR2] << 8) | (msg_dat[HD_ERR3] )) EXIT rv END # # Start of calls # FUNC req_start() LOCAL rv:I LOCAL rtype:I LOCAL sbuf:B[16] # 4 + 4 + 2 * 4 LOCAL rbuf:B[12] # 4 + 4 + 4 rv = ER_OK # Preparing the transmission contents CALL head_setup(sbuf, MTREQ_START) CALL set_worddat(sbuf, 8, WORK_AREA.X) CALL set_worddat(sbuf, 10, WORK_AREA.Y) CALL set_worddat(sbuf, 12, WORK_AREA.X + WORK_AREA.W) CALL set_worddat(sbuf, 14, WORK_AREA.Y + WORK_AREA.H) # Transmission reception rv = snr_msg(sbuf, 16, rbuf, 12, False) IF (rv > 0) # Operation was successful, so confirm the reply contents rtype = check_ret(rbuf) IF (rtype == MTRSP_NORMAL) # Acquisition of the error code rv = get_errcode(rbuf) ENDIF ELSEIF (rv == 0) # Transmission reception failure (no opposite to cooperate) rv = -1 ENDIF EXIT rv END # # Terminate call # FUNC req_finish() LOCAL rv:I LOCAL rtype:I LOCAL sbuf:B[8] # 4 + 4 LOCAL rbuf:B[12] # 4 + 4 + 4 rv = ER_OK # Prepare transmission contents CALL head_setup(sbuf, MTREQ_FINISH) # Transmission reception rv = snr_msg(sbuf, 8, rbuf, 12, False) IF (rv > 0) # Operation was successful, so confirm the reply contents rtype = check_ret(rbuf) IF (rtype == MTRSP_NORMAL) # Acquire the error code rv = get_errcode(rbuf) ENDIF ELSEIF (rv == 0) # Transmission reception failure(no opposite to cooperate) rv = -1 ENDIF EXIT rv END # # Request to redraw # FUNC req_redraw(left:I, top:I, right:I, bottom:I, isPeriod:B) LOCAL rv:I LOCAL i:I LOCAL rtype:I LOCAL sbuf:B[16] # 4 + 4 + 2 * 4 LOCAL rbuf:B[12] # 4 + 4 + 4 rv = ER_OK IF (left >= right) i = left left = right right = i ENDIF IF (top >= bottom) i = top top = bottom bottom = i ENDIF # Prepare transmission contents CALL head_setup(sbuf, MTREQ_REDRAW) CALL set_worddat(sbuf, 8, left) CALL set_worddat(sbuf, 10, top) CALL set_worddat(sbuf, 12, right) CALL set_worddat(sbuf, 14, bottom) # Transmission reception rv = snr_msg(sbuf, 16, rbuf, 12, isPeriod) IF (rv > 0) # Operation was successful, so confirm the reply contents rtype = check_ret(rbuf) IF (rtype == MTRSP_NORMAL) # Error code acquisition rv = get_errcode(rbuf) ENDIF ELSEIF (rv == 0) # Transmission reception failure (no opposite to cooperate) rv = -1 ENDIF EXIT rv END # # Draw straight line # FUNC req_line(spX:I, spY:I, epX:I, epY:I) LOCAL rv:I LOCAL rtype:I LOCAL sbuf:B[20] # 4 + 4 + 2 * 2 + 2 * 2 + 4 LOCAL rbuf:B[12] # 4 + 4 + 4 rv = ER_OK # Prepare transmission contents CALL head_setup(sbuf, MTREQ_LINE) CALL set_worddat(sbuf, 8, spX) CALL set_worddat(sbuf, 10, spY) CALL set_worddat(sbuf, 12, epX) CALL set_worddat(sbuf, 14, epY) CALL set_intdat(sbuf, 16, col_tbl[sel_col]) # Transmission reception rv = snr_msg(sbuf, 20, rbuf, 12, False) IF (rv > 0) # Operation was successful, so confirm the reply contents rtype = check_ret(rbuf) IF (rtype == MTRSP_NORMAL) # Error code acquisition rv = get_errcode(rbuf) ENDIF ELSEIF (rv == 0) # Transmission reception failure (no opposite to cooperate) rv = -1 ENDIF EXIT rv END # # Draw rectangular frame # FUNC req_box(left:I, top:I, right:I, bottom:I) LOCAL rv:I LOCAL i:I LOCAL rtype:I LOCAL sbuf:B[20] # 4 + 4 + 2 * 4 + 4 LOCAL rbuf:B[12] # 4 + 4 + 4 rv = ER_OK IF (left >= right) i = left left = right right = i ENDIF IF (top >= bottom) i = top top = bottom bottom = i ENDIF # Prepare transmission contents CALL head_setup(sbuf, MTREQ_BOX) CALL set_worddat(sbuf, 8, left) CALL set_worddat(sbuf, 10, top) CALL set_worddat(sbuf, 12, right) CALL set_worddat(sbuf, 14, bottom) CALL set_intdat(sbuf, 16, col_tbl[sel_col]) # Transmission reception rv = snr_msg(sbuf, 20, rbuf, 12, False) IF (rv > 0) # Operation was successful, so confirm the reply contents rtype = check_ret(rbuf) IF (rtype == MTRSP_NORMAL) # Error code acquisition rv = get_errcode(rbuf) ENDIF ELSEIF (rv == 0) # Transmission reception failure (no opposite to cooperate) rv = -1 ENDIF EXIT rv END # # Draw circle/ellipse # FUNC req_circle(left:I, top:I, right:I, bottom:I) LOCAL rv:I LOCAL i:I LOCAL rtype:I LOCAL sbuf:B[20] # 4 + 4 + 2 * 4 + 4 LOCAL rbuf:B[12] # 4 + 4 + 4 rv = ER_OK IF (left >= right) i = left left = right right = i ENDIF IF (top >= bottom) i = top top = bottom bottom = i ENDIF # Prepare transmission contents CALL head_setup(sbuf, MTREQ_CIRCLE) CALL set_worddat(sbuf, 8, left) CALL set_worddat(sbuf, 10, top) CALL set_worddat(sbuf, 12, right) CALL set_worddat(sbuf, 14, bottom) CALL set_intdat(sbuf, 16, col_tbl[sel_col]) # Transmission reception rv = snr_msg(sbuf, 20, rbuf, 12, False) IF (rv > 0) # Operation was successful, so confirm the reply contents rtype = check_ret(rbuf) IF (rtype == MTRSP_NORMAL) # Error code acquisition rv = get_errcode(rbuf) ENDIF ELSEIF (rv == 0) # Transmission reception error (no opposite to cooperate) rv = -1 ENDIF EXIT rv END # # Draw character string # FUNC req_text(pX:I, pY:I) LOCAL rv:I LOCAL rtype:I LOCAL sbuf:B[530] # 4 + 4 + 2 * 2 + 4 + arbitrary ((256+1) * 2) LOCAL rbuf:B[12] # 4 + 4 + 4 # Prepare transmission contents CALL head_setup(sbuf, MTREQ_TEXT) CALL set_worddat(sbuf, 8, pX) CALL set_worddat(sbuf, 10, pY) CALL set_intdat(sbuf, 12, col_tbl[sel_col]) CALL set_tcstrdat(sbuf, 16, TB_TEXT.TX, TB_TEXT.TL) CALL set_worddat(sbuf, 16 + TB_TEXT.TL * 2, TNULL) # Transmission reception rv = snr_msg(sbuf, 16 + (TB_TEXT.TL + 1) * 2, rbuf, 12, False) IF (rv > 0) # Operation was successful, so confirm the reply contents rtype = check_ret(rbuf) IF (rtype == MTRSP_NORMAL) # Error code acquisition rv = get_errcode(rbuf) ENDIF ELSEIF (rv == 0) # Transmission reception failure (no opposite to cooperate) rv = -1 ENDIF EXIT rv END # ------------------------------------------ Segment operations(basic parts types) # # MS_PARTS press (event loop) # FUNC press_MS_PARTS(seg:S) LOCAL flg:B flg = False IF ($WACT == 0) # Synchronization not carried out in window switching ELSE # Overlapping pictures during a press MOVE MS_FRAME_P:seg.X, seg.Y, @ # Event loop during press REPEAT IF (($PDX > seg.X) && ($PDX < seg.X + seg.W) && \ ($PDY > seg.Y) && ($PDY < seg.Y + seg.H)) # Inside the parts region IF (!(flg)) flg = True APPEAR MS_FRAME_P ENDIF ELSE # Outside the parts region flg = False DISAPPEAR MS_FRAME_P ENDIF IF ($PDB == 0) # Released the PD DISAPPEAR MS_FRAME_P BREAK ENDIF ENDREPEAT DISAPPEAR MS_FRAME_P ENDIF EXIT flg END # # Press processing (event loop) of WS_PARTS # FUNC press_WS_PARTS(seg:S, oseg:S, oimg:S, iimg:S) LOCAL flg:B flg = False IF ($WACT == 0) # Synchronization not carried out in window switching ELSE # Overlapping pictures during press MOVE oimg:oseg.X, oseg.Y, @ MOVE iimg:seg.X, seg.Y + 4, @ # Event loop during press REPEAT IF (($PDX > seg.X) && ($PDX < seg.X + seg.W) && \ ($PDY > seg.Y) && ($PDY < seg.Y + seg.H)) # Inside the parts region IF (!(flg)) flg = True APPEAR oimg APPEAR iimg ENDIF ELSE # Outside the parts region flg = False DISAPPEAR oimg DISAPPEAR iimg ENDIF IF ($PDB == 0) # Released the PD DISAPPEAR oimg DISAPPEAR iimg BREAK ENDIF ENDREPEAT DISAPPEAR oimg DISAPPEAR iimg ENDIF EXIT flg END # # Execution processing part of each MS_PARTS # ACTION act_MS_DRAW(seg:S, idx:I, x:I, y:I) PRESS MS_LINE, MS_BOX, MS_CIRCLE, MS_TEXT IF (isBusy) EXIT ENDIF IF (press_MS_PARTS(seg)) act_type = idx ENDIF EXIT END # # Execution processing part of TB_PARTS used to input character strings # ACTION act_TB_TEXT(seg:S, idx:I, x:I, y:I) CLICK TB_TEXT KINPUT seg, x, y EXIT END # # Execution part of WS_PARTS for color selection # ACTION act_WS_COLOR(seg:S, idx:I, x:I, y:I) PRESS WS_BLACK, WS_BLUE, WS_RED, WS_MAGENTA, WS_GREEN, WS_CYAN, WS_YELLOW, WS_WHITE # Join with above line IF (isBusy) EXIT ENDIF IF (idx == sel_col) CALL press_WS_PARTS(seg, WS_FRAME, WS_FRAME_P, AS_IND_ONP) ELSE IF (press_WS_PARTS(seg, WS_FRAME, WS_FRAME_P, AS_IND_OFFP)) sel_col = idx MOVE AS_IND_ON:seg.X, seg.Y + 4, @ ENDIF ENDIF EXIT END # # Execution processing part of work area # ACTION act_WORK_AREA(seg:S, idx:I, x:I, y:I) CLICK WORK_AREA IF ((isBusy) || (act_type < 0)) EXIT ENDIF x = x - seg.X y = y - seg.Y IF (act_type == 3) # Character string immediately executed with a click sp[0] = x sp[1] = y CALL req_text(sp[0], sp[1]) act_type = -1 ELSE # Otherwise, two points specified IF (act_type < 10) # Start point_ sp[0] = x sp[1] = y act_type = act_type + 10 ELSE # End point ep[0] = x ep[1] = y SWITCH (act_type) CASE 10 # Straight line CALL req_line(sp[0],sp[1],ep[0],ep[1]) BREAK CASE 11 # Rectangular frame CALL req_box(sp[0],sp[1],ep[0],ep[1]) BREAK CASE 12 # Circle/ellipse CALL req_circle(sp[0],sp[1],ep[0],ep[1]) BREAK ENDCASE act_type = -1 ENDIF ENDIF EXIT END # ------------------------------------------------------------------ Main processes # # Initialization of internal state # FUNC init_proc() LOCAL rv:I rv = ER_OK isBusy = False act_type = -1 sel_col = 0 sp[0] = 0 sp[1] = 0 ep[0] = 0 ep[1] = 0 col_tbl[0] = 0x10000000 # Black col_tbl[1] = 0x100000ff # Blue col_tbl[2] = 0x10ff0000 # Red col_tbl[3] = 0x10ff00ff # Magenta col_tbl[4] = 0x1000ff00 # Green col_tbl[5] = 0x1000ffff # Cyan col_tbl[6] = 0x10ffff00 # Yellow col_tbl[7] = 0x10ffffff # White # Initialize processes of call targets rv = req_start() EXIT rv END # # Initialization of each segment # FUNC init_seg() LOCAL rv:I rv = ER_OK # Stop display UPDATE 0 # Initialization of the contents of each segments TEXT TB_TEXT, "" SWITCH (sel_col) CASE 0 MOVE AS_IND_ON:WS_BLACK.X, WS_BLACK.Y + 4, @ BREAK CASE 1 MOVE AS_IND_ON:WS_BLUE.X, WS_BLUE.Y + 4, @ BREAK CASE 2 MOVE AS_IND_ON:WS_RED.X, WS_RED.Y + 4, @ BREAK CASE 3 MOVE AS_IND_ON:WS_MAGENTA.X, WS_MAGENTA.Y + 4, @ BREAK CASE 4 MOVE AS_IND_ON:WS_GREEN.X, WS_GREEN.Y + 4, @ BREAK CASE 5 MOVE AS_IND_ON:WS_CYAN.X, WS_CYAN.Y + 4, @ BREAK CASE 6 MOVE AS_IND_ON:WS_YELLOW.X, WS_YELLOW.Y + 4, @ BREAK CASE 7 MOVE AS_IND_ON:WS_WHITE.X, WS_WHITE.Y + 4, @ BREAK ENDCASE # Display each segment APPEAR AS_IND_ON APPEAR MS_LINE APPEAR MS_BOX APPEAR MS_CIRCLE APPEAR MS_TEXT APPEAR TB_TEXT APPEAR WS_BLACK APPEAR WS_BLUE APPEAR WS_RED APPEAR WS_MAGENTA APPEAR WS_GREEN APPEAR WS_CYAN APPEAR WS_YELLOW APPEAR WS_WHITE APPEAR WS_FRAME APPEAR WORK_AREA # Reopen display UPDATE 1 CALL req_redraw(0, 0, 0, 0, False) # Execute and put in place the text box KINPUT TB_TEXT EXIT rv END # # Periodic redrawing # MACTION period_redraw() REPEAT IF (REDRAW_TIME > 0) SLEEP REDRAW_TIME ENDIF # Issue redraw request CALL req_redraw(0, 0, 0, 0, True) ENDREPEAT # Doesn't come here EXIT END # # Main processing part of application # FUNC main_proc() LOCAL rv:I # Initialization processing rv = init_proc() IF (rv != ER_OK) FINISH # Crash ENDIF rv = init_seg() IF (rv != ER_OK) FINISH # Crash ENDIF # Make carry out periodic redrawing EXECUTE period_redraw() EXIT END # --------------------------------- Basic processes(startup/termination processing) # # Startup processing # PROLOGUE # Adjust window position IF (($WDX != WND_XPOS) || ($WDY != WND_YPOS)) WMOVE WND_XPOS, WND_YPOS ENDIF # Adjust window size IF (($WDW != WND_WIDTH) || ($WDH != WND_HEIGHT)) WSIZE WND_WIDTH, WND_HEIGHT ENDIF # Start CALL main_proc() END # # Termination processing # EPILOGUE # Stop periodic processes TERMINATE # Stop call targets # CALL req_finish() WSAVE END |
prog_4-main.c |
/* * prog_4-main.c (T-Shell sample/Main) * * (C) Copyright 2003 by Personal Media Corporation. */ #include "sample.h" /* Internal variables */ LOCAL TC PROG_4_NM[8] = { /* [prog_4] */ TK_p, TK_r, TK_o, TK_g, TK_USCR, TK_4, TNULL }; /* Internal function prototypes */ LOCAL ERR init_proc(VOID); LOCAL VOID fin_proc(VOID); /* ------------------------------------------------------ Internal functions */ /* * Initialization processing */ LOCAL ERR init_proc(VOID) { ERR er; W pid; er = ER_OK; /* Acquisition of self process ID */ pid = b_prc_sts(0, NULL, NULL); printf("b_prc_sts : %d, %d\n", pid, pid >> 16); /* Set global name */ er = b_cre_nam(PROG_4_NM, pid, N_CREATE | DELEXIT); if (er < ER_OK) { printf("b_cre_nam : %d, %d\n", er, er >> 16); goto EXIT; } /* Initialization of drawing processes */ er = draw_init(); if (er < ER_OK) { printf("draw_init : %d, %d\n", er, er >> 16); } EXIT: return er; } /* * Termination processing */ LOCAL VOID fin_proc(VOID) { /* Resource freeing of drawing processes */ draw_fin(); return; } /* ---------------------------------------------------- main(cli style main) */ /* * main (cli style main) */ EXPORT W main(W ac, TC *av[]) { W rv; rv = 0; /* Initialization processing */ rv = init_proc(); if (rv >= ER_OK) { /* Start event loop */ rv = event_loop(); } /* Termination processing */ fin_proc(); b_ext_prc(rv); return rv; } -------------------- /* * prog_4-draw.c (T-Shell Sample/Drawing Processes) * * (C) Copyright 2003 by Personal Media Corporation. */ #include "sample.h" /* Internal macros */ #define DEF_BMP (BMP){1, 0, 0x0000, {{0, 0, 0, 0}}, {NULL}} #define rectwidth(r) ((r).c.right - (r).c.left) #define rectheight(r) ((r).c.bottom - (r).c.top) /* Internal variables */ LOCAL W gid = -1; /* Drawing environment ID of the drawing target */ LOCAL W bgid = 1; /* Drawing environment ID for work use */ LOCAL BMP bmp = DEF_BMP; /* Bitmap for work use */ LOCAL PAT pat; /* Patterns for color specification use */ LOCAL RECT dr; /* Rectangular region of the display address */ /* Internal function prototype */ LOCAL ERR disp_buffer(VOID); /* ---------------------------------------------------------------- Internal functions */ /* * Making the contents of the work region reflect on the screen */ LOCAL ERR disp_buffer(VOID) { ERR er; er = b_gcop_bmp(bgid, &bmp.bounds, gid, &dr, NULL, G_STORE | G_CVCOLOR | G_CVFORM); if (er < ER_OK) { printf("b_gcop_bmp : %d, %d\n", er, er >> 16); } return er; } /* ================================================================ Global functions */ /* -------------------------------------------------------------- Main processes */ /* * Initialization processing (mainly equivalent to a constructor) */ EXPORT ERR draw_init(VOID) { ERR er; er = ER_OK; /* Initialize each variable */ gid = -1; bgid = -1; bmp = DEF_BMP; dr = (RECT){{0, 0, 0, 0}}; /* Set patterns */ pat = (PAT){{0, 16, 16, 0x10000000, 0x80000000, FILL100}}; return er; } /* * Termination processing (Mainly equivalent to a destructor) */ EXPORT VOID draw_fin(VOID) { /* Free each resource */ if (bgid >= 0) { b_gcls_env(bgid); } if (bmp.baseaddr[0] != NULL) { free(bmp.baseaddr[0]); } /* Return variables to initials */ gid = -1; bgid = -1; bmp = DEF_BMP; dr = (RECT){{0, 0, 0, 0}}; return; } /* ---------------------------------------------------------------- Drawing related */ /* * Creation of the work region */ EXPORT ERR draw_gen_workarea(W pgid, RECT r) { ERR er; CSPEC csp = {0x0001, {0x1008, 0x0808, 0x0008, 0}, NULL}; er = ER_OK; /* Remember display address */ gid = pgid; dr = r; /* Create work region (create environment of 16.70 million colors) */ bmp.planes = 1; bmp.pixbits = 0x2018; bmp.bounds.p.lefttop = (PNT){0, 0}; bmp.bounds.c.right = rectwidth(r); bmp.bounds.c.bottom = rectheight(r); bmp.rowbytes = rectwidth(r) << 2; bmp.baseaddr[0] = (UB *)(malloc(bmp.rowbytes * rectheight(r))); printf("bmp.bounds : %d, %d, %d, %d\n", bmp.bounds.c.left, bmp.bounds.c.top, bmp.bounds.c.right, bmp.bounds.c.bottom); if (bmp.baseaddr[0] == NULL) { er = ER_NOMEM; printf("memory allocation error.\n"); } else { /* Create drawing environment of the work region */ bgid = b_gopn_mem(NULL, &bmp, (B *)(&csp)); printf("b_gopn_mem : %d, %d\n", bgid, bgid >> 16); if (bgid < ER_OK) { er = bgid; } else { /* Initialize contents (paint over with white) */ b_gfil_rec(bgid, bmp.bounds, WHITE0, 0, G_STORE); /* Reflect in display */ er = disp_buffer(); } } return er; } /* * Redraw */ EXPORT ERR draw_redraw(RECT r) { ERR er; RECT vr; er = ER_OK; /* Remember original display region */ b_gget_vis(gid, &vr); /* Switch to redraw region */ /* printf("r : %d, %d, %d, %d\n", r.c.left, r.c.top, r.c.right, r.c.bottom); */ if ((r.c.left < r.c.right) && (r.c.top < r.c.bottom)) { b_gset_vis(gid, r); } /* Draw contents */ er = disp_buffer(); /* Return display region */ b_gset_vis(gid, vr); return er; } /* * Draw straight line */ EXPORT ERR draw_line(PNT sp, PNT ep, COLOR col) { ERR er; er = ER_OK; /* Set color */ pat.spat.fgcol = col; /* Draw line */ printf("sp : %d, %d ep : %d, %d col : 0x%08x\n", sp.x, sp.y, ep.x, ep.y, col); er = b_gdra_lin(bgid, sp, ep, 0x0001, &pat, G_STORE); if (er < ER_OK) { printf("b_gdra_lin : %d, %d\n", er, er >> 16); } else { /* Reflect in display */ er = disp_buffer(); } return er; } /* * Draw rectangular frame */ EXPORT ERR draw_box(RECT r, COLOR col) { ERR er; er = ER_OK; /* Set color */ pat.spat.fgcol = col; /* Draw line */ printf("r : %d, %d, %d, %d col : 0x%08x\n", r.c.left, r.c.top, r.c.right, r.c.bottom, col); er = b_gfra_rec(bgid, r, 0x0001, &pat, 0, G_STORE); if (er < ER_OK) { printf("b_gfra_rec : %d, %d\n", er, er >> 16); } else { /* Reflect in display */ er = disp_buffer(); } return er; } /* * Draw circle/ellipse */ EXPORT ERR draw_circle(RECT r, COLOR col) { ERR er; er = ER_OK; /* Set color */ pat.spat.fgcol = col; /* Draw line */ printf("r : %d, %d, %d, %d col : 0x%08x\n", r.c.left, r.c.top, r.c.right, r.c.bottom, col); er = b_gfra_ovl(bgid, r, 0x0001, &pat, 0, G_STORE); if (er < ER_OK) { printf("b_gfra_ovl : %d, %d\n", er, er >> 16); } else { /* Reflect in display */ er = disp_buffer(); } return er; } /* * Draw character string */ EXPORT ERR draw_text(PNT p, COLOR col, const TC *str) { ERR er; WERR rv; er = ER_OK; /* Set color */ b_gset_chc(bgid, col, 0x80000000); /* Switch language/script specification */ b_gset_scr(bgid, TSC_SYS); /* Draw character string */ printf("p : %d, %d col : 0x%08x\n", p.x, p.y, col); printf("text : %S\n", str); rv = b_gdra_stp(bgid, p.x, p.y + 16, (TC *)(str), tc_strlen(str), G_STORE); if (rv < ER_OK) { er = rv; printf("b_gdra_stp : &%d, %d\n", er, er >> 16); } else { /* Reflect in display */ er = disp_buffer(); } return er; } -------------------- /* * prog_4-evt.c (T-Shell Sample/Event Loop) * * (C) Copyright 2003 by Personal Media Corporation. */ #include "sample.h" /* Internal function prototype */ LOCAL Bool chk_header(const MSG_ANY *msg); /* Global variable */ EXPORT Bool doloop = False; /* True : Internal functions */ /* ---------------------------------------------------------------- Internal functions */ /* * Confirm the header */ LOCAL Bool chk_header(const MSG_ANY *msg) { Bool flg; flg = False; /* Initial value does not match */ /* Confirmation of message type used */ if (msg->hd.msg_type != SMPL_MSGTYPE) { printf("not match message type.\n"); goto EXIT; } /* Confirmation of minimum length */ if (msg->hd.msg_size < (sizeof(MSG_HEAD) - offsetof(MSG_HEAD,ext_size))) { printf("not enough size.\n"); goto EXIT; } /* Collation of identifiers */ if ((msg->hd.magic[0] != MSG_MAGIC0) || (msg->hd.magic[1] != MSG_MAGIC1) || (msg->hd.magic[2] != MSG_MAGIC2) || (msg->hd.magic[3] != MSG_MAGIC3)) { printf("not match magic.\n"); goto EXIT; } /* Recognition */ flg = True; EXIT: return flg; } /* -------------------------------------------------------------- Main processes */ /* * Event loop of message reception wait */ EXPORT WERR event_loop(VOID) { WERR rv; W pid; MSG_ANY dmy; /* Temporary reception use */ rv = ER_OK; doloop = True; do { /* Temporary reception */ pid = b_rcv_msg(SMPL_MSGMASK, (MESSAGE *)(&dmy), sizeof(dmy), WAIT | NOCLR); if ((pid < ER_OK) && (pid != ER_PAR)) { rv = pid; printf("b_rcv_msg : %d, %d\n", rv, rv >> 16); break; } /* Verification of header part */ if (chk_header(&dmy)) { /* Main reception */ rv = recv_main(&dmy); if (rv < ER_OK) { printf("recv_main : %d, %d\n", rv); } } else { /* Discard as it does not seem related */ b_clr_msg(MM_ALL, MM_ALL); continue; } } while (doloop); return rv; } -------------------- /* * prog_4-gval.h (T-Shell Sample/Global Variable Declaration) * * (C) Copyright 2003 by Personal Media Corporation. */ #ifndef _PROG_4_GVAL_H #define _PROG_4_GVAL_H /* from main.c */ /* from evt.c */ IMPORT Bool doloop; /* True : continue event loop */ /* from rcvmsg.c */ /* from sndmsg.c */ /* from draw.c */ #endif /* _PROG_4_GVAL_H */ -------------------- /* * prog_4-msg.h (T-Shell Sample/Message Definitions) * * (C) Copyright 2003 by Personal Media Corporation. */ #ifndef _PROG_4_MSG_H #define _PROG_4_MSG_H /* ---------------------------------------------------------------- Basic definitions */ #define SMPL_MSGTYPE MS_TYPE7 #define SMPL_MSGMASK MM_TYPE7 #define MSG_MAGIC0 'S' /* Identifier */ #define MSG_MAGIC1 'M' #define MSG_MAGIC2 'P' #define MSG_MAGIC3 'L' #define MSG_TYPEID_MASK 0xffff0000 #define MSG_OPE_MASK 0x0000ffff enum MSG_TYPEID { MSG_TYPEID_REQ = 0x00010000, MSG_TYPEID_RSP = 0x00020000 }; typedef struct { /* Header part*/ W msg_type; /* Same as MESSAGE.msg_type */ W msg_size; /* Same as MESSAGE.msg_size */ W ext_size; UB magic[4]; /* Identifier */ UW type; /* Call contents classification */ } MSG_HEAD; typedef struct { /* Arbitrary format*/ MSG_HEAD hd; /* Header part */ UB dt[1]; /* Some kind of data string */ } MSG_ANY; /* ------------------------------------------------------------------ Requests */ enum MSGTYPE_REQ { /* Classification numbers of requests */ MSGTYPE_REQ_START = 0x00010001, MSGTYPE_REQ_FINISH = 0x00010002, MSGTYPE_REQ_REDRAW = 0x00010003, MSGTYPE_REQ_LINE = 0x00010004, MSGTYPE_REQ_BOX = 0x00010005, MSGTYPE_REQ_CIRCLE = 0x00010006, MSGTYPE_REQ_TEXT = 0x00010007 }; typedef struct { /* Call start */ MSG_HEAD hd; /* Header part */ RECT r; /* Rectangular range corresponding to work region */ } MSG_REQ_START; typedef struct { /* Call termination (process termination) */ MSG_HEAD hd; /* Header part */ ; } MSG_REQ_FINISH; typedef struct { /* Redraw request */ MSG_HEAD hd; /* Header part */ RECT r; /* Redraw region (entire, if empty) */ } MSG_REQ_REDRAW; typedef struct { /* Straight line */ MSG_HEAD hd; /* Header part */ PNT sp; /* Start point */ PNT ep; /* End point */ COLOR col; /* Color (absolute color specification desirable) */ } MSG_REQ_LINE; typedef struct { /* Rectangular frame */ MSG_HEAD hd; /* Header part */ RECT r; /* Rectangular shape range */ COLOR col; /* Color (absolute color specification desirable) */ } MSG_REQ_BOX; typedef struct { /* Circle/ellipse */ MSG_HEAD hd; /* Header part */ RECT r; /* Rectangular region (external connect) */ COLOR col; /* Color (absolute color specification desirable) */ } MSG_REQ_CIRCLE; typedef struct { MSG_HEAD hd; /* Header part */ PNT p; /* Drawing start point (upper left) */ COLOR col; /* Color (absolute color specification desirable) */ TC str[1]; /* Character string (Actually, variable length/TNULL terminus) */ } MSG_REQ_TEXT; typedef union { /* Union */ MSG_REQ_START start; MSG_REQ_FINISH finish; MSG_REQ_REDRAW redraw; MSG_REQ_LINE line; MSG_REQ_BOX box; MSG_REQ_CIRCLE circle; MSG_REQ_TEXT text; } MSG_REQ; /* ------------------------------------------------------------------ Replies */ enum MSGTYPE_RSP { /* Classification numbers of replies */ MSGTYPE_RSP_NORMAL = 0x00020001 }; typedef struct { /* Normal reply */ MSG_HEAD hd; /* Header part */ ERR er; /* Error code */ } MSG_RSP_NORMAL; typedef union { /* Union */ MSG_RSP_NORMAL normal; } MSG_RSP; #endif /* _PROG_4_MSG_H */ -------------------- /* * prog_4-proto.h (T-Shell Sample/Global Function Prototype Declarations) * * (C) Copyright 2003 by Personal Media Corporation. */ #ifndef _PROG_4_PROTO_H #define _PROG_4_PROTO_H /* from main.c */ /* from evt.c */ IMPORT WERR event_loop(VOID); /* from rcvmsg.c */ IMPORT ERR recv_main(const MSG_ANY *dmy); /* from sndmsg.c */ IMPORT ERR send_rsp_normal(W pid, ERR err); /* from draw.c */ IMPORT ERR draw_init(VOID); IMPORT VOID draw_fin(VOID); IMPORT ERR draw_gen_workarea(W pgid, RECT r); IMPORT ERR draw_redraw(RECT r); IMPORT ERR draw_line(PNT sp, PNT ep, COLOR col); IMPORT ERR draw_box(RECT r, COLOR col); IMPORT ERR draw_circle(RECT r, COLOR col); IMPORT ERR draw_text(PNT p, COLOR col, const TC *str); #endif /* _PROG_4_PROTO_H */ -------------------- /* * prog_4-rcvmsg.c (T-Shell Sample/Message Reception Processing Part) * * (C) Copyright 2003 by Personal Media Corporation. */ #include "sample.h" /* Internal type declarations */ typedef struct { /* Request processing function table */ UW type; /* Request classifications */ FUNCP fn; /* Execution functions */ } RCVFN; /* Internal function prototypes */ LOCAL ERR req_start(W pid, const MSG_REQ *msg); LOCAL ERR req_finish(W pid, const MSG_REQ *msg); LOCAL ERR req_redraw(W pid, const MSG_REQ *msg); LOCAL ERR req_line(W pid, const MSG_REQ *msg); LOCAL ERR req_box(W pid, const MSG_REQ *msg); LOCAL ERR req_circle(W pid, const MSG_REQ *msg); LOCAL ERR req_test(W pid, const MSG_REQ *msg); /* Request processing functions table */ LOCAL RCVFN rcvfn_tbl[] = { {MSGTYPE_REQ_START, req_start}, {MSGTYPE_REQ_FINISH, req_finish}, {MSGTYPE_REQ_REDRAW, req_redraw}, {MSGTYPE_REQ_LINE, req_line}, {MSGTYPE_REQ_BOX, req_box}, {MSGTYPE_REQ_CIRCLE, req_circle}, {MSGTYPE_REQ_TEXT, req_test}, {0xffffffff, NULL} /* Terminus */ }; /* ---------------------------------------------------------------- Internal functions */ /* * Call start */ LOCAL ERR req_start(W pid, const MSG_REQ *msg) { ERR er; W cnt; W wid; W gid; printf("req_start()\n"); er = ER_OK; /* Acquire window ID of window possessing request source process */ cnt = b_wlst_wnd(-pid, 1, &wid); if (cnt < ER_OK) { er = cnt; printf("b_wlst_wnd : %d, %d\n", er, er >> 16); goto EXIT; } printf("process ID : %d window ID : %d\n", pid, wid); /* Acquire drawing environment ID */ gid = b_wget_gid(wid); if (gid < ER_OK) { er = gid; printf("b_wget_gid : %d, %d\n", er, er >> 16); goto EXIT; } printf("gid : %d\n", gid); /* Creation of work region */ er = draw_gen_workarea(gid, msg->start.r); if (er < ER_OK) { printf("draw_gen_workarea : %d, %d\n", er, er >> 16); } EXIT: /* Reply */ send_rsp_normal(pid, er); return er; } /* * Call termination */ LOCAL ERR req_finish(W pid, const MSG_REQ *msg) { printf("req_finish()\n"); /* Event loop termination */ doloop = False; /* Reply */ send_rsp_normal(pid, ER_OK); return (ER_OK); /* Usually, ER_OK */ } /* * Redraw request */ LOCAL ERR req_redraw(W pid, const MSG_REQ *msg) { ERR er; /* printf("req_redraw()\n"); */ /* Execute redraw */ er = draw_redraw(msg->redraw.r); /* Reply */ send_rsp_normal(pid, er); return er; } /* * Draw straight line */ LOCAL ERR req_line(W pid, const MSG_REQ *msg) { ERR er; printf("req_line()\n"); /* Execute drawing */ er = draw_line(msg->line.sp, msg->line.ep, msg->line.col); /* Reply */ send_rsp_normal(pid, er); return er; } /* * Draw rectangular frame */ LOCAL ERR req_box(W pid, const MSG_REQ *msg) { ERR er; printf("req_box()\n"); /* Execute drawing */ er = draw_box(msg->box.r, msg->box.col); /* Reply */ send_rsp_normal(pid, er); return er; } /* * Draw circle/ellipse */ LOCAL ERR req_circle(W pid, const MSG_REQ *msg) { ERR er; printf("req_circle()\n"); /* `Execute drawing */ er = draw_circle(msg->circle.r, msg->circle.col); /* Reply */ send_rsp_normal(pid, er); return er; } /* * Draw character string */ LOCAL ERR req_test(W pid, const MSG_REQ *msg) { ERR er; W len; printf("req_test()\n"); /* Execute drawing */ er = draw_text(msg->text.p, msg->text.col, msg->text.str); /* Reply */ send_rsp_normal(pid, er); return er; } /* -------------------------------------------------------------- Main processes */ /* * Message main reception * * Here, messages are erased without fail */ EXPORT ERR recv_main(const MSG_ANY *dmy) { ERR er; W l; W pid; W msize; MSG_ANY *msg; er = ER_OK; msg = NULL; /* Securing the region */ msize = dmy->hd.msg_size + offsetof(MSG_HEAD, ext_size); msg = (MSG_ANY *)(malloc(msize)); if (msg == NULL) { er = ER_NOMEM; printf("memory allocation error.\n"); b_clr_msg(MM_ALL, MM_ALL); /* Message erased */ goto EXIT; } /* Reception (reception in erasure) */ pid = b_rcv_msg(MSGMASK(dmy->hd.msg_type), (MESSAGE*)(msg), msize, NOWAIT | CLR); if (pid < ER_OK) { er = pid; printf("b_rcv_msg : %d, %d\n", er, er >> 16); b_clr_msg(MM_ALL, MM_ALL); /* Message erased */ goto EXIT; } /* Branch in received contents */ for (l = 0; rcvfn_tbl[l].type != 0xffffffff; l++) { if (rcvfn_tbl[l].type == msg->hd.type) { if (rcvfn_tbl[l].fn != NULL) { er = (rcvfn_tbl[l].fn)(pid, (const MSG_REQ *)(msg)); } break; } } EXIT: if (msg != NULL) { free(msg); } return er; } -------------------- /* * prog_4-sample.h (T-Shell Sample/Common Header) * * (C) Copyright 2003 by Personal Media Corporation. */ #ifndef _PROG_4_SAMPLE_H #define _PROG_4_SAMPLE_H #include <basic.h> #include <btron/outer.h> #include <btron/dp.h> #include <tcode.h> #include <stdio.h> #include <stdlib.h> #include <tlang.h> #include <tstring.h> /* Message definition */ #include "msg.h" /* Global variable */ #include "gval.h" /* Global function prototype */ #include "proto.h" #endif /* _PROG_4_SAMPLE_H */ -------------------- /* * prog_4-sndmsg.c (T-Shell Sample/Message Transmissions) * * (C) Copyright 2003 by Personal Media Corporation. */ #include "sample.h" /* Internal function prototypes */ LOCAL ERR send_mesg(W pid, MSG_ANY *msg, UW type); /* ---------------------------------------------------------------- Internal functions */ /* * Transmit message */ LOCAL ERR send_mesg(W pid, MSG_ANY *msg, UW type) { ERR er; er = ER_OK; /* Write in header part */ msg->hd.msg_type = SMPL_MSGTYPE; msg->hd.ext_size = 0; /* Usually, 0 */ msg->hd.magic[0] = MSG_MAGIC0; msg->hd.magic[1] = MSG_MAGIC1; msg->hd.magic[2] = MSG_MAGIC2; msg->hd.magic[3] = MSG_MAGIC3; msg->hd.type = type; /* Message transmission */ er = b_snd_msg(pid, (MESSAGE *)(msg), NOWAIT); if (er < ER_OK) { printf("b_snd_msg : %d, %d\n", er, er >> 16); } return er; } /* -------------------------------------------------------------- Main processes */ /* * Transmit normal response */ EXPORT ERR send_rsp_normal(W pid, ERR err) { ERR er; MSG_RSP_NORMAL msg; er = ER_OK; /* Prepare contents */ msg.er = err; msg.hd.msg_size = sizeof(MSG_RSP_NORMAL) - offsetof(MSG_HEAD,ext_size); /* Transmission */ er = send_mesg(pid, (MSG_ANY *)(&msg), MSGTYPE_RSP_NORMAL); if (er < ER_OK) { printf("send_mesg : %d, %d\n", er, er >> 16); } return er; } -------------------- # # @(#)Makefile (prog_4) # For use with GNU make # # make method # make # Create release use regular version # make mode=debug # Create for use in debugging # make clean # Delete all files created with make # make install # Install in the prescribed place (for actual machine use only) # # Version version = 0x1000 # Set release use to default #mode = # Source dependencies-related file (automatically created) DEPS = Dependencies DEPENDENCIES_OUTPUT := $(DEPS) # Application standard rules include $(BD)/bappl/etc/makerules # ---------------------------------------------------------------------------- # Create target TARGET = prog_4 # Search path of source files S = ./ ../src VPATH = $(S) # Header file directory addition HEADER := $(S) $(HEADER) # Source files SRC = main.c \ evt.c \ rcvmsg.c \ sndmsg.c \ draw.c OBJ = $(addsuffix .o, $(basename $(SRC))) WC_SRC = $(filter %.C, $(SRC)) DBFLAGS += -l ifeq ($(mode), debug) CFLAGS += -Wall endif # ---------------------------------------------------------------------------- .PHONY: all clean INST = $(addprefix $(TARGET), .bz .map) INST2 = $(addprefix $(TARGET), .out) all: $(INST) $(TARGET).out: $(OBJ) $(LINK.o) $(LDOBJS) $^ $(LOADLIBES) $(LDLIBS) $(OUTPUT_OPTION) clean: $(RM) $(OBJ) $(RM) $(WC_SRC:%.C=%.c) $(DBSRC) $(RM) $(INST) $(INST2) *.lst $(DEPS) # Compression archive $(TARGET).bz: $(INST2) $(CP) $(TARGET).out _t $(STRIP) _t $(MKBTF) -o$@ -a0x8003 -c -tprog_4 \ 9.$(CPU_TYPE)._t $(RM) _t # Source dependencies related $(WC_SRC:%.C=%.c): ifdef DEPENDENCIES_OUTPUT $(DEPS): ; touch $(DEPS) else $(DEPS): $(SRC) ; $(MAKEDEPS) $@ $? endif include $(DEPS) |
ReadMe |
The sample programs are recorded in the directory configuration below. tshell83/ prog_1/ : b_rcv_msg() (used in parallel with prog_2) prog_2/ : b_snd_msg() (used in parallel with prog_1) prog_3/ : b_rcv_msg() (receives things transmitted from MSCRIPT) prog_4/ : Example that cooperates with MSCRIPT prog_m.bpk : Sample program in MSCRIPT (Packing Box) Furthermore, because prog_m.bpk is made up in packing box format, please decompress it by means of BPACK (Book Packer) by taking out conversion file as a packing box with the File Converter on top of Cho Kanji, etc. When decompressed, a real object called prog_m will be created, in which the the contents below are recorded. prog_m prog_m1 : Example that realizes parts in MSCRIPT prog_m2 : MSEND (transmits messages vis-à-vis prog_3) prog_m3 : Example that cooperates with MSCRIPT (used in parallel with prog_4) From prog_1/ through prog_4/, on the development host, please carry out compile matched to the CPU of the T-Engine you will use. From prog_m1 through prog_m3, please copy as real objects onto disk, etc., on which you have installed T-Shell the things in which the respective formats are made up as scripts, and then execute them on top of T-Shell. |
____________________
[1] In this example, because we have decided on a state during a pointer press, we have implemented an event loop during pressing. In MicroScript, because it is also possible to describe in a manner in which processing is executed in cases where a segment has been clicked, if we use this, it will come about that we will be finished with the present program of several lines.
[2] Here, we have made a program based on MicroScript and C language the subject, but cooperation based on inter-process messaging is also used even with C language-based programs themselves, and thus it is a method of very high general purposeness.
[3] Furthermore, concerning synchronization and cooperation among processes, outside of inter-process messaging in PMC T-Kernel Extension that we take up on this occasion, functions such as semaphore, event flag, mailbox (message buffer), and rendezvous, which are frequently used with T-Kernel and ITRON, are also provided.
[4] In doing b_snd_msg(), it is necessary to know the process ID of the transmission target. Here, in prog_1 of the receiving side, we store the process ID of the self process in the global name [prog_1]. In prog_2 of the transmitting side, we make it so that we use the value obtained from this global name as the process ID of the transmission target.
[5] Outside of this, because MicroScript cannot freely handle a drawing environment, it also cannot acquire currently displayed screen contents.
[6] The message types that can be handled with MicroScript are in the form of the eight types from MS_TYPE0 to MS_TYPE7. As for the message types we can specify with the MSEND statement, they are the values from 0 to 7, and we specify the values of this range with anything from MS_TYPE0 up to MS_TYPE7.
[7] Because structures cannot be handled in MicroScript, this becomes a simple byte string. For that reason, paying attention to the CPU endian and alignment is necessary.
[8] When transmitting with the MSEND statement, MESSAGE.msg_type, MESSAGE.msg_size, and MESSAGE.msg_body are specified as respectively different arguments. For that reason, inside the main body of the message we want to transmit, contents corresponding to MESSAGE.msg_type and MESSAGE.msg_size must not be included (we specify only contents corresponding to MESSAGE.msg_body).
[9] For the contents of the structure that transmits and receives, please refer to the source of the sample program that is recorded on the CD-ROM.
[10] In this example, as differs with the previous, in b_cre_nam(), it has become the N_CREATE specification. In this case, if something with the same name already exists, b_cre_nam() becomes an error, but there are cases where this is used for the purpose avoiding duplicating and starting up the same application.
[11] Accurately, these are things that are arranged as segments; in actuality, it is not a case in which we are arranging parts called buttons and selectors. In MicroScript, by skillfully operating these segments, we implement in a manner in which they behave as parts.
[12] By means of the PROCESS statement, it is also possible to start up the process at the cooperation destination from MicroScript. However, please be careful, because we have to switch the binary that should start up for the CPU of the T-Engine we will use.
[TN] All the programs loaded on the CD-ROM mentioned here have been translated and appear at the end of this article. The interface parts of the MicroScript programs are shown below together with prog_m2, which has no interface parts. These were packed in the prog_m.bpk file.
Reference Documentation
[1] Sakamura, Ken Gen. Ed.; PMC Institute Ed.: Maikurosukuriputo nyuumon [An Introduction to BTRON MicroScript] , Personal Media Corp., 1999. (ISBN4-89362-160-2)
[2] Sakamura, Ken Gen. Ed.; PMC Institute Ed.: BTRON Maikurosukuriputo [BTRON MicroScript Reference Manual], Personal Media Corp., 1997. (ISBN4-89362-155-6)
The above article on PMC T-Shell appeared on pages 32-40 in Vol. 83 of TRONWARE . It was translated and loaded onto this Web page with the permission of Personal Media Corporation.
Copyright © 2003 Personal Media Corporation
Copyright © 2008 Sakamura Laboratory, University Museum, University of Tokyo