I'm using ChibiOS RTOS and I have some questions that might seem basic, but kind of escape me a bit.
ChibiOS has a function called:
chSysLock();
and
chSysUnlock();
It's my understanding that these two functions will lock and unlock the kernel respectively.
So my questions are:
- What does locking the kernel do?
- Why do you want to lock the kernel?
And lastly, lets use this example:
static void sem_cb(void) {
chSysLock();
chBSemSignalI(&sem_1);
chSysUnlock();
}
This function just signals a semaphore for what ever thread is waiting for it.
So my last question is:
- What is the point of locking the kernel just to signal a semaphore? If I don't then ChibiOS will complain and won't compile without the system lock.
In general in an RTOS kernel locking simply the scheduler will not run so context switches will not occur. Often some or all interrupts are disabled too. Locking is used for critical sections - sections of code that must run without interruption or preemption.
I am no expert in ChibiOS, but it seems somewhat over-complicated in this respect and is not very comprehensively documented. The kernel states are described here. It has two lock modes, and
chSysLock()
invokes the S-Locked state, whereIt is not clear from the documentation whether that means that only I/S-Class APIs may be used or that
I/S-mode
APIs may only be called when locked. The whole state and its purpose is not well defined IMO. However it is common in some RTOS to have special versions of functions that do not invoke the scheduler, this saves regular API functions from the overhead of having to check the kernel state or interrupt context and is a minor optimization (at the expense of safety in my opinion). This is borne out by the documentation for chBSemSignalI:In your example, what is happening is the the semaphore is given, but the scheduler will not run so any waiting thread will not be immediately made ready. It is not clear whether
chSysUnlock()
causes the scheduler to run - the documentation says "Special function, this function has special requirements see the notes.", but gives no clue regarding where these notes may be found.I would expect the scheduler to run, and on the face of it the function
sem_cb()
would seem to serve little purpose; however I would also expectchSysLock()/chSysUnlock()
to be nestable, in which case the purpose of the function makes more sense. It allows a single semaphore-give function (sem_cb()
) to be used regardless of the kernel state. That is to say it is safe to call in both normal and S-State, but adds the overhead that the separate S-State/Normal state APIs are intended to avoid. Personally I'd always go for safety (though not necessarily implement it in this manner) at least until it could be shown that the overhead was unacceptable. It essentially says "_give the semaphore and if the kernel is not locked reschedule, otherwise defer rescheduling until the kernel is unlocked - i.e. after the last nested unlock".It does not allow however
sem_cb()
to be called from an interrupt context since that would requirechSysLockFromISR()
.The above makes a lot of assumptions from the documentation and "expected" RTOS behaviour. If I happened to be using ChibOS in the face of such scant documentation, I'd check the source code to determine the exact behaviour.