Skip to content

Commit 8921ed0

Browse files
committed
hal_struct: add man3 pages and halcmd show/list struct support
- docs/man/man3/hal_struct_newf.3: full man page for hal_struct_newf, hal_struct_attach, hal_struct_detach with SYNOPSIS, ARGUMENTS, DESCRIPTION, RETURN VALUE, EXAMPLE, and SEE ALSO sections - hal_struct_attach.3, hal_struct_detach.3: .so redirects to main page - halcmd_commands.cc: add print_struct_info() and print_struct_names() following the print_param_info/print_thread_info pattern; wire into do_show_cmd (show struct, bare show, show all) and do_list_cmd - halcmd_completion.c: add "struct" to show_table and list_table
1 parent cf54273 commit 8921ed0

5 files changed

Lines changed: 189 additions & 2 deletions

File tree

docs/man/man3/hal_struct_attach.3

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.so man3/hal_struct_newf.3

docs/man/man3/hal_struct_detach.3

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.so man3/hal_struct_newf.3

docs/man/man3/hal_struct_newf.3

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
'\" t
2+
.\" Title: hal_struct_newf
3+
.\" Author: LinuxCNC contributors
4+
.\" Manual: LinuxCNC Documentation
5+
.\" Source: LinuxCNC
6+
.\" Language: English
7+
.\"
8+
.TH "HAL_STRUCT_NEWF" "3" "2026" "LinuxCNC" "LinuxCNC Documentation"
9+
.ie \n(.g .ds Aq \(aq
10+
.el .ds Aq '
11+
.nh
12+
.ad l
13+
.SH "NAME"
14+
hal_struct_newf, hal_struct_attach, hal_struct_detach \- named opaque blobs in HAL shared memory
15+
.SH "SYNTAX"
16+
.sp
17+
int hal_struct_newf(int \fIcomp_id\fR, long int \fIsize\fR, const void *\fIdefval\fR, const char *\fIfmt\fR, \fI\&...\fR)
18+
.sp
19+
int hal_struct_attach(const char *\fIname\fR, void **\fImemptr\fR)
20+
.sp
21+
int hal_struct_detach(const char *\fIname\fR)
22+
.SH "ARGUMENTS"
23+
.PP
24+
\fIcomp_id\fR
25+
.RS 4
26+
A HAL component identifier returned by an earlier call to
27+
\fBhal_init\fR(3)\&.
28+
.RE
29+
.PP
30+
\fIsize\fR
31+
.RS 4
32+
The number of bytes to allocate in HAL shared memory for the data blob\&.
33+
.RE
34+
.PP
35+
\fIdefval\fR
36+
.RS 4
37+
A pointer to an initialiser of \fIsize\fR bytes that is copied into the
38+
newly allocated blob\&. If NULL the blob is zero-initialised\&.
39+
.RE
40+
.PP
41+
\fIfmt, \&...\fR
42+
.RS 4
43+
A printf-style format string and arguments that form the name of the entry\&.
44+
The resulting name must be no longer than HAL_NAME_LEN characters\&.
45+
.RE
46+
.PP
47+
\fIname\fR
48+
.RS 4
49+
The name of the struct entry to find, as passed to \fBhal_struct_newf\fR\&.
50+
.RE
51+
.PP
52+
\fImemptr\fR
53+
.RS 4
54+
Address of a pointer that will be set to point at the data blob on success\&.
55+
.RE
56+
.SH "DESCRIPTION"
57+
.sp
58+
HAL struct entries are named, reference-counted opaque blobs that live in HAL
59+
shared memory\&. They occupy a separate namespace from pins, signals, and
60+
parameters and are therefore not visible in
61+
.B halcmd show pin
62+
or
63+
.B halcmd show param
64+
output\&. Use
65+
.B halcmd show struct
66+
to inspect them\&.
67+
.sp
68+
\fBhal_struct_newf\fR allocates \fIsize\fR bytes from HAL shared memory,
69+
optionally initialises the region from \fIdefval\fR (or zeroes if NULL), and
70+
registers it under the printf-formatted name\&. The function must be called
71+
before \fBhal_ready\fR(3)\&. There is no corresponding delete function; the
72+
data lives for the lifetime of the HAL shared memory block\&. The entry
73+
metadata is reclaimed automatically when the owning component calls
74+
\fBhal_exit\fR(3)\&.
75+
.sp
76+
\fBhal_struct_attach\fR finds the entry by name, increments its reference
77+
count, and stores a pointer to the data blob in \fI*memptr\fR\&. It may be
78+
called from both realtime and userspace contexts after \fBhal_init\fR(3)\&.
79+
.sp
80+
\fBhal_struct_detach\fR decrements the reference count\&. Calling it when the
81+
reference count is already zero is an error\&. The data is not freed\&.
82+
.SH "RETURN VALUE"
83+
.sp
84+
All three functions return 0 on success\&. On failure they return a negative
85+
HAL status code:
86+
.PP
87+
\fB\-EINVAL\fR
88+
.RS 4
89+
Bad argument, duplicate name (newf), component is already ready (newf), or
90+
detach underflow (detach)\&.
91+
.RE
92+
.PP
93+
\fB\-ENOMEM\fR
94+
.RS 4
95+
Name too long, or HAL shared memory exhausted\&.
96+
.RE
97+
.PP
98+
\fB\-ENOENT\fR
99+
.RS 4
100+
No entry with the given name found (attach or detach)\&.
101+
.RE
102+
.SH "EXAMPLE"
103+
.sp
104+
RT side (in \fIrtapi_app_main\fR):
105+
.sp
106+
.nf
107+
typedef struct { double value; int count; } my_params_t;
108+
static my_params_t *params;
109+
110+
my_params_t defaults = { 1\&.0, 0 };
111+
if (hal_struct_newf(comp_id, sizeof(*params), &defaults,
112+
"%s\&.params", prefix) < 0)
113+
return \-1;
114+
if (hal_struct_attach(prefix ".params", (void **)&params) < 0)
115+
return \-1;
116+
.fi
117+
.sp
118+
Userspace side:
119+
.sp
120+
.nf
121+
my_params_t *params;
122+
if (hal_struct_attach("mycomp\&.params", (void **)&params) < 0)
123+
return \-1;
124+
/* read params\->value, params\->count ... */
125+
hal_struct_detach("mycomp\&.params");
126+
.fi
127+
.SH "SEE ALSO"
128+
.sp
129+
\fBhal_init\fR(3), \fBhal_malloc\fR(3), \fBhal_exit\fR(3), \fBhalcmd\fR(1)

src/hal/utils/halcmd_commands.cc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ static void print_script_sig_info(int type, char **patterns);
6868
static void print_param_info(int type, char **patterns);
6969
static void print_funct_info(char **patterns);
7070
static void print_thread_info(char **patterns);
71+
static void print_struct_info(char **patterns);
72+
static void print_struct_names(char **patterns);
7173
static void print_comp_names(char **patterns);
7274
static void print_pin_names(char **patterns);
7375
static void print_sig_names(char **patterns);
@@ -1022,6 +1024,7 @@ int do_show_cmd(char *type, char **patterns)
10221024
print_param_aliases(NULL);
10231025
print_funct_info(NULL);
10241026
print_thread_info(NULL);
1027+
print_struct_info(NULL);
10251028
} else if (strcmp(type, "all") == 0) {
10261029
/* print everything, using the pattern */
10271030
print_comp_info(patterns);
@@ -1032,6 +1035,7 @@ int do_show_cmd(char *type, char **patterns)
10321035
print_param_aliases(patterns);
10331036
print_funct_info(patterns);
10341037
print_thread_info(patterns);
1038+
print_struct_info(patterns);
10351039
} else if (strcmp(type, "comp") == 0) {
10361040
print_comp_info(patterns);
10371041
} else if (strcmp(type, "pin") == 0) {
@@ -1055,6 +1059,8 @@ int do_show_cmd(char *type, char **patterns)
10551059
print_funct_info(patterns);
10561060
} else if (strcmp(type, "thread") == 0) {
10571061
print_thread_info(patterns);
1062+
} else if (strcmp(type, "struct") == 0) {
1063+
print_struct_info(patterns);
10581064
} else if (strcmp(type, "alias") == 0) {
10591065
print_pin_aliases(patterns);
10601066
print_param_aliases(patterns);
@@ -1093,6 +1099,8 @@ int do_list_cmd(char *type, char **patterns)
10931099
print_funct_names(patterns);
10941100
} else if (strcmp(type, "thread") == 0) {
10951101
print_thread_names(patterns);
1102+
} else if (strcmp(type, "struct") == 0) {
1103+
print_struct_names(patterns);
10961104
} else {
10971105
halcmd_error("Unknown 'list' type '%s'\n", type);
10981106
return -1;
@@ -2067,6 +2075,54 @@ static void print_thread_info(char **patterns)
20672075
halcmd_output("\n");
20682076
}
20692077

2078+
static void print_struct_info(char **patterns)
2079+
{
2080+
SHMFIELD(hal_struct_entry_t) next;
2081+
hal_struct_entry_t *entry;
2082+
hal_comp_t *comp;
2083+
2084+
if (scriptmode == 0) {
2085+
halcmd_output("Structs:\n");
2086+
halcmd_output("Owner Refs Name\n");
2087+
}
2088+
rtapi_mutex_get(&(hal_data->mutex));
2089+
next = hal_data->struct_list_ptr;
2090+
while (next != 0) {
2091+
entry = SHMPTR(next);
2092+
if ( match(patterns, entry->name) ) {
2093+
comp = SHMPTR(entry->owner_ptr);
2094+
if (scriptmode == 0) {
2095+
halcmd_output(" %5d %4d %s\n",
2096+
comp->comp_id, entry->attach_count, entry->name);
2097+
} else {
2098+
halcmd_output("%s %d %s\n",
2099+
comp->name, entry->attach_count, entry->name);
2100+
}
2101+
}
2102+
next = entry->next_ptr;
2103+
}
2104+
rtapi_mutex_give(&(hal_data->mutex));
2105+
halcmd_output("\n");
2106+
}
2107+
2108+
static void print_struct_names(char **patterns)
2109+
{
2110+
SHMFIELD(hal_struct_entry_t) next;
2111+
hal_struct_entry_t *entry;
2112+
2113+
rtapi_mutex_get(&(hal_data->mutex));
2114+
next = hal_data->struct_list_ptr;
2115+
while (next != 0) {
2116+
entry = SHMPTR(next);
2117+
if ( match(patterns, entry->name) ) {
2118+
halcmd_output("%s ", entry->name);
2119+
}
2120+
next = entry->next_ptr;
2121+
}
2122+
rtapi_mutex_give(&(hal_data->mutex));
2123+
halcmd_output("\n");
2124+
}
2125+
20702126
static void print_comp_names(char **patterns)
20712127
{
20722128
SHMFIELD(hal_comp_t) next;

src/hal/utils/halcmd_completion.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static const char *alias_table[] = {
6868
};
6969

7070
static const char *show_table[] = {
71-
"all", "alias", "comp", "pin", "sig", "param", "funct", "thread",
71+
"all", "alias", "comp", "pin", "sig", "param", "funct", "thread", "struct",
7272
NULL,
7373
};
7474

@@ -78,7 +78,7 @@ static const char *save_table[] = {
7878
};
7979

8080
static const char *list_table[] = {
81-
"comp", "alias", "pin", "sig", "param", "funct", "thread",
81+
"comp", "alias", "pin", "sig", "param", "funct", "thread", "struct",
8282
NULL
8383
};
8484

0 commit comments

Comments
 (0)