Is there any way to change the console port on an iMX6 running VxWorks 7 while running? I know how to change it via kernel configuration, but that is a compile time setting. Is there any way I can change it while running?
The ioLib documentation explains how to redirect the stdio file descriptors at run-time either globally or on a per task basis, using ioGlobalStdSet() or ioTaskStdSet() respectively. You can set stdin, stout, and stderr independently, so you will need to set all three to redirect all console I/O.
So for example:
#include <ioLib.h>
int redirectStdio( const char* devname )
{
int new_io_fd = open( devname, O_RDWR, 0 ) ;
if( new_io_fd >= 0 )
{
ioGlobalStdSet( STD_IN, new_io_fd ) ;
ioGlobalStdSet( STD_OUT, new_io_fd ) ;
ioGlobalStdSet( STD_ERR, new_io_fd ) ;
}
return new_io_fd ;
}
Then you might have:
if( redirectStdio( "/tyCo/2" ) < 0 )
{
printf( "Redirect failed - still here!\n" ) ;
}
else
{
printf( "stdio now directs here\n" ) ;
}
There are also ioGlobalStdGet() and ioTaskStdGet() functions so it is possible to retain the original settings and restore them if necessary for example.
Related
I had already done several projects using simple freertos ideas: led, button. Implementing semaphores, queues or some interrupt. I can't run this simple code tough.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#define BLINK_GPIO 21 //2
#define BUTTON_GPIO 0
void task_blink(void *pvParameters);
void task_botao(void *pvParameters);
//void wd_off_task(void *pvParameters);
SemaphoreHandle_t sem_sinc;
void app_main(void)
{
gpio_pad_select_gpio(BLINK_GPIO); // Configura o pino como IO
gpio_set_direction(BLINK_GPIO,GPIO_MODE_OUTPUT); // Configura o IO como saida
gpio_pad_select_gpio(BUTTON_GPIO); // Configura o pino como IO
gpio_set_direction(BUTTON_GPIO,GPIO_MODE_INPUT); // Configura o IO como entrada
vSemaphoreCreateBinary(sem_sinc); // Cria o Semaforo
xSemaphoreTake(sem_sinc,0); // Garante que inicializa com 0
xTaskCreate(task_blink,"Task Blink",1024,NULL,2,NULL);
printf("Task Blink Criada!!!\r\n");
xTaskCreate(task_botao,"Task Botao",1024,NULL,2,NULL);
printf("Task Botao Criada!!!\r\n");
//xTaskCreate(wd_off_task,"Task desliga WD",1024,NULL,1,NULL);
}
void task_botao(void *pvParameters)
{
while(1)
{
if(gpio_get_level(BUTTON_GPIO) == 0)
{
while(gpio_get_level(BUTTON_GPIO) == 0){}
printf("Botao Pressionado!!!\r\n");
xSemaphoreGive(sem_sinc);
vTaskDelay(1);
}
}
}
void task_blink(void *pvParameters)
{
while(1)
{
if(xSemaphoreTake(sem_sinc,portMAX_DELAY)==pdTRUE)
{
printf("Pisca Led!!!\r\n");
if((gpio_get_level(BUTTON_GPIO) == 0))
gpio_set_level(BLINK_GPIO, 1);
else
gpio_set_level(BLINK_GPIO, 0);
}
}
}
The issue:
The code is built nicely, and the same for the flashing to ESP. As I press the button, it shows in the terminal the designed messages. See, the only problem here lies on I can't set the LED's level, toggling it! Because of this, all I can get is the LED turning on and turning off afterwards quickly(every time the semaphore syncronizes the 2 tasks).
I suspect it's all about some kind of config, related to this GPIO. (Although I'm using the reset port to read the button, I still think this is not the matter, because the port was properly configured on the lines above)
Your switch polling needs to detect transitions, but avoid erroneously detecting switch bounce as a valid transition. For example:
#define BUTTON_DN = 0 ;
#define BUTTON_UP = 1 ;
#define POLL_DELAY = 50 ;
void task_botao(void *pvParameters)
{
int button_state = gpio_get_level( BUTTON_GPIO ) ;
for(;;)
{
int input_state = gpio_get_level( BUTTON_GPIO ) ;
// If button pressed...
if( input_state == BUTTON_DN &&
button_state != BUTTON_UP )
{
button_state = BUTTON_DN ;
// Signal button press event.
xSemaphoreGive(sem_sinc ) ;
}
// otherwise if button released...
else if( input_state == BUTTON_UP &&
button_state != BUTTON_DN )
{
button_state = BUTTON_UP ;
}
// Delay to yield processor and
// avoid switch bounce on transitions
vTaskDelay( POLL_DELAY );
}
}
The blinking task need not be reading the button input at all; not is it unnecessary, it is also a bad design:
void task_blink(void *pvParameters)
{
int led_state = 0 ;
gpio_set_level( BLINK_GPIO, led_state ) ;
for(;;)
{
if( xSemaphoreTake( sem_sinc, portMAX_DELAY ) == pdTRUE )
{
led_state = !led_state ;
gpio_set_level( BLINK_GPIO, led_state ) ;
}
}
}
There are some things to consider. Your thinking is logical, but there are some issues.
A button is a mechanical device and while you press it, you think it will be a straightforward 0 instead of 1 it’s not. If you have an oscilloscope, I recommend you to check the voltage level on the gpio input. Or google button bounce. And floating pins. Those two concepts should be clear. The processor is very straightforward in interpreting the values.
Example: https://hackaday.com/wp-content/uploads/2015/11/debounce_bouncing.png
Now your functions are in fact constantly checking the button status, somehow at the cost of processor time. For small projects not of an issue, but when they get bigger they are.
What you want to do is to setup an interrupt to the button status: at the moment the level changes it will fire some code. And it doesn’t have to double check the gpio status in two tasks, with the chance it will miss the status in the second (because of delays). It’s important to realize you are checking the same level twice now.
Not a problem now but maybe later: the stack size of the tasks is somehow small, make it a good use to always check if it’s enough by checking the current free size. Vague problems arise if it’s not.
I'm looking for a preferably cross-platform way to detect from within a Tcl script if the interpreter is running in a foreground or in a background process.
I've seen how to do it via ps (or /proc/$$/stat on Linux); is there a better way or do I have to hack something around that approach? I already have a utility library written in C so exposing the lowlevel API that ps also uses so I don't have to parse process output (or special file content) would be fine.
There's no truly cross-platform notion of foreground, but the main platforms do have ways of doing it according to the notion they have of foreground.
Linux, macOS, and other Unix:
For determining if a process is foreground or not, you need to check if its process group ID is the terminal's controlling process group ID. For Tcl, you'd be looking to surface the getpgrp() and tcgetpgrp() system calls (both POSIX). Tcl has no built-in exposure of either, so you're talking either a compiled extension (may I recommend Critcl for this?) or calling an external program like ps. Fortunately, if you use the latter (a reasonable option if this is just an occasional operation) you can typically condition the output so that you get just the information you want and need to do next to no parsing.
# Tested on macOS, but may work on other platforms
proc isForeground {{pid 0}} {
try {
lassign [exec ps -p [expr {$pid ? $pid : [pid]}] -o "pgid=,tpgid="] pgid tpgid
} on error {} {
return -code error "no such process"
}
# If tpgid is zero, the process is a daemon of some kind
expr {$pgid == $tpgid && $tpgid != 0}
}
Windows
There's code to do it, and the required calls are supported by the TWAPI extension so you don't need to make your own. (WARNING! I've not tested this!)
package require twapi_ui
proc isForeground {{pid 0}} {
set forground_pid [get_window_thread [get_foreground_window]]
return [expr {($pid ? $pid : [pid]) == $foreground_pid}]
}
Thanks to Donal I came up with the implementation below that should work on all POSIX Unix variants:
/*
processIsForeground
synopsis: processIsForeground
Returns true if the process is running in the foreground or false
if in the background.
*/
int IsProcessForegroundCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
/* Check the arg count */
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
int fd;
errno = 0;
if ((fd = open("/dev/tty", O_RDONLY)) != -1) {
const pid_t pgrp = getpgrp();
const pid_t tcpgrp = tcgetpgrp(fd);
if (pgrp != -1 && tcpgrp != -1) {
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pgrp == tcpgrp));
close(fd);
return TCL_OK;
}
close(fd);
}
Tcl_SetErrno(errno);
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "processIsForeground: ", (char *)Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
int Pextlib_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, "8.4", 0) == NULL)
return TCL_ERROR;
// SNIP
Tcl_CreateObjCommand(interp, "processIsForeground", IsProcessForegroundCmd, NULL, NULL);
if (Tcl_PkgProvide(interp, "Pextlib", "1.0") != TCL_OK)
return TCL_ERROR;
return TCL_OK;
}
is there a possibility to list all running processes in contiki os and output the result on the debugging output (i.e. UART) ?
Insert this in the contiki platform.c and main():
struct process *p;
uint8_t ps;
int n;
int
main(void) /*contiki main() here */
{
n=0;
while(1)
{
//...
//...
/*************************************************************/
if(n==100)
{
uint8_t ps=process_nevents();
PRINTF("there are %u events in the queue", ps);
PRINTF("\n\n");
PRINTF("Processes:");
for(p = PROCESS_LIST(); p != NULL; p = p->next)
{
char namebuf[30];
strncpy(namebuf, PROCESS_NAME_STRING(p), sizeof(namebuf));
PRINTF("%s", namebuf);
PRINTF("\n\n");
n=0;
}
}
n +=1;
/*********************************************************************/
//...
//...
}
return 0;
}
this will output the running processes every 100th iteration of the main loop
if you use UART as debugging port you have to redirect the output of PRINTF() to the correct port by i.e. on atmega128rfa1
/* Second rs232 port for debugging or slip alternative */
rs232_init(RS232_PORT_1, USART_BAUD_9600,USART_PARITY_NONE |
USART_STOP_BITS_1 | USART_DATA_BITS_8);
/* Redirect stdout */
/* #if RF230BB_CONF_LEDONPORTE1 || defined(RAVEN_LCD_INTERFACE) */
rs232_redirect_stdout(RS232_PORT_1);
the contiki shell source code contains very useful commands that can easily be used for debugging without using the entire shell, see
http://anrg.usc.edu/contiki/index.php/Contiki_Shell
Is it possible to access value of local variable of one process from another process .
For example in program below, I want to read value of my_id from manager.
proctype user (byte id){
byte my_id = id;
}
proctype manager (){
printf ("my_id : %d \n" , user:my_id);
}
init {
run user (5);
run manager();
}
You can refer to the current value of local variable by using "procname[pid]:var".
You can accomplish this using c_code{} and/or c_expr() syntax. Here is an example from the SPIN manual:
active proctype ex1()
{ int x;
do
:: c_expr { Pex1->x < 10 } ->
c_code { Pex1->x++; }
:: x < 10 -> x++
:: c_expr { fct() } -> x--
:: else -> break
od
}
The local 'x' of 'ex1' can be accessed using 'Pex1->x' from within c_expr{}.
I'm looking for a programatic way to find the powerpc cpu type on Linux. Performing some google searches associated an answer suggesting the mfpvr instruction I found that this is available in the ELF AUX header, and sure enough I can obtain the POWER5 string for the machine I'm running on with the following:
#include <stdio.h>
#include <elf.h>
int main( int argc, char **argv, char **envp )
{
/* walk past all env pointers */
while ( *envp++ != NULL )
;
/* and find ELF auxiliary vectors (if this was an ELF binary) */
#if 0
Elf32_auxv_t * auxv = (Elf32_auxv_t *) envp ;
#else
Elf64_auxv_t * auxv = (Elf64_auxv_t *) envp ;
#endif
char * platform = NULL ;
for ( ; auxv->a_type != AT_NULL ; auxv++ )
{
if ( auxv->a_type == AT_PLATFORM )
{
platform = (char *)auxv->a_un.a_val ;
break;
}
}
if ( platform )
{
printf( "%s\n", platform ) ;
}
return 0 ;
}
In the shared library context where I want to use this info I have no access to envp. Is there an alternate programatic method to find the beginning of the ELF AUX header?
You can get if from /proc/self/auxv file
According to man proc /proc/self/auxv is available since kernel level 2.6.0-test7.
Another option - get some (existing) environment variable - let say HOME,
or PATH, or whatever. Please note that you'll get it's ADDRESS. From here you can go back and find previous env variable, then one before it, etc. After that you can likewise skip all argv arguments. And then you get to the last AUXV entry. Some steps back - and you should be able find your AT_PLATFORM.
EDIT: It looks like glibc now provides a programatic method to get at this info:
glibc-headers-2.17-106: /usr/include/sys/auxv.h : getauxinfo()
Example:
#include <sys/auxv.h>
#include <stdio.h>
int main()
{
unsigned long v = getauxval( AT_PLATFORM ) ;
printf( "%s\n", (char *)v ) ;
return 0 ;
}