Skip to content

Timer thread stack size too small for Berry on BK7231N #1663

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
niteria opened this issue May 31, 2025 · 0 comments
Open

Timer thread stack size too small for Berry on BK7231N #1663

niteria opened this issue May 31, 2025 · 0 comments

Comments

@niteria
Copy link
Contributor

niteria commented May 31, 2025

Symptoms / reproduction steps

Create a demo_module.be file (same as [1]) with contents:

# simple module
# use `import demo_module`

demo_module = module("demo_module")

demo_module.foo = "bar"

demo_module.say_hello = def ()
	print("Hello Berry!")
end

return demo_module      # return the module as the output of import

Running berry import demo_module will work correctly, but addRepeatingEvent 1 1 berry import demo_module will crash the device.

Diagnosis

berry import demo_module and addRepeatingEvent 1 1 berry import demo_module run in different RTOS threads.

One is a http handler thread with stack size defined here:

#define HTTP_CLIENT_STACK_SIZE 8192

Another runs inside QuickTick (

void QuickTick(void* param)
) as a timer:
QuickTick,

The stack size for timers on BK7231N is defined here: https://github.com/openshwprojects/OpenBK7231N/blob/2a61aa189bad9c0120eb636b00bb12cfbb03dd95/platforms/bk7231n/bk7231n_os/beken378/os/include/FreeRTOSConfig.h#L88

Changing configTIMER_TASK_STACK_DEPTH to ( ( unsigned short ) (6000 / sizeof( portSTACK_TYPE )) ) allows addRepeatingEvent 1 1 berry import demo_module to run without crashing.

Helpful notes

The way I debugged this was by querying RTOS for current thread's stack size.

I've added these lines to bool berryRun(bvm *vm, const char *prog):

UBaseType_t highWaterMark = uxTaskGetStackHighWaterMark(NULL);
ADDLOG_INFO(LOG_FEATURE_BERRY, "berryRun Current task minimum free stack: %u words\n", (unsigned int)highWaterMark);

uxTaskGetStackHighWaterMark is not available by default. I needed to add this line to platforms/bk7231n/bk7231n_os/beken378/os/include/FreeRTOSConfig.h:

#define INCLUDE_uxTaskGetStackHighWaterMark 1

In the case of berry import demo_module I got this output:

Info:BERRY:berryRun Current task minimum free stack: 1784 words

and for addRepeatingEvent 1 1 berry import demo_module I got:

Info:BERRY:berryRun Current task minimum free stack: 222 words

Is doubling enough?

During my testing I discovered that the berry code compiled (be_loadstring function) successfully, but what would run out of stack is the actual execution (be_pcall function).

The main execution loop for berry is vm_exec [2] , it tries to avoid recursion for the most common cases by dispatch() being defined as #define dispatch() goto loop.
It's hard to tell if there are examples of berry code that would blow up the C stack, but they seem unlikely to arise from normal use.
My point is that I don't think that there's a fundamental flaw in berry that would force us to keep increasing the stack size for every bigger piece of code.

[1] https://berry.readthedocs.io/en/latest/source/en/Chapter-8.html#packaging-a-module
[2] https://github.com/berry-lang/berry/blob/72ee56f037261bb263178718fdf7a55654adf1fc/src/be_vm.c#L542

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant