Skip to content
This repository was archived by the owner on Feb 5, 2025. It is now read-only.

Commit 2579b72

Browse files
committed
fix: memory leak
1 parent 22ebf4b commit 2579b72

File tree

12 files changed

+102
-66
lines changed

12 files changed

+102
-66
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/pre-commit/mirrors-clang-format
3-
rev: v17.0.2
3+
rev: v17.0.3
44
hooks:
55
- id: clang-format
66
types_or: [c++, c]
@@ -19,7 +19,7 @@ repos:
1919
- id: cpplint
2020

2121
- repo: https://github.com/crate-ci/typos
22-
rev: v1.16.20
22+
rev: typos-dict-v0.11.2
2323
hooks:
2424
- id: typos
2525
args:

.vscode/launch.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
"servertype": "external",
1616
"preLaunchTask": "Launch OpenOCD",
1717
"gdbTarget": "${env:WSL2_HOST_IP}:3333",
18+
"preLaunchCommands": [
19+
"monitor arm semihosting enable",
20+
],
1821
}
1922
]
2023
}

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@
3737
"$gcc"
3838
],
3939
}
40-
]
40+
],
4141
}

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
# Build global options
33
# NOTE: Can be overridden externally.
44
#
5+
SEMIHOSTING_OPT = --specs=rdimon.specs -lc -lrdimon
56

67
ifeq ($(APP),)
78
APP = default
89
endif
910

1011
# Compiler options here.
1112
ifeq ($(USE_OPT),)
12-
USE_OPT = -Og -ggdb -fomit-frame-pointer -falign-functions=16
13+
USE_OPT = -Og -ggdb -fomit-frame-pointer -falign-functions=16 $(SEMIHOSTING_OPT)
1314
endif
1415

1516
# C specific options here (added to USE_OPT).

apps/blus_mini/blus_mini.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@
1616
#include "chprintf.h"
1717
#include "tas2780.h"
1818

19-
/**
20-
* @brief Global stream pointer for print messages.
21-
*/
22-
static BaseSequentialStream *gp_stream = (BaseSequentialStream *)&SD2;
23-
2419
/**
2520
* @brief Settings structure for the TAS2780 I2C driver.
2621
*/
@@ -70,32 +65,31 @@ static THD_FUNCTION(housekeeping_thread, arg) {
7065
chRegSetThreadName("reporting");
7166

7267
while (true) {
68+
tas2780_acquire_lock();
7369
tas2780_ensure_active_all();
70+
tas2780_release_lock();
7471

75-
chBSemWait(&g_stream_lock);
7672
chSysLock();
77-
size_t buffer_fill_size = audio_playback_get_buffer_fill_size();
78-
size_t feedback_value = audio_feedback_get_value();
79-
size_t playback_state = audio_playback_get_state();
73+
// size_t buffer_fill_size = audio_playback_get_buffer_fill_size();
74+
// size_t feedback_value = audio_feedback_get_value();
75+
// size_t playback_state = audio_playback_get_state();
8076
chSysUnlock();
8177

8278
// Disable extended reporting statistics.
8379
#if 0
8480
uint8_t noise_gate_mask = tas2780_get_noise_gate_mask_all();
85-
chprintf(gp_stream, "Noise gate: %u\n", noise_gate_mask);
81+
PRINTF("Noise gate: %u\n", noise_gate_mask);
8682

87-
chprintf(gp_stream, "Potentiometer: %u\n",
83+
PRINTF("Potentiometer: %u\n",
8884
g_adc_sample >> 4); // Convert to an 8 bit number.
8985

90-
chprintf(gp_stream, "Volume: %li / %li dB\n",
86+
PRINTF("Volume: %li / %li dB\n",
9187
(audio_request_get_channel_volume(AUDIO_COMMON_CHANNEL_LEFT) >> 8),
9288
(audio_request_get_channel_volume(AUDIO_COMMON_CHANNEL_RIGHT) >> 8));
9389
#endif
9490

95-
chprintf(gp_stream, "Buffer: %lu / %lu (fb %lu) @ state %lu\n", buffer_fill_size, AUDIO_MAX_BUFFER_SIZE,
96-
feedback_value, playback_state);
97-
98-
chBSemSignal(&g_stream_lock);
91+
// PRINTF("Buffer: %u / %u (fb %u) @ state %u\n", buffer_fill_size, AUDIO_MAX_BUFFER_SIZE, feedback_value,
92+
// playback_state);
9993

10094
chThdSleepMilliseconds(500);
10195
}
@@ -107,7 +101,12 @@ static THD_FUNCTION(housekeeping_thread, arg) {
107101
void app_setup(void) {
108102
// Setup amplifiers.
109103
i2cStart(&I2CD1, &g_tas2780_i2c_config);
104+
105+
tas2780_init();
106+
107+
tas2780_acquire_lock();
110108
tas2780_setup_all();
109+
tas2780_release_lock();
111110

112111
// Begin reading volume potentiometer ADC.
113112
app_start_volume_adc();
@@ -128,6 +127,7 @@ static void app_set_volume_and_mute_state(void) {
128127
int16_t right_channel_volume = audio_request_get_channel_volume(AUDIO_COMMON_CHANNEL_RIGHT);
129128
chSysUnlock();
130129

130+
tas2780_acquire_lock();
131131
if (b_left_channel_is_muted) {
132132
tas2780_set_volume_all(TAS2780_VOLUME_MUTE, TAS2780_CHANNEL_LEFT);
133133
} else {
@@ -139,6 +139,7 @@ static void app_set_volume_and_mute_state(void) {
139139
} else {
140140
tas2780_set_volume_all(right_channel_volume, TAS2780_CHANNEL_RIGHT);
141141
}
142+
tas2780_release_lock();
142143
}
143144

144145
/**

source/audio/audio.c

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,8 @@
1414

1515
#include <string.h>
1616

17-
#include "chprintf.h"
1817
#include "common.h"
19-
20-
/**
21-
* @brief Global stream pointer for print messages.
22-
*/
23-
static BaseSequentialStream *gp_stream = (BaseSequentialStream *)&SD2;
18+
#include "print.h"
2419

2520
/**
2621
* @brief The number of audio messages that can be held.
@@ -165,7 +160,7 @@ static void audio_update_sample_rate(void) {
165160
g_i2s_config.i2spr = AUDIO_SPI_GET_I2SPR(sample_rate_hz);
166161
}
167162

168-
static THD_WORKING_AREA(wa_audio_thread, 128);
163+
static THD_WORKING_AREA(wa_audio_thread, 256u);
169164

170165
/**
171166
* @brief A thread that handles audio-related tasks.
@@ -192,9 +187,7 @@ static THD_FUNCTION(audio_thread, arg) {
192187

193188
switch (message) {
194189
case AUDIO_COMMON_MSG_START_PLAYBACK:
195-
chBSemWait(&g_stream_lock);
196-
chprintf(gp_stream, "### Start playback.\n");
197-
chBSemSignal(&g_stream_lock);
190+
PRINTF("### Start playback.\n");
198191

199192
// Set volumes to the values configured via USB audio.
200193
audio_send_app_message(AUDIO_COMMON_MSG_SET_VOLUME);
@@ -205,9 +198,7 @@ static THD_FUNCTION(audio_thread, arg) {
205198
break;
206199

207200
case AUDIO_COMMON_MSG_STOP_PLAYBACK:
208-
chBSemWait(&g_stream_lock);
209-
chprintf(gp_stream, "### Stop playback.\n");
210-
chBSemSignal(&g_stream_lock);
201+
PRINTF("### Stop playback.\n");
211202

212203
audio_feedback_stop_sof_capture();
213204
i2sStopExchange(&I2S_DRIVER);
@@ -217,9 +208,7 @@ static THD_FUNCTION(audio_thread, arg) {
217208
break;
218209

219210
case AUDIO_COMMON_MSG_SET_SAMPLE_RATE:
220-
chBSemWait(&g_stream_lock);
221-
chprintf(gp_stream, "### Set sample rate.\n");
222-
chBSemSignal(&g_stream_lock);
211+
PRINTF("### Set sample rate.\n");
223212

224213
chSysLock();
225214
audio_update_sample_rate();

source/audio/audio_request.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static volatile struct audio_request_message {
4343
uint16_t value; ///< The wValue field of the request.
4444
uint16_t index; ///< The wIndex field of the request.
4545
uint16_t length; ///< The valid data length.
46-
uint8_t data[8u]; ///< The data buffer.
46+
uint8_t data[1024u]; ///< The data buffer.
4747
} g_request;
4848

4949
/**
@@ -398,6 +398,8 @@ bool audio_request_hook_cb(USBDriver *p_usb) {
398398
g_request.index = ((p_usb->setup[5] << 8) | p_usb->setup[4]);
399399
g_request.length = ((p_usb->setup[7] << 8) | p_usb->setup[6]);
400400

401+
chDbgAssert(g_request.length <= ARRAY_LENGTH(g_request.data), "Request data buffer exceeded.");
402+
401403
switch (g_request.request_type & USB_RTYPE_TYPE_MASK) {
402404
case USB_RTYPE_TYPE_STD:
403405
return audio_request_handle_standard(p_usb);

source/common.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,6 @@ __STATIC_INLINE size_t add_circular_unsigned(size_t summand_a, size_t summand_b,
127127
return wrap_unsigned(summand_a + summand_b, max_value);
128128
}
129129

130-
/**
131-
* @brief A lock for the stream that is used for printing messages, defined in the \a main module.
132-
*/
133-
extern binary_semaphore_t g_stream_lock;
134-
135130
#endif // SOURCE_COMMON_H_
136131

137132
/**

source/drivers/tas2780/tas2780.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,26 @@
1414
#include "tas2780_registers.h"
1515
#include "tas2780_settings.h"
1616

17+
/**
18+
* @brief The locking semaphore for the TAS2780 module.
19+
*/
20+
static binary_semaphore_t g_bsem;
21+
22+
/**
23+
* @brief Lock the TAS2780 module.
24+
*/
25+
void tas2780_acquire_lock(void) { chBSemWait(&g_bsem); }
26+
27+
/**
28+
* @brief Release the TAS2780 module.
29+
*/
30+
void tas2780_release_lock(void) { chBSemSignal(&g_bsem); }
31+
32+
/**
33+
* @brief Initialize the TAS2780 module.
34+
*/
35+
void tas2780_init(void) { chBSemObjectInit(&g_bsem, false); }
36+
1737
/**
1838
* @brief All amplifier contexts.
1939
* @details Will be set up with settings from \a tas2780_settings.h .

source/drivers/tas2780/tas2780.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,12 @@ struct tas2780_context {
5555
///< is loudest. The range of gains is 10 dB.
5656
};
5757

58+
void tas2780_acquire_lock(void);
59+
void tas2780_release_lock(void);
60+
void tas2780_init(void);
61+
5862
void tas2780_setup_all(void);
5963
void tas2780_set_volume_all(int16_t volume_8q8_db, enum tas2780_channel channel);
60-
void tas2780_init(struct tas2780_context *p_context, uint16_t device_address);
6164
void tas2780_ensure_active_all(void);
6265
uint8_t tas2780_get_noise_gate_mask_all(void);
6366

source/main.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
#include "audio.h"
1919
#include "ch.h"
20-
#include "chprintf.h"
2120
#include "hal.h"
21+
#include "print.h"
2222
#include "usb.h"
2323

2424
/**
@@ -36,16 +36,6 @@ static mailbox_t g_mailbox;
3636
*/
3737
static msg_t g_mailbox_buffer[MESSAGE_BUFFER_LENGTH];
3838

39-
/**
40-
* @brief Global stream pointer for print messages.
41-
*/
42-
static BaseSequentialStream *gp_stream = (BaseSequentialStream *)&SD2;
43-
44-
/**
45-
* @brief A lock for the stream that is used for printing messages.
46-
*/
47-
binary_semaphore_t g_stream_lock;
48-
4939
// Weak definitions that shall be overridden by the user application (if required).
5040

5141
/**
@@ -68,6 +58,11 @@ __WEAK void app_set_volume(void) {}
6858
*/
6959
__WEAK void app_set_mute_state(void) {}
7060

61+
/**
62+
* @brief Semihosting initialization.
63+
*/
64+
extern void initialise_monitor_handles(void);
65+
7166
/**
7267
* @brief Application entry point.
7368
*
@@ -77,6 +72,9 @@ int main(void) {
7772
halInit();
7873
chSysInit();
7974

75+
// Enable semihosting interface.
76+
initialise_monitor_handles();
77+
8078
// Initialize the main thread mailbox that receives audio messages (volume, mute).
8179
chMBObjectInit(&g_mailbox, g_mailbox_buffer, ARRAY_LENGTH(g_mailbox_buffer));
8280

@@ -86,14 +84,10 @@ int main(void) {
8684
// Initialize the USB module.
8785
usb_setup();
8886

89-
chBSemObjectInit(&g_stream_lock, false);
90-
9187
// Initialize a stream for print messages.
9288
sdStart(&SD2, NULL);
9389

94-
chBSemWait(&g_stream_lock);
95-
chprintf(gp_stream, "### Starting USB-I2S bridge.\n");
96-
chBSemSignal(&g_stream_lock);
90+
PRINTF("### Starting USB-I2S bridge.\n");
9791

9892
// Set up the user application.
9993
app_setup();
@@ -107,30 +101,26 @@ int main(void) {
107101
chSysHalt("Failed to receive message.");
108102
}
109103

110-
chBSemWait(&g_stream_lock);
111-
112104
switch (message) {
113105
case AUDIO_COMMON_MSG_RESET_VOLUME:
114-
chprintf(gp_stream, "### Reset volume.\n");
106+
PRINTF("### Reset volume.\n");
115107
app_reset_volume();
116108
break;
117109

118110
case AUDIO_COMMON_MSG_SET_MUTE_STATE:
119-
chprintf(gp_stream, "### Set mute state.\n");
111+
PRINTF("### Set mute state.\n");
120112
app_set_mute_state();
121113
break;
122114

123115
case AUDIO_COMMON_MSG_SET_VOLUME:
124-
chprintf(gp_stream, "### Set volume.\n");
116+
PRINTF("### Set volume.\n");
125117
app_set_volume();
126118
break;
127119

128120
default:
129121
chSysHalt("Unknown message type.");
130122
break;
131123
}
132-
133-
chBSemSignal(&g_stream_lock);
134124
}
135125
}
136126

source/print.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2023 elagil
2+
3+
/**
4+
* @file
5+
* @brief Printing functionality.
6+
*
7+
* @addtogroup common
8+
* @{
9+
*/
10+
11+
#ifndef SOURCE_PRINT_H_
12+
#define SOURCE_PRINT_H_
13+
14+
#include <stdarg.h>
15+
16+
#include "chprintf.h"
17+
#include "common.h"
18+
19+
/**
20+
* @brief Generic print function, which can perform different functions.
21+
*
22+
* @param fmt Format specifier.
23+
* @param ... Additional arguments.
24+
*/
25+
static inline void PRINTF(const char* fmt, ...) {
26+
va_list args;
27+
va_start(args, fmt);
28+
chvprintf((BaseSequentialStream*)&SD2, fmt, args);
29+
va_end(args);
30+
}
31+
32+
#endif // SOURCE_PRINT_H_

0 commit comments

Comments
 (0)